Compare commits
54 commits
1ad324aa23
...
0236586e44
Author | SHA1 | Date | |
---|---|---|---|
|
0236586e44 | ||
|
e13c7ae68c | ||
|
1d68123ea1 | ||
|
cf7b706582 | ||
|
c42d030d02 | ||
|
edfce9b492 | ||
|
e5d1ecd9f3 | ||
|
42a7813776 | ||
|
627faba0db | ||
|
a4ebaf52f5 | ||
|
660fe527f2 | ||
|
1a0ed7f298 | ||
062f5d3811 | |||
034c70542f | |||
|
ef244c3319 | ||
|
556505894c | ||
|
7c63ad66f9 | ||
|
26772a48eb | ||
|
2ded14deda | ||
|
465c082328 | ||
|
25e6660e8e | ||
f58afe92cb | |||
2b3ca0dff9 | |||
|
1e88a31f90 | ||
|
026d32c92a | ||
|
a28b9df6b5 | ||
d2bde99e1f | |||
f8ffedb5db | |||
4b7d17c02f | |||
0ae98f96b5 | |||
|
fb3d314ee2 | ||
|
b032b32db1 | ||
|
63f4b37655 | ||
|
bdc0423bf3 | ||
749f05816c | |||
06ebe95309 | |||
|
40ec4b0968 | ||
|
c4c9dc83c0 | ||
9a37db94ae | |||
|
0ba3a8cd7f | ||
|
0aeaf50c92 | ||
|
a9947ff9f7 | ||
|
c7324c020b | ||
|
46419b0960 | ||
|
c1c8729023 | ||
|
9bcc9ab690 | ||
|
0b6a2db2f1 | ||
61a04b034a | |||
|
ca42a5e7e0 | ||
400cda8dcd | |||
fe50ead4ee | |||
f1717cbd29 | |||
|
5394fde136 | ||
|
29621b739a |
55 changed files with 19558 additions and 2689 deletions
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
|
@ -84,7 +84,7 @@ jobs:
|
||||||
assets+=("-a" "$asset")
|
assets+=("-a" "$asset")
|
||||||
done
|
done
|
||||||
tag_name="${GITHUB_REF##*/}"
|
tag_name="${GITHUB_REF##*/}"
|
||||||
hub release create "${assets[@]}" -m "$tag_name" "$tag_name"
|
gh release create "$tag_name" "${assets[@]}"
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
@ -97,6 +97,6 @@ jobs:
|
||||||
assets+=("-a" "$asset")
|
assets+=("-a" "$asset")
|
||||||
done
|
done
|
||||||
tag_name="${GITHUB_REF##*/}"
|
tag_name="${GITHUB_REF##*/}"
|
||||||
hub release create -p "${assets[@]}" -m "$tag_name" -m "This is a pre-release for testing purposes only. It may or may not be unstable." -m "Join the Telegram group to help out: https://github.com/Wunderfitz/harbour-fernschreiber/issues/162" "$tag_name"
|
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:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -53,3 +53,6 @@ compile_commands.json
|
||||||
|
|
||||||
# TDLib API Secrets
|
# TDLib API Secrets
|
||||||
tdlibsecrets.h
|
tdlibsecrets.h
|
||||||
|
|
||||||
|
#Convinience scripts
|
||||||
|
*.sh
|
||||||
|
|
|
@ -14,7 +14,11 @@ Fernschreiber wouldn't be the same without all the people helping in making it b
|
||||||
- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies, emoji handling, qml/js optimizations, multi-message actions, i18n fixes, chat permission handling, code reviews, logging categories, bot support, github build: [jgibbon](https://github.com/jgibbon)
|
- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies, emoji handling, qml/js optimizations, multi-message actions, i18n fixes, chat permission handling, code reviews, logging categories, bot support, github build: [jgibbon](https://github.com/jgibbon)
|
||||||
- Copy message to clipboard: [Christian Stemmle](https://github.com/chstem)
|
- Copy message to clipboard: [Christian Stemmle](https://github.com/chstem)
|
||||||
- Hide send message button if send-by-enter is switched on, focus text input on entering a chat: [santhoshmanikandan](https://github.com/santhoshmanikandan)
|
- 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: [Peter G.](https://github.com/nephros)
|
- Integration of logout and sesison options to settings page, search results optimization, highlight unread conversations: [Peter G.](https://github.com/nephros)
|
||||||
|
- Option to always append last message in notifications: [Johannes Bachmann](https://github.com/dscheinah)
|
||||||
|
- Option to jump to quoted message, widescreen UI adjustments: [Mikhail Barashkov](https://github.com/mbarashkov)
|
||||||
|
|
||||||
|
This list might not be complete. In case I forgot something/somebody, please let me know or create a PR, thanks! :)
|
||||||
|
|
||||||
### Logo/Icon
|
### Logo/Icon
|
||||||
- Designed by [Matteo](https://github.com/iamnomeutente), adjustments by [Slava Monich](https://github.com/monich)
|
- Designed by [Matteo](https://github.com/iamnomeutente), adjustments by [Slava Monich](https://github.com/monich)
|
||||||
|
@ -48,7 +52,7 @@ const char TDLIB_API_HASH[] = "1234567890abcdef1234567890abcdef";
|
||||||
|
|
||||||
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
||||||
|
|
||||||
Moreover, you need to have a compiled version of [TDLib 1.8.3](https://github.com/tdlib/td) or higher in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
|
Moreover, you need to have a compiled version of [TDLib 1.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.
|
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.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
X-Nemo-Application-Type=generic
|
X-Nemo-Application-Type=silica-qt5
|
||||||
Icon=harbour-fernschreiber
|
Icon=harbour-fernschreiber
|
||||||
Exec=harbour-fernschreiber
|
Exec=harbour-fernschreiber
|
||||||
Name=Fernschreiber
|
Name=Fernschreiber
|
||||||
|
|
|
@ -40,7 +40,7 @@ Loader {
|
||||||
|
|
||||||
property string chatId
|
property string chatId
|
||||||
property string userName
|
property string userName
|
||||||
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.username.toLowerCase()
|
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.usernames.editable_username.toLowerCase()
|
||||||
property string query
|
property string query
|
||||||
property int currentOffset: 0
|
property int currentOffset: 0
|
||||||
property string responseExtra: chatId+"|"+userName+"|"+query+"|"+currentOffset
|
property string responseExtra: chatId+"|"+userName+"|"+query+"|"+currentOffset
|
||||||
|
|
|
@ -47,6 +47,7 @@ ListItem {
|
||||||
readonly property bool canDeleteMessage: myMessage.can_be_deleted_for_all_users || (myMessage.can_be_deleted_only_for_self && myMessage.chat_id === page.myUserId)
|
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 hasContentComponent
|
||||||
property bool additionalOptionsOpened
|
property bool additionalOptionsOpened
|
||||||
|
property bool wasNavigatedTo: false
|
||||||
|
|
||||||
readonly property var additionalItemsModel: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
|
readonly property var additionalItemsModel: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
|
||||||
extraContentLoader.item.extraContextMenuItems : 0
|
extraContentLoader.item.extraContextMenuItems : 0
|
||||||
|
@ -64,9 +65,10 @@ ListItem {
|
||||||
readonly property bool showForwardMessageMenuItem: (baseContextMenuItemCount + 2) <= 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
|
// 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
|
readonly property bool haveSpaceForDeleteMessageMenuItem: (baseContextMenuItemCount + 3 - (deleteMessageIsOnlyExtraOption ? 1 : 0)) <= maxContextMenuItemCount
|
||||||
|
property var chatReactions
|
||||||
property var messageReactions
|
property var messageReactions
|
||||||
|
|
||||||
highlighted: (down || isSelected || additionalOptionsOpened) && !menuOpen
|
highlighted: (down || isSelected || additionalOptionsOpened || wasNavigatedTo) && !menuOpen
|
||||||
openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
|
openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
|
||||||
|
|
||||||
signal replyToMessage()
|
signal replyToMessage()
|
||||||
|
@ -94,20 +96,43 @@ ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInteractionText(viewCount, reactions) {
|
function getInteractionText(viewCount, reactions, size, highlightColor) {
|
||||||
var interactionText = "";
|
var interactionText = "";
|
||||||
if (viewCount > 0) {
|
if (viewCount > 0) {
|
||||||
interactionText = Emoji.emojify("👁️", Theme.fontSizeTiny) + Functions.getShortenedCount(viewCount);
|
interactionText = Emoji.emojify("👁️ ", size) + Functions.getShortenedCount(viewCount);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < reactions.length; i++) {
|
for (var i = 0; i < reactions.length; i++) {
|
||||||
interactionText += ( " " + Emoji.emojify(reactions[i].reaction, Theme.fontSizeTiny) );
|
var reaction = reactions[i]
|
||||||
if (!chatPage.isPrivateChat) {
|
var reactionText = reaction.reaction ? reaction.reaction : (reaction.type && reaction.type.emoji) ? reaction.type.emoji : ""
|
||||||
interactionText += ( " " + Functions.getShortenedCount(reactions[i].total_count) );
|
if (reactionText) {
|
||||||
|
interactionText += ( " " + Emoji.emojify(reactionText, size) );
|
||||||
|
if (!chatPage.isPrivateChat) {
|
||||||
|
var count = Functions.getShortenedCount(reaction.total_count)
|
||||||
|
interactionText += " "
|
||||||
|
interactionText += (reaction.is_chosen ? ( "<font color='" + highlightColor + "'><b>" + count + "</b></font>" ) : count)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return interactionText;
|
return interactionText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openReactions() {
|
||||||
|
if (messageListItem.chatReactions) {
|
||||||
|
Debug.log("Using chat reactions")
|
||||||
|
messageListItem.messageReactions = chatReactions
|
||||||
|
showItemCompletelyTimer.requestedIndex = index;
|
||||||
|
showItemCompletelyTimer.start();
|
||||||
|
} else {
|
||||||
|
Debug.log("Obtaining message reactions")
|
||||||
|
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
|
||||||
|
}
|
||||||
|
selectReactionBubble.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContentWidthMultiplier() {
|
||||||
|
return Functions.isWidescreen(appWindow) ? 0.4 : 1.0
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (messageListItem.precalculatedValues.pageIsSelecting) {
|
if (messageListItem.precalculatedValues.pageIsSelecting) {
|
||||||
page.toggleMessageSelection(myMessage);
|
page.toggleMessageSelection(myMessage);
|
||||||
|
@ -125,12 +150,26 @@ ListItem {
|
||||||
|
|
||||||
if (messageListItem.messageReactions) {
|
if (messageListItem.messageReactions) {
|
||||||
messageListItem.messageReactions = null;
|
messageListItem.messageReactions = null;
|
||||||
|
selectReactionBubble.visible = false;
|
||||||
} else {
|
} else {
|
||||||
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
|
selectReactionBubble.visible = !selectReactionBubble.visible;
|
||||||
|
elementSelected(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDoubleClicked: {
|
||||||
|
if (messageListItem.chatReactions) {
|
||||||
|
Debug.log("Using chat reactions")
|
||||||
|
messageListItem.messageReactions = chatReactions
|
||||||
|
showItemCompletelyTimer.requestedIndex = index;
|
||||||
|
showItemCompletelyTimer.start();
|
||||||
|
} else {
|
||||||
|
Debug.log("Obtaining message reactions")
|
||||||
|
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onPressAndHold: {
|
onPressAndHold: {
|
||||||
if (openMenuOnPressAndHold) {
|
if (openMenuOnPressAndHold) {
|
||||||
openContextMenu()
|
openContextMenu()
|
||||||
|
@ -154,6 +193,25 @@ ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatPage
|
||||||
|
onResetElements: {
|
||||||
|
messageListItem.messageReactions = null;
|
||||||
|
selectReactionBubble.visible = false;
|
||||||
|
}
|
||||||
|
onElementSelected: {
|
||||||
|
if (elementIndex !== index) {
|
||||||
|
selectReactionBubble.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNavigatedTo: {
|
||||||
|
if (targetIndex === index) {
|
||||||
|
messageListItem.wasNavigatedTo = true;
|
||||||
|
restoreNormalityTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: contextMenuLoader
|
id: contextMenuLoader
|
||||||
active: false
|
active: false
|
||||||
|
@ -258,6 +316,9 @@ ListItem {
|
||||||
messageListItem.messageReactions = null;
|
messageListItem.messageReactions = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onReactionsUpdated: {
|
||||||
|
chatReactions = tdLibWrapper.getChatReactions(page.chatInformation.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
@ -270,16 +331,34 @@ ListItem {
|
||||||
interval: 200
|
interval: 200
|
||||||
triggeredOnStart: false
|
triggeredOnStart: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
Debug.log("Show item completely timer triggered, requested index: " + requestedIndex + ", current index: " + index)
|
||||||
if (requestedIndex === index) {
|
if (requestedIndex === index) {
|
||||||
chatView.highlightMoveDuration = -1;
|
var p = chatView.contentItem.mapFromItem(reactionsColumn, 0, 0)
|
||||||
chatView.highlightResizeDuration = -1;
|
if (chatView.contentY > p.y || p.y + reactionsColumn.height > chatView.contentY + chatView.height) {
|
||||||
chatView.scrollToIndex(requestedIndex);
|
Debug.log("Moving reactions for item at", requestedIndex, "info the view")
|
||||||
chatView.highlightMoveDuration = 0;
|
chatView.highlightMoveDuration = -1
|
||||||
chatView.highlightResizeDuration = 0;
|
chatView.highlightResizeDuration = -1
|
||||||
|
chatView.scrollToIndex(requestedIndex, height <= chatView.height ? ListView.Contain : ListView.End)
|
||||||
|
chatView.highlightMoveDuration = 0
|
||||||
|
chatView.highlightResizeDuration = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: restoreNormalityTimer
|
||||||
|
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
interval: 1000
|
||||||
|
triggeredOnStart: false
|
||||||
|
onTriggered: {
|
||||||
|
Debug.log("Restore normality for index " + index);
|
||||||
|
messageListItem.wasNavigatedTo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
delegateComponentLoadingTimer.start();
|
delegateComponentLoadingTimer.start();
|
||||||
if (myMessage.reply_to_message_id) {
|
if (myMessage.reply_to_message_id) {
|
||||||
|
@ -322,8 +401,10 @@ ListItem {
|
||||||
id: messageTextRow
|
id: messageTextRow
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
width: precalculatedValues.entryWidth
|
width: precalculatedValues.entryWidth
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: Functions.isWidescreen(appWindow) ? undefined : parent.horizontalCenter
|
||||||
|
anchors.left: Functions.isWidescreen(appWindow) ? parent.left : undefined
|
||||||
y: Theme.paddingSmall
|
y: Theme.paddingSmall
|
||||||
|
anchors.leftMargin: Functions.isWidescreen(appWindow) ? Theme.paddingMedium : undefined
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: profileThumbnailLoader
|
id: profileThumbnailLoader
|
||||||
|
@ -440,8 +521,12 @@ ListItem {
|
||||||
page.toggleMessageSelection(myMessage)
|
page.toggleMessageSelection(myMessage)
|
||||||
} else {
|
} else {
|
||||||
messageOptionsDrawer.open = false
|
messageOptionsDrawer.open = false
|
||||||
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage
|
if(appSettings.goToQuotedMessage) {
|
||||||
messageOverlayLoader.active = true
|
chatPage.showMessage(messageInReplyToRow.inReplyToMessage.id, true)
|
||||||
|
} else {
|
||||||
|
messageOverlayLoader.active = true
|
||||||
|
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onPressAndHold: {
|
onPressAndHold: {
|
||||||
|
@ -467,11 +552,12 @@ ListItem {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
Component.onCompleted: {
|
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);
|
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
|
||||||
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
|
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
|
||||||
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
|
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
|
||||||
} else if (myMessage.forward_info.origin["@type"] === "messageForwardOriginUser") {
|
} else if (originType === "messageOriginUser" || originType === "messageForwardOriginUser") {
|
||||||
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
|
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
|
||||||
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
|
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
|
||||||
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
|
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
|
||||||
|
@ -552,7 +638,7 @@ ListItem {
|
||||||
id: webPagePreviewLoader
|
id: webPagePreviewLoader
|
||||||
active: false
|
active: false
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
width: parent.width
|
width: parent.width * getContentWidthMultiplier()
|
||||||
height: (status === Loader.Ready) ? item.implicitHeight : myMessage.content.web_page ? precalculatedValues.webPagePreviewHeight : 0
|
height: (status === Loader.Ready) ? item.implicitHeight : myMessage.content.web_page ? precalculatedValues.webPagePreviewHeight : 0
|
||||||
|
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
|
@ -566,7 +652,7 @@ ListItem {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: extraContentLoader
|
id: extraContentLoader
|
||||||
width: parent.width
|
width: parent.width * getContentWidthMultiplier()
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
height: item ? item.height : (messageListItem.hasContentComponent ? chatView.getContentComponentHeight(model.content_type, myMessage.content, width) : 0)
|
height: item ? item.height : (messageListItem.hasContentComponent ? chatView.getContentComponentHeight(model.content_type, myMessage.content, width) : 0)
|
||||||
}
|
}
|
||||||
|
@ -625,7 +711,7 @@ ListItem {
|
||||||
height: ( ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0 ) ? ( Theme.fontSizeExtraSmall + Theme.paddingSmall ) : 0
|
height: ( ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0 ) ? ( Theme.fontSizeExtraSmall + Theme.paddingSmall ) : 0
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
Label {
|
Label {
|
||||||
text: getInteractionText(messageViewCount, reactions)
|
text: getInteractionText(messageViewCount, reactions, font.pixelSize, Theme.highlightColor)
|
||||||
width: parent.width
|
width: parent.width
|
||||||
font.pixelSize: Theme.fontSizeTiny
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||||
|
@ -677,7 +763,7 @@ ListItem {
|
||||||
Image {
|
Image {
|
||||||
id: emojiPicture
|
id: emojiPicture
|
||||||
source: Emoji.getEmojiPath(modelData)
|
source: Emoji.getEmojiPath(modelData)
|
||||||
width: Theme.fontSizeLarge
|
width: status === Image.Ready ? Theme.fontSizeLarge : 0
|
||||||
height: Theme.fontSizeLarge
|
height: Theme.fontSizeLarge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,11 @@ Flickable {
|
||||||
|
|
||||||
function getOriginalAuthor(forwardInformation, fontSize) {
|
function getOriginalAuthor(forwardInformation, fontSize) {
|
||||||
switch (forwardInformation.origin["@type"]) {
|
switch (forwardInformation.origin["@type"]) {
|
||||||
|
case "messageOriginChannel":
|
||||||
case "messageForwardOriginChannel":
|
case "messageForwardOriginChannel":
|
||||||
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
||||||
return Emoji.emojify(otherChatInformation.title, fontSize);
|
return Emoji.emojify(otherChatInformation.title, fontSize);
|
||||||
|
case "messageOriginUser":
|
||||||
case "messageForwardOriginUser":
|
case "messageForwardOriginUser":
|
||||||
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_id.user_id);
|
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_id.user_id);
|
||||||
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
||||||
|
|
|
@ -31,12 +31,12 @@ Loader {
|
||||||
property var botUserInformation: tdLibWrapper.getUserInformation(message.via_bot_user_id)
|
property var botUserInformation: tdLibWrapper.getUserInformation(message.via_bot_user_id)
|
||||||
color: Theme.secondaryColor
|
color: Theme.secondaryColor
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
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.username, font.pixelSize)+"</a>")
|
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
|
textFormat: Text.RichText
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
if(link === "userId://" + message.via_bot_user_id && botUserInformation.type.is_inline) {
|
if(link === "userId://" + message.via_bot_user_id && botUserInformation.type.is_inline) {
|
||||||
newMessageTextField.text = "@"+botUserInformation.username+" "
|
newMessageTextField.text = "@"+botUserInformation.usernames.editable_username+" "
|
||||||
newMessageTextField.cursorPosition = newMessageTextField.text.length
|
newMessageTextField.cursorPosition = newMessageTextField.text.length
|
||||||
lostFocusTimer.start();
|
lostFocusTimer.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
|
||||||
ListItem {
|
ListItem {
|
||||||
id: chatListViewItem
|
id: chatListViewItem
|
||||||
|
@ -103,31 +104,42 @@ ListItem {
|
||||||
anchors.centerIn: chatUnreadMessagesCountBackground
|
anchors.centerIn: chatUnreadMessagesCountBackground
|
||||||
visible: chatListViewItem.unreadCount > 0
|
visible: chatListViewItem.unreadCount > 0
|
||||||
opacity: isMuted ? Theme.opacityHigh : 1.0
|
opacity: isMuted ? Theme.opacityHigh : 1.0
|
||||||
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
|
text: Functions.formatUnreadCount(chatListViewItem.unreadCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: chatUnreadReactionCountBackground
|
|
||||||
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
|
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
|
||||||
width: Theme.fontSizeLarge
|
width: Theme.fontSizeLarge
|
||||||
height: Theme.fontSizeLarge
|
height: Theme.fontSizeLarge
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
radius: parent.width / 2
|
radius: parent.width / 2
|
||||||
visible: chatListViewItem.unreadReactionCount > 0
|
visible: chatListViewItem.unreadReactionCount > 0 || chatListViewItem.unreadMentionCount > 0
|
||||||
}
|
|
||||||
|
|
||||||
Icon {
|
Icon {
|
||||||
source: "image://theme/icon-s-favorite"
|
source: "image://theme/icon-s-favorite"
|
||||||
height: Theme.iconSizeExtraSmall
|
height: Theme.iconSizeExtraSmall
|
||||||
width: Theme.iconSizeExtraSmall
|
width: Theme.iconSizeExtraSmall
|
||||||
highlighted: chatListViewItem.highlighted
|
highlighted: chatListViewItem.highlighted
|
||||||
anchors.centerIn: chatUnreadReactionCountBackground
|
anchors.centerIn: parent
|
||||||
visible: chatListViewItem.unreadReactionCount > 0
|
visible: chatListViewItem.unreadReactionCount > 0 && !chatListViewItem.unreadMentionCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font {
|
||||||
|
pixelSize: Theme.iconSizeExtraSmall
|
||||||
|
bold: true
|
||||||
|
}
|
||||||
|
color: Theme.primaryColor
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: chatListViewItem.unreadMentionCount > 0
|
||||||
|
opacity: isMuted ? Theme.opacityHigh : 1.0
|
||||||
|
text: "@"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -150,6 +162,9 @@ ListItem {
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0) - (mutedImage.visible ? (mutedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
|
|
@ -60,12 +60,12 @@ Column {
|
||||||
},
|
},
|
||||||
inlineKeyboardButtonTypeSwitchInline: function() {
|
inlineKeyboardButtonTypeSwitchInline: function() {
|
||||||
if(modelData.type.in_current_chat) {
|
if(modelData.type.in_current_chat) {
|
||||||
chatPage.setMessageText("@" + userInformation.username + " "+(modelData.type.query || ""))
|
chatPage.setMessageText("@" + userInformation.usernames.editable_username + " "+(modelData.type.query || ""))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
|
pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
|
||||||
myUserId: chatPage.myUserId,
|
myUserId: chatPage.myUserId,
|
||||||
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.username + " "+(modelData.type.query || "")},
|
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.usernames.editable_username + " "+(modelData.type.query || "")},
|
||||||
state: "fillTextArea"
|
state: "fillTextArea"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,8 +300,8 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
|
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
|
||||||
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
|
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
|
||||||
description: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.username)
|
description: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.usernames.editable_username)
|
||||||
? ("@"+chatInformationPage.privateChatUserInformation.username) : ""
|
? ("@"+chatInformationPage.privateChatUserInformation.usernames.editable_username) : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaFlickable {
|
SilicaFlickable {
|
||||||
|
|
|
@ -79,7 +79,7 @@ ChatInformationTabItemBase {
|
||||||
// chat title
|
// chat title
|
||||||
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
|
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
|
||||||
// last user
|
// last user
|
||||||
prologSecondaryText.text: "@"+(user.username !== "" ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
|
prologSecondaryText.text: "@"+(user.username ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
|
||||||
secondaryText {
|
secondaryText {
|
||||||
horizontalAlignment: Text.AlignRight
|
horizontalAlignment: Text.AlignRight
|
||||||
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
|
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
|
||||||
|
@ -180,6 +180,9 @@ ChatInformationTabItemBase {
|
||||||
for(var memberIndex in members) {
|
for(var memberIndex in members) {
|
||||||
var memberData = members[memberIndex];
|
var memberData = members[memberIndex];
|
||||||
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.user_id) || {user:{}, bot_info:{}};
|
var userInfo = tdLibWrapper.getUserInformation(memberData.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.user = userInfo;
|
||||||
memberData.bot_info = memberData.bot_info || {};
|
memberData.bot_info = memberData.bot_info || {};
|
||||||
pageContent.membersList.append(memberData);
|
pageContent.membersList.append(memberData);
|
||||||
|
|
|
@ -27,7 +27,7 @@ MessageContentBase {
|
||||||
|
|
||||||
property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
|
property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
|
||||||
readonly property bool asEmoji: appSettings.showStickersAsEmojis
|
readonly property bool asEmoji: appSettings.showStickersAsEmojis
|
||||||
readonly property bool animated: stickerData.type["@type"] === "stickerTypeAnimated" && appSettings.animateStickers
|
readonly property bool animated: stickerData.format["@type"] === "stickerFormatTgs" && appSettings.animateStickers
|
||||||
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
|
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
|
||||||
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
|
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
|
||||||
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
|
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
|
import "../../js/functions.js" as Functions
|
||||||
|
|
||||||
Grid {
|
Grid {
|
||||||
width: parent.width - ( 2 * x )
|
width: parent.width - ( 2 * x )
|
||||||
columns: (appWindow.deviceOrientation & Orientation.LandscapeMask) || Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge ? 2 : 1
|
columns: Functions.isWidescreen(appWindow) ? 2 : 1
|
||||||
readonly property real columnWidth: width/columns
|
readonly property real columnWidth: width/columns
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,17 @@ AccordionItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
TextSwitch {
|
||||||
width: parent.columnWidth
|
width: parent.columnWidth
|
||||||
checked: appSettings.useOpenWith
|
checked: appSettings.useOpenWith
|
||||||
|
@ -81,6 +92,28 @@ AccordionItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
ComboBox {
|
||||||
id: feedbackComboBox
|
id: feedbackComboBox
|
||||||
width: parent.columnWidth
|
width: parent.columnWidth
|
||||||
|
@ -135,35 +168,53 @@ AccordionItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSwitch {
|
Item {
|
||||||
width: parent.columnWidth
|
// Occupies one grid cell so that the column ends up under the combo box
|
||||||
checked: appSettings.notificationTurnsDisplayOn && enabled
|
// in the landscape layout
|
||||||
text: qsTr("Notification turns on the display")
|
visible: parent.columns === 2
|
||||||
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
|
width: 1
|
||||||
height: enabled ? implicitHeight: 0
|
height: 1
|
||||||
clip: height < implicitHeight
|
|
||||||
visible: height > 0
|
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationTurnsDisplayOn = !checked
|
|
||||||
}
|
|
||||||
Behavior on height { SmoothedAnimation { duration: 200 } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSwitch {
|
Column {
|
||||||
width: parent.columnWidth
|
|
||||||
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: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
|
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
|
||||||
|
width: parent.columnWidth
|
||||||
height: enabled ? implicitHeight: 0
|
height: enabled ? implicitHeight: 0
|
||||||
clip: height < implicitHeight
|
clip: height < implicitHeight
|
||||||
visible: height > 0
|
visible: height > 0
|
||||||
automaticCheck: false
|
|
||||||
onClicked: {
|
|
||||||
appSettings.notificationSoundsEnabled = !checked
|
|
||||||
}
|
|
||||||
Behavior on height { SmoothedAnimation { duration: 200 } }
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,153 +30,183 @@ AccordionItem {
|
||||||
Column {
|
Column {
|
||||||
id: activeSessionsItem
|
id: activeSessionsItem
|
||||||
bottomPadding: Theme.paddingMedium
|
bottomPadding: Theme.paddingMedium
|
||||||
property variant activeSessions;
|
property variant activeSessions
|
||||||
property bool loaded : false;
|
property int inactiveSessionsTtlDays
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!activeSessions) {
|
if (!activeSessions) {
|
||||||
tdLibWrapper.getActiveSessions();
|
tdLibWrapper.getActiveSessions();
|
||||||
} else {
|
|
||||||
activeSessionsItem.loaded = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onSessionsReceived: {
|
onSessionsReceived: {
|
||||||
activeSessionsItem.activeSessions = sessions;
|
activeSessionsItem.activeSessions = sessions
|
||||||
activeSessionsItem.loaded = true;
|
activeSessionsItem.inactiveSessionsTtlDays = inactive_session_ttl_days
|
||||||
}
|
}
|
||||||
onOkReceived: {
|
onOkReceived: {
|
||||||
if (request === "terminateSession") {
|
if (request === "terminateSession") {
|
||||||
appNotification.show(qsTr("Session was terminated"));
|
appNotification.show(qsTr("Session was terminated"));
|
||||||
activeSessionsItem.loaded = false;
|
|
||||||
tdLibWrapper.getActiveSessions();
|
tdLibWrapper.getActiveSessions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: sessionInformationLoader
|
|
||||||
active: tdLibWrapper.authorizationState === TelegramAPI.AuthorizationReady
|
active: tdLibWrapper.authorizationState === TelegramAPI.AuthorizationReady
|
||||||
width: parent.width
|
width: parent.width
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
SilicaListView {
|
Column {
|
||||||
id: activeSessionsListView
|
BusyIndicator {
|
||||||
width: parent.width
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
height: contentHeight
|
running: !activeSessionsListView.count && !activeSessionsItem.inactiveSessionsTtlDays
|
||||||
model: activeSessionsItem.activeSessions
|
size: BusyIndicatorSize.Medium
|
||||||
headerPositioning: ListView.OverlayHeader
|
visible: opacity > 0
|
||||||
header: Separator {
|
height: running ? implicitHeight : 0
|
||||||
width: parent.width
|
|
||||||
color: Theme.primaryColor
|
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
|
||||||
}
|
}
|
||||||
delegate: ListItem {
|
|
||||||
id: activeSessionListItem
|
SilicaListView {
|
||||||
|
id: activeSessionsListView
|
||||||
width: parent.width
|
width: parent.width
|
||||||
contentHeight: activeSessionColumn.height + ( 2 * Theme.paddingMedium )
|
height: contentHeight
|
||||||
|
model: activeSessionsItem.activeSessions
|
||||||
menu: ContextMenu {
|
headerPositioning: ListView.OverlayHeader
|
||||||
hasContent: !modelData.is_current
|
header: Separator {
|
||||||
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
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: modelData.application_name + " " + modelData.application_version
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.bold: true
|
|
||||||
color: Theme.primaryColor
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: modelData.device_model + ", " + (modelData.platform + " " + modelData.system_version).trim()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primaryColor
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
width: parent.width
|
|
||||||
text: qsTr("IP address: %1, origin: %2").arg(modelData.ip).arg(modelData.country)
|
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
|
||||||
color: Theme.secondaryColor
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
color: Theme.primaryColor
|
|
||||||
maximumLineCount: 1
|
|
||||||
truncationMode: TruncationMode.Fade
|
|
||||||
anchors {
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Separator {
|
|
||||||
id: separator
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ AccordionItem {
|
||||||
visible: true
|
visible: true
|
||||||
canEdit: true
|
canEdit: true
|
||||||
headerText: qsTr("Username", "user name of the logged-in profile - header")
|
headerText: qsTr("Username", "user name of the logged-in profile - header")
|
||||||
text: userInformation.username
|
text: userInformation.usernames.editable_username
|
||||||
width: parent.columnWidth
|
width: parent.columnWidth
|
||||||
headerLeftAligned: true
|
headerLeftAligned: true
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,14 @@ function setGlobals(globals) {
|
||||||
tdLibWrapper = globals.tdLibWrapper;
|
tdLibWrapper = globals.tdLibWrapper;
|
||||||
appNotification = globals.appNotification;
|
appNotification = globals.appNotification;
|
||||||
}
|
}
|
||||||
|
function formatUnreadCount(value) {
|
||||||
|
if(value < 1000) {
|
||||||
|
return value;
|
||||||
|
} else if(value > 9000) {
|
||||||
|
return '9k+';
|
||||||
|
}
|
||||||
|
return ''+Math.floor(value / 1000)+'k'+((value % 1000)>0 ? '+' : '');
|
||||||
|
}
|
||||||
|
|
||||||
function getUserName(userInformation) {
|
function getUserName(userInformation) {
|
||||||
return ((userInformation.first_name || "") + " " + (userInformation.last_name || "")).trim();
|
return ((userInformation.first_name || "") + " " + (userInformation.last_name || "")).trim();
|
||||||
|
@ -527,3 +535,7 @@ function getMessagesNeededForwardPermissions(messages) {
|
||||||
}
|
}
|
||||||
return neededPermissions
|
return neededPermissions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isWidescreen(appWindow) {
|
||||||
|
return (appWindow.deviceOrientation & Silica.Orientation.LandscapeMask) || Silica.Screen.sizeCategory === Silica.Screen.Large || Silica.Screen.sizeCategory === Silica.Screen.ExtraLarge
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ Page {
|
||||||
property bool iterativeInitialization: false;
|
property bool iterativeInitialization: false;
|
||||||
property var messageToShow;
|
property var messageToShow;
|
||||||
property string messageIdToShow;
|
property string messageIdToShow;
|
||||||
|
property string messageIdToScrollTo;
|
||||||
readonly property bool userIsMember: ((isPrivateChat || isSecretChat) && chatInformation["@type"]) || // should be optimized
|
readonly property bool userIsMember: ((isPrivateChat || isSecretChat) && chatInformation["@type"]) || // should be optimized
|
||||||
(isBasicGroup || isSuperGroup) && (
|
(isBasicGroup || isSuperGroup) && (
|
||||||
(chatGroupInformation.status["@type"] === "chatMemberStatusMember")
|
(chatGroupInformation.status["@type"] === "chatMemberStatusMember")
|
||||||
|
@ -63,9 +64,13 @@ Page {
|
||||||
)
|
)
|
||||||
property var selectedMessages: []
|
property var selectedMessages: []
|
||||||
readonly property bool isSelecting: selectedMessages.length > 0
|
readonly property bool isSelecting: selectedMessages.length > 0
|
||||||
readonly property bool canSendMessages: hasSendPrivilege("can_send_messages")
|
readonly property bool canSendMessages: hasSendPrivilege("can_send_basic_messages")
|
||||||
property bool doSendBotStartMessage
|
property bool doSendBotStartMessage
|
||||||
property string sendBotStartMessageParameter
|
property string sendBotStartMessageParameter
|
||||||
|
property var availableReactions
|
||||||
|
signal resetElements()
|
||||||
|
signal elementSelected(int elementIndex)
|
||||||
|
signal navigatedTo(int targetIndex)
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
|
@ -184,7 +189,7 @@ Page {
|
||||||
}
|
}
|
||||||
tdLibWrapper.getChatPinnedMessage(chatInformation.id);
|
tdLibWrapper.getChatPinnedMessage(chatInformation.id);
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false);
|
tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false);
|
||||||
|
availableReactions = tdLibWrapper.getChatReactions(chatInformation.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) {
|
function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) {
|
||||||
|
@ -406,6 +411,24 @@ Page {
|
||||||
chatPage.focus = true;
|
chatPage.focus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showMessage(messageId, initialRun) {
|
||||||
|
// Means we tapped a quoted message and had to load it.
|
||||||
|
if(initialRun) {
|
||||||
|
chatPage.messageIdToScrollTo = messageId
|
||||||
|
}
|
||||||
|
if (chatPage.messageIdToScrollTo && chatPage.messageIdToScrollTo != "") {
|
||||||
|
var index = chatModel.getMessageIndex(chatPage.messageIdToScrollTo);
|
||||||
|
if(index !== -1) {
|
||||||
|
chatPage.messageIdToScrollTo = "";
|
||||||
|
chatView.scrollToIndex(index);
|
||||||
|
navigatedTo(index);
|
||||||
|
} else if(initialRun) {
|
||||||
|
// we only want to do this once.
|
||||||
|
chatModel.triggerLoadHistoryForMessage(chatPage.messageIdToScrollTo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: forwardMessagesTimer
|
id: forwardMessagesTimer
|
||||||
interval: 200
|
interval: 200
|
||||||
|
@ -439,7 +462,8 @@ Page {
|
||||||
|
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
if (chatPage.canSendMessages && !chatPage.isDeletedUser) {
|
if (chatPage.canSendMessages && !chatPage.isDeletedUser) {
|
||||||
tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text);
|
tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text,
|
||||||
|
newMessageInReplyToRow.inReplyToMessage ? newMessageInReplyToRow.inReplyToMessage.id : 0);
|
||||||
}
|
}
|
||||||
fernschreiberUtils.stopGeoLocationUpdates();
|
fernschreiberUtils.stopGeoLocationUpdates();
|
||||||
tdLibWrapper.closeChat(chatInformation.id);
|
tdLibWrapper.closeChat(chatInformation.id);
|
||||||
|
@ -478,7 +502,10 @@ Page {
|
||||||
if (pageStack.depth === 1) {
|
if (pageStack.depth === 1) {
|
||||||
// Only clear chat model if navigated back to overview page. In other cases we keep the information...
|
// Only clear chat model if navigated back to overview page. In other cases we keep the information...
|
||||||
chatModel.clear();
|
chatModel.clear();
|
||||||
|
} else {
|
||||||
|
resetElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,12 +589,12 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onUserFullInfoReceived: {
|
onUserFullInfoReceived: {
|
||||||
if(userFullInfo["@extra"] === chatPartnerInformation.id.toString()) {
|
if ((isPrivateChat || isSecretChat) && userFullInfo["@extra"] === chatPartnerInformation.id.toString()) {
|
||||||
chatPage.botInformation = userFullInfo;
|
chatPage.botInformation = userFullInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onUserFullInfoUpdated: {
|
onUserFullInfoUpdated: {
|
||||||
if(userId === chatPartnerInformation.id) {
|
if ((isPrivateChat || isSecretChat) && userId === chatPartnerInformation.id) {
|
||||||
chatPage.botInformation = userFullInfo;
|
chatPage.botInformation = userFullInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -607,6 +634,15 @@ Page {
|
||||||
|
|
||||||
chatViewCooldownTimer.restart();
|
chatViewCooldownTimer.restart();
|
||||||
chatViewStartupReadTimer.restart();
|
chatViewStartupReadTimer.restart();
|
||||||
|
|
||||||
|
var remainingDoubleTapHints = appSettings.remainingDoubleTapHints;
|
||||||
|
Debug.log("Remaining double tap hints: " + remainingDoubleTapHints);
|
||||||
|
if (remainingDoubleTapHints > 0) {
|
||||||
|
doubleTapHintTimer.start();
|
||||||
|
tapHint.visible = true;
|
||||||
|
tapHintLabel.visible = true;
|
||||||
|
appSettings.remainingDoubleTapHints = remainingDoubleTapHints - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onNewMessageReceived: {
|
onNewMessageReceived: {
|
||||||
if (( chatView.manuallyScrolledToBottom && Qt.application.state === Qt.ApplicationActive ) || message.sender_id.user_id === chatPage.myUserId) {
|
if (( chatView.manuallyScrolledToBottom && Qt.application.state === Qt.ApplicationActive ) || message.sender_id.user_id === chatPage.myUserId) {
|
||||||
|
@ -618,8 +654,8 @@ Page {
|
||||||
onUnreadCountUpdated: {
|
onUnreadCountUpdated: {
|
||||||
Debug.log("[ChatPage] Unread count updated, new count: ", unreadCount);
|
Debug.log("[ChatPage] Unread count updated, new count: ", unreadCount);
|
||||||
chatInformation.unread_count = unreadCount;
|
chatInformation.unread_count = unreadCount;
|
||||||
chatUnreadMessagesItem.visible = ( !chatPage.loading && chatInformation.unread_count > 0 && chatOverviewItem.visible );
|
chatUnreadMessagesItem.visible = ( !chatPage.loading && unreadCount > 0 && chatOverviewItem.visible );
|
||||||
chatUnreadMessagesCount.text = unreadCount > 99 ? "99+" : unreadCount;
|
chatUnreadMessagesCount.text = Functions.formatUnreadCount(unreadCount)
|
||||||
}
|
}
|
||||||
onLastReadSentMessageUpdated: {
|
onLastReadSentMessageUpdated: {
|
||||||
Debug.log("[ChatPage] Updating last read sent index, new index: ", lastReadSentIndex);
|
Debug.log("[ChatPage] Updating last read sent index, new index: ", lastReadSentIndex);
|
||||||
|
@ -634,6 +670,8 @@ Page {
|
||||||
if (chatView.height > chatView.contentHeight) {
|
if (chatView.height > chatView.contentHeight) {
|
||||||
Debug.log("[ChatPage] Chat content quite small...");
|
Debug.log("[ChatPage] Chat content quite small...");
|
||||||
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
||||||
|
} else if (chatPage.messageIdToScrollTo && chatPage.messageIdToScrollTo != "") {
|
||||||
|
showMessage(chatPage.messageIdToScrollTo, false)
|
||||||
}
|
}
|
||||||
chatViewCooldownTimer.restart();
|
chatViewCooldownTimer.restart();
|
||||||
chatViewStartupReadTimer.restart();
|
chatViewStartupReadTimer.restart();
|
||||||
|
@ -1170,7 +1208,7 @@ Page {
|
||||||
readonly property int profileThumbnailDimensions: showUserInfo ? Theme.itemSizeSmall : 0
|
readonly property int profileThumbnailDimensions: showUserInfo ? Theme.itemSizeSmall : 0
|
||||||
readonly property int pageMarginDouble: 2 * Theme.horizontalPageMargin
|
readonly property int pageMarginDouble: 2 * Theme.horizontalPageMargin
|
||||||
readonly property int paddingMediumDouble: 2 * Theme.paddingMedium
|
readonly property int paddingMediumDouble: 2 * Theme.paddingMedium
|
||||||
readonly property int entryWidth: chatView.width - pageMarginDouble //ширина полной строки сообщения вместе с аватаркой
|
readonly property int entryWidth: chatView.width - pageMarginDouble
|
||||||
readonly property int textItemWidth: entryWidth - profileThumbnailDimensions - Theme.paddingSmall
|
readonly property int textItemWidth: entryWidth - profileThumbnailDimensions - Theme.paddingSmall
|
||||||
readonly property int backgroundWidth: page.isPrivateChat ? textItemWidth - pageMarginDouble : textItemWidth //уменьшенная ширина сообщений для приватных чатов
|
readonly property int backgroundWidth: page.isPrivateChat ? textItemWidth - pageMarginDouble : textItemWidth //уменьшенная ширина сообщений для приватных чатов
|
||||||
readonly property int backgroundRadius: textItemWidth/50
|
readonly property int backgroundRadius: textItemWidth/50
|
||||||
|
@ -1196,10 +1234,9 @@ Page {
|
||||||
manuallyScrolledToBottom = chatView.atYEnd
|
manuallyScrolledToBottom = chatView.atYEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollToIndex(index) {
|
function scrollToIndex(index, mode) {
|
||||||
if(index > 0 && index < chatView.count) {
|
if(index > 0 && index < chatView.count) {
|
||||||
positionViewAtIndex(index, ListView.Contain)
|
positionViewAtIndex(index, (mode === undefined) ? ListView.Contain : mode)
|
||||||
// currentIndex = index;
|
|
||||||
if(index === chatView.count - 1) {
|
if(index === chatView.count - 1) {
|
||||||
manuallyScrolledToBottom = true;
|
manuallyScrolledToBottom = true;
|
||||||
}
|
}
|
||||||
|
@ -1348,6 +1385,7 @@ Page {
|
||||||
messageId: model.message_id
|
messageId: model.message_id
|
||||||
messageViewCount: model.view_count
|
messageViewCount: model.view_count
|
||||||
reactions: model.reactions
|
reactions: model.reactions
|
||||||
|
chatReactions: availableReactions
|
||||||
messageIndex: model.index
|
messageIndex: model.index
|
||||||
hasContentComponent: !!myMessage.content && chatView.delegateMessagesContent.indexOf(model.content_type) > -1
|
hasContentComponent: !!myMessage.content && chatView.delegateMessagesContent.indexOf(model.content_type) > -1
|
||||||
canReplyToMessage: chatPage.canSendMessages
|
canReplyToMessage: chatPage.canSendMessages
|
||||||
|
@ -1427,7 +1465,7 @@ Page {
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
anchors.centerIn: chatUnreadMessagesCountBackground
|
anchors.centerIn: chatUnreadMessagesCountBackground
|
||||||
visible: chatUnreadMessagesItem.visible
|
visible: chatUnreadMessagesItem.visible
|
||||||
text: chatInformation.unread_count > 99 ? "99+" : chatInformation.unread_count
|
text: Functions.formatUnreadCount(chatInformation.unread_count)
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -1596,7 +1634,7 @@ Page {
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
id: attachImageIconButton
|
id: attachImageIconButton
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
visible: chatPage.hasSendPrivilege("can_send_photos")
|
||||||
icon.source: "image://theme/icon-m-image"
|
icon.source: "image://theme/icon-m-image"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var picker = pageStack.push("Sailfish.Pickers.ImagePickerPage", {
|
var picker = pageStack.push("Sailfish.Pickers.ImagePickerPage", {
|
||||||
|
@ -1612,7 +1650,7 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton {
|
IconButton {
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
visible: chatPage.hasSendPrivilege("can_send_videos")
|
||||||
icon.source: "image://theme/icon-m-video"
|
icon.source: "image://theme/icon-m-video"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var picker = pageStack.push("Sailfish.Pickers.VideoPickerPage", {
|
var picker = pageStack.push("Sailfish.Pickers.VideoPickerPage", {
|
||||||
|
@ -1628,7 +1666,7 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton {
|
IconButton {
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
visible: chatPage.hasSendPrivilege("can_send_voice_notes")
|
||||||
icon.source: "image://theme/icon-m-mic"
|
icon.source: "image://theme/icon-m-mic"
|
||||||
icon.sourceSize {
|
icon.sourceSize {
|
||||||
width: Theme.iconSizeMedium
|
width: Theme.iconSizeMedium
|
||||||
|
@ -1641,7 +1679,7 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton {
|
IconButton {
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
visible: chatPage.hasSendPrivilege("can_send_documents")
|
||||||
icon.source: "image://theme/icon-m-document"
|
icon.source: "image://theme/icon-m-document"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var picker = pageStack.push("Sailfish.Pickers.FilePickerPage", {
|
var picker = pageStack.push("Sailfish.Pickers.FilePickerPage", {
|
||||||
|
@ -2154,4 +2192,31 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: doubleTapHintTimer
|
||||||
|
running: true
|
||||||
|
triggeredOnStart: false
|
||||||
|
repeat: false
|
||||||
|
interval: 6000
|
||||||
|
onTriggered: {
|
||||||
|
tapHint.visible = false;
|
||||||
|
tapHintLabel.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TapInteractionHint {
|
||||||
|
id: tapHint
|
||||||
|
loops: Animation.Infinite
|
||||||
|
taps: 2
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
InteractionHintLabel {
|
||||||
|
id: tapHintLabel
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
text: qsTr("Double-tap on a message to choose a reaction")
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,10 +143,11 @@ Page {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onUsersReceived: {
|
onMessageSendersReceived: {
|
||||||
|
Debug.log("Received poll users...")
|
||||||
if(extra === optionDelegate.usersResponseIdentifierString) {
|
if(extra === optionDelegate.usersResponseIdentifierString) {
|
||||||
for(var i = 0; i < userIds.length; i += 1) {
|
for(var i = 0; i < senders.length; i += 1) {
|
||||||
optionDelegate.users.append({id: userIds[i], user:tdLibWrapper.getUserInformation(userIds[i])});
|
optionDelegate.users.append({id: senders[i].user_id, user:tdLibWrapper.getUserInformation(senders[i].user_id)});
|
||||||
}
|
}
|
||||||
loadUsersTimer.start();
|
loadUsersTimer.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,26 @@
|
||||||
# * date Author's Name <author's email> version-release
|
# * date Author's Name <author's email> version-release
|
||||||
# - Summary of changes
|
# - Summary of changes
|
||||||
|
|
||||||
|
* Sun Dec 03 2023 Sebastian J. Wolf <sebastian@ygriega.de> 0.17
|
||||||
|
- Update to TDLib 1.8.21, expect some hiccups ;)
|
||||||
|
- Added contacts sync (OpenRepos builds only)
|
||||||
|
- Tweaks to reaction handling (opens now on double click or click + star)
|
||||||
|
- Option to jump to quoted message
|
||||||
|
- Option to highlight unread conversations
|
||||||
|
- Option to suppress notification previews
|
||||||
|
- Option to append last message content to notifications
|
||||||
|
- Added "unread mention" indicator to chat list
|
||||||
|
- Improve message when search yields no results
|
||||||
|
- New unread info for chats with high amount of unread messages
|
||||||
|
- Setting for session inactivity timeout
|
||||||
|
- UI improvements in landscape mode
|
||||||
|
- Fix: Restore video functionality on SFOS 4.5
|
||||||
|
- Fix: Chat list timestamp now updated more reliably
|
||||||
|
- Fix: Faster reconnect after network changes
|
||||||
|
- Fix: Some URLs couldn't be opened
|
||||||
|
- Updated translations for several languages
|
||||||
|
- Thanks to monich, nephros, arustg, jgibbon, carlosgonz0, okruhliak, dscheinah, pherjung and mbarashkov for your contributions
|
||||||
|
|
||||||
* Sun Jun 12 2022 Sebastian J. Wolf <sebastian@ygriega.de> 0.16
|
* Sun Jun 12 2022 Sebastian J. Wolf <sebastian@ygriega.de> 0.16
|
||||||
- Support message reactions
|
- Support message reactions
|
||||||
- Support t.me/+... links
|
- Support t.me/+... links
|
||||||
|
|
|
@ -10,9 +10,9 @@ Name: harbour-fernschreiber
|
||||||
%define __requires_exclude ^lib(tdjson|ssl|crypto).*$
|
%define __requires_exclude ^lib(tdjson|ssl|crypto).*$
|
||||||
# << macros
|
# << macros
|
||||||
|
|
||||||
Summary: Fernschreiber is a Telegram client for Sailfish OS
|
Summary: Fernschreiber is a Telegram client for Aurora OS
|
||||||
Version: 0.17
|
Version: 0.17
|
||||||
Release: 3
|
Release: 12
|
||||||
Group: Qt/Qt
|
Group: Qt/Qt
|
||||||
License: LICENSE
|
License: LICENSE
|
||||||
URL: http://werkwolf.eu/
|
URL: http://werkwolf.eu/
|
||||||
|
|
|
@ -29,14 +29,19 @@ namespace {
|
||||||
const QString KEY_ANIMATE_STICKERS("animateStickers");
|
const QString KEY_ANIMATE_STICKERS("animateStickers");
|
||||||
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
||||||
const QString KEY_NOTIFICATION_SOUNDS_ENABLED("notificationSoundsEnabled");
|
const QString KEY_NOTIFICATION_SOUNDS_ENABLED("notificationSoundsEnabled");
|
||||||
|
const QString KEY_NOTIFICATION_SUPPRESS_ENABLED("notificationSuppressContent");
|
||||||
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
||||||
|
const QString KEY_NOTIFICATION_ALWAYS_SHOW_PREVIEW("notificationAlwaysShowPreview");
|
||||||
|
const QString KEY_GO_TO_QUOTED_MESSAGE("goToQuotedMessage");
|
||||||
const QString KEY_STORAGE_OPTIMIZER("useStorageOptimizer");
|
const QString KEY_STORAGE_OPTIMIZER("useStorageOptimizer");
|
||||||
const QString KEY_INLINEBOT_LOCATION_ACCESS("allowInlineBotLocationAccess");
|
const QString KEY_INLINEBOT_LOCATION_ACCESS("allowInlineBotLocationAccess");
|
||||||
const QString KEY_REMAINING_INTERACTION_HINTS("remainingInteractionHints");
|
const QString KEY_REMAINING_INTERACTION_HINTS("remainingInteractionHints");
|
||||||
|
const QString KEY_REMAINING_DOUBLE_TAP_HINTS("remainingDoubleTapHints");
|
||||||
const QString KEY_ONLINE_ONLY_MODE("onlineOnlyMode");
|
const QString KEY_ONLINE_ONLY_MODE("onlineOnlyMode");
|
||||||
const QString KEY_DELAY_MESSAGE_READ("delayMessageRead");
|
const QString KEY_DELAY_MESSAGE_READ("delayMessageRead");
|
||||||
const QString KEY_FOCUS_TEXTAREA_ON_CHAT_OPEN("focusTextAreaOnChatOpen");
|
const QString KEY_FOCUS_TEXTAREA_ON_CHAT_OPEN("focusTextAreaOnChatOpen");
|
||||||
const QString KEY_SPONSORED_MESS("sponsoredMess");
|
const QString KEY_SPONSORED_MESS("sponsoredMess");
|
||||||
|
const QString KEY_HIGHLIGHT_UNREADCONVS("highlightUnreadConversations");
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSettings::AppSettings(QObject *parent) : QObject(parent), settings(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/de.ygriega/fernschreiber/settings.conf", QSettings::NativeFormat)
|
AppSettings::AppSettings(QObject *parent) : QObject(parent), settings(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/de.ygriega/fernschreiber/settings.conf", QSettings::NativeFormat)
|
||||||
|
@ -155,6 +160,20 @@ void AppSettings::setNotificationSoundsEnabled(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppSettings::notificationSuppressContent() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_NOTIFICATION_SUPPRESS_ENABLED, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setNotificationSuppressContent(bool enable)
|
||||||
|
{
|
||||||
|
if (notificationSuppressContent() != enable) {
|
||||||
|
LOG(KEY_NOTIFICATION_SUPPRESS_ENABLED << enable);
|
||||||
|
settings.setValue(KEY_NOTIFICATION_SUPPRESS_ENABLED, enable);
|
||||||
|
emit notificationSuppressContentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppSettings::NotificationFeedback AppSettings::notificationFeedback() const
|
AppSettings::NotificationFeedback AppSettings::notificationFeedback() const
|
||||||
{
|
{
|
||||||
return (NotificationFeedback) settings.value(KEY_NOTIFICATION_FEEDBACK, (int) NotificationFeedbackAll).toInt();
|
return (NotificationFeedback) settings.value(KEY_NOTIFICATION_FEEDBACK, (int) NotificationFeedbackAll).toInt();
|
||||||
|
@ -169,6 +188,34 @@ void AppSettings::setNotificationFeedback(NotificationFeedback feedback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppSettings::notificationAlwaysShowPreview() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_NOTIFICATION_ALWAYS_SHOW_PREVIEW, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setNotificationAlwaysShowPreview(bool enable)
|
||||||
|
{
|
||||||
|
if (notificationAlwaysShowPreview() != enable) {
|
||||||
|
LOG(KEY_NOTIFICATION_ALWAYS_SHOW_PREVIEW << enable);
|
||||||
|
settings.setValue(KEY_NOTIFICATION_ALWAYS_SHOW_PREVIEW, enable);
|
||||||
|
emit notificationAlwaysShowPreviewChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppSettings::goToQuotedMessage() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_GO_TO_QUOTED_MESSAGE, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setGoToQuotedMessage(bool enable)
|
||||||
|
{
|
||||||
|
if (goToQuotedMessage() != enable) {
|
||||||
|
LOG(KEY_GO_TO_QUOTED_MESSAGE << enable);
|
||||||
|
settings.setValue(KEY_GO_TO_QUOTED_MESSAGE, enable);
|
||||||
|
emit goToQuotedMessageChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AppSettings::storageOptimizer() const
|
bool AppSettings::storageOptimizer() const
|
||||||
{
|
{
|
||||||
return settings.value(KEY_STORAGE_OPTIMIZER, true).toBool();
|
return settings.value(KEY_STORAGE_OPTIMIZER, true).toBool();
|
||||||
|
@ -212,6 +259,20 @@ void AppSettings::setRemainingInteractionHints(int remainingHints)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AppSettings::remainingDoubleTapHints() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_REMAINING_DOUBLE_TAP_HINTS, 3).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setRemainingDoubleTapHints(int remainingHints)
|
||||||
|
{
|
||||||
|
if (remainingDoubleTapHints() != remainingHints) {
|
||||||
|
LOG(KEY_REMAINING_DOUBLE_TAP_HINTS << remainingHints);
|
||||||
|
settings.setValue(KEY_REMAINING_DOUBLE_TAP_HINTS, remainingHints);
|
||||||
|
emit remainingDoubleTapHintsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AppSettings::onlineOnlyMode() const
|
bool AppSettings::onlineOnlyMode() const
|
||||||
{
|
{
|
||||||
return settings.value(KEY_ONLINE_ONLY_MODE, false).toBool();
|
return settings.value(KEY_ONLINE_ONLY_MODE, false).toBool();
|
||||||
|
@ -240,6 +301,20 @@ void AppSettings::setDelayMessageRead(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppSettings::highlightUnreadConversations() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_HIGHLIGHT_UNREADCONVS, true).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setHighlightUnreadConversations(bool enable)
|
||||||
|
{
|
||||||
|
if (highlightUnreadConversations() != enable) {
|
||||||
|
LOG(KEY_HIGHLIGHT_UNREADCONVS << enable);
|
||||||
|
settings.setValue(KEY_HIGHLIGHT_UNREADCONVS, enable);
|
||||||
|
emit highlightUnreadConversationsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AppSettings::getFocusTextAreaOnChatOpen() const
|
bool AppSettings::getFocusTextAreaOnChatOpen() const
|
||||||
{
|
{
|
||||||
return settings.value(KEY_FOCUS_TEXTAREA_ON_CHAT_OPEN, false).toBool();
|
return settings.value(KEY_FOCUS_TEXTAREA_ON_CHAT_OPEN, false).toBool();
|
||||||
|
|
|
@ -32,14 +32,19 @@ class AppSettings : public QObject {
|
||||||
Q_PROPERTY(bool animateStickers READ animateStickers WRITE setAnimateStickers NOTIFY animateStickersChanged)
|
Q_PROPERTY(bool animateStickers READ animateStickers WRITE setAnimateStickers NOTIFY animateStickersChanged)
|
||||||
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
||||||
Q_PROPERTY(bool notificationSoundsEnabled READ notificationSoundsEnabled WRITE setNotificationSoundsEnabled NOTIFY notificationSoundsEnabledChanged)
|
Q_PROPERTY(bool notificationSoundsEnabled READ notificationSoundsEnabled WRITE setNotificationSoundsEnabled NOTIFY notificationSoundsEnabledChanged)
|
||||||
|
Q_PROPERTY(bool notificationSuppressContent READ notificationSuppressContent WRITE setNotificationSuppressContent NOTIFY notificationSuppressContentChanged)
|
||||||
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
||||||
|
Q_PROPERTY(bool notificationAlwaysShowPreview READ notificationAlwaysShowPreview WRITE setNotificationAlwaysShowPreview NOTIFY notificationAlwaysShowPreviewChanged)
|
||||||
|
Q_PROPERTY(bool goToQuotedMessage READ goToQuotedMessage WRITE setGoToQuotedMessage NOTIFY goToQuotedMessageChanged)
|
||||||
Q_PROPERTY(bool storageOptimizer READ storageOptimizer WRITE setStorageOptimizer NOTIFY storageOptimizerChanged)
|
Q_PROPERTY(bool storageOptimizer READ storageOptimizer WRITE setStorageOptimizer NOTIFY storageOptimizerChanged)
|
||||||
Q_PROPERTY(bool allowInlineBotLocationAccess READ allowInlineBotLocationAccess WRITE setAllowInlineBotLocationAccess NOTIFY allowInlineBotLocationAccessChanged)
|
Q_PROPERTY(bool allowInlineBotLocationAccess READ allowInlineBotLocationAccess WRITE setAllowInlineBotLocationAccess NOTIFY allowInlineBotLocationAccessChanged)
|
||||||
Q_PROPERTY(int remainingInteractionHints READ remainingInteractionHints WRITE setRemainingInteractionHints NOTIFY remainingInteractionHintsChanged)
|
Q_PROPERTY(int remainingInteractionHints READ remainingInteractionHints WRITE setRemainingInteractionHints NOTIFY remainingInteractionHintsChanged)
|
||||||
|
Q_PROPERTY(int remainingDoubleTapHints READ remainingDoubleTapHints WRITE setRemainingDoubleTapHints NOTIFY remainingDoubleTapHintsChanged)
|
||||||
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
|
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
|
||||||
Q_PROPERTY(bool delayMessageRead READ delayMessageRead WRITE setDelayMessageRead NOTIFY delayMessageReadChanged)
|
Q_PROPERTY(bool delayMessageRead READ delayMessageRead WRITE setDelayMessageRead NOTIFY delayMessageReadChanged)
|
||||||
Q_PROPERTY(bool focusTextAreaOnChatOpen READ getFocusTextAreaOnChatOpen WRITE setFocusTextAreaOnChatOpen NOTIFY focusTextAreaOnChatOpenChanged)
|
Q_PROPERTY(bool focusTextAreaOnChatOpen READ getFocusTextAreaOnChatOpen WRITE setFocusTextAreaOnChatOpen NOTIFY focusTextAreaOnChatOpenChanged)
|
||||||
Q_PROPERTY(SponsoredMess sponsoredMess READ getSponsoredMess WRITE setSponsoredMess NOTIFY sponsoredMessChanged)
|
Q_PROPERTY(SponsoredMess sponsoredMess READ getSponsoredMess WRITE setSponsoredMess NOTIFY sponsoredMessChanged)
|
||||||
|
Q_PROPERTY(bool highlightUnreadConversations READ highlightUnreadConversations WRITE setHighlightUnreadConversations NOTIFY highlightUnreadConversationsChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum SponsoredMess {
|
enum SponsoredMess {
|
||||||
|
@ -83,9 +88,18 @@ public:
|
||||||
bool notificationSoundsEnabled() const;
|
bool notificationSoundsEnabled() const;
|
||||||
void setNotificationSoundsEnabled(bool enable);
|
void setNotificationSoundsEnabled(bool enable);
|
||||||
|
|
||||||
|
bool notificationSuppressContent() const;
|
||||||
|
void setNotificationSuppressContent(bool enable);
|
||||||
|
|
||||||
NotificationFeedback notificationFeedback() const;
|
NotificationFeedback notificationFeedback() const;
|
||||||
void setNotificationFeedback(NotificationFeedback feedback);
|
void setNotificationFeedback(NotificationFeedback feedback);
|
||||||
|
|
||||||
|
bool notificationAlwaysShowPreview() const;
|
||||||
|
void setNotificationAlwaysShowPreview(bool enable);
|
||||||
|
|
||||||
|
bool goToQuotedMessage() const;
|
||||||
|
void setGoToQuotedMessage(bool enable);
|
||||||
|
|
||||||
bool storageOptimizer() const;
|
bool storageOptimizer() const;
|
||||||
void setStorageOptimizer(bool enable);
|
void setStorageOptimizer(bool enable);
|
||||||
|
|
||||||
|
@ -95,6 +109,9 @@ public:
|
||||||
int remainingInteractionHints() const;
|
int remainingInteractionHints() const;
|
||||||
void setRemainingInteractionHints(int remainingHints);
|
void setRemainingInteractionHints(int remainingHints);
|
||||||
|
|
||||||
|
int remainingDoubleTapHints() const;
|
||||||
|
void setRemainingDoubleTapHints(int remainingHints);
|
||||||
|
|
||||||
bool onlineOnlyMode() const;
|
bool onlineOnlyMode() const;
|
||||||
void setOnlineOnlyMode(bool enable);
|
void setOnlineOnlyMode(bool enable);
|
||||||
|
|
||||||
|
@ -107,6 +124,9 @@ public:
|
||||||
SponsoredMess getSponsoredMess() const;
|
SponsoredMess getSponsoredMess() const;
|
||||||
void setSponsoredMess(SponsoredMess sponsoredMess);
|
void setSponsoredMess(SponsoredMess sponsoredMess);
|
||||||
|
|
||||||
|
bool highlightUnreadConversations() const;
|
||||||
|
void setHighlightUnreadConversations(bool enable);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendByEnterChanged();
|
void sendByEnterChanged();
|
||||||
void focusTextAreaAfterSendChanged();
|
void focusTextAreaAfterSendChanged();
|
||||||
|
@ -116,14 +136,19 @@ signals:
|
||||||
void animateStickersChanged();
|
void animateStickersChanged();
|
||||||
void notificationTurnsDisplayOnChanged();
|
void notificationTurnsDisplayOnChanged();
|
||||||
void notificationSoundsEnabledChanged();
|
void notificationSoundsEnabledChanged();
|
||||||
|
void notificationSuppressContentChanged();
|
||||||
void notificationFeedbackChanged();
|
void notificationFeedbackChanged();
|
||||||
|
void notificationAlwaysShowPreviewChanged();
|
||||||
|
void goToQuotedMessageChanged();
|
||||||
void storageOptimizerChanged();
|
void storageOptimizerChanged();
|
||||||
void allowInlineBotLocationAccessChanged();
|
void allowInlineBotLocationAccessChanged();
|
||||||
void remainingInteractionHintsChanged();
|
void remainingInteractionHintsChanged();
|
||||||
|
void remainingDoubleTapHintsChanged();
|
||||||
void onlineOnlyModeChanged();
|
void onlineOnlyModeChanged();
|
||||||
void delayMessageReadChanged();
|
void delayMessageReadChanged();
|
||||||
void focusTextAreaOnChatOpenChanged();
|
void focusTextAreaOnChatOpenChanged();
|
||||||
void sponsoredMessChanged();
|
void sponsoredMessChanged();
|
||||||
|
void highlightUnreadConversationsChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace {
|
||||||
const QString UNREAD_COUNT("unread_count");
|
const QString UNREAD_COUNT("unread_count");
|
||||||
const QString UNREAD_MENTION_COUNT("unread_mention_count");
|
const QString UNREAD_MENTION_COUNT("unread_mention_count");
|
||||||
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
|
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
|
||||||
|
const QString AVAILABLE_REACTIONS("available_reactions");
|
||||||
const QString NOTIFICATION_SETTINGS("notification_settings");
|
const QString NOTIFICATION_SETTINGS("notification_settings");
|
||||||
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
||||||
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
||||||
|
@ -70,6 +71,7 @@ public:
|
||||||
int unreadCount() const;
|
int unreadCount() const;
|
||||||
int unreadMentionCount() const;
|
int unreadMentionCount() const;
|
||||||
int unreadReactionCount() const;
|
int unreadReactionCount() const;
|
||||||
|
QVariant availableReactions() const;
|
||||||
QVariant photoSmall() const;
|
QVariant photoSmall() const;
|
||||||
qlonglong lastReadInboxMessageId() const;
|
qlonglong lastReadInboxMessageId() const;
|
||||||
qlonglong senderUserId() const;
|
qlonglong senderUserId() const;
|
||||||
|
@ -168,6 +170,11 @@ int ChatListModel::ChatData::unreadMentionCount() const
|
||||||
return chatData.value(UNREAD_MENTION_COUNT).toInt();
|
return chatData.value(UNREAD_MENTION_COUNT).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant ChatListModel::ChatData::availableReactions() const
|
||||||
|
{
|
||||||
|
return chatData.value(AVAILABLE_REACTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
int ChatListModel::ChatData::unreadReactionCount() const
|
int ChatListModel::ChatData::unreadReactionCount() const
|
||||||
{
|
{
|
||||||
return chatData.value(UNREAD_REACTION_COUNT).toInt();
|
return chatData.value(UNREAD_REACTION_COUNT).toInt();
|
||||||
|
@ -400,6 +407,7 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper, AppSettings *appSetting
|
||||||
connect(tdLibWrapper, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SLOT(handleChatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
connect(tdLibWrapper, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SLOT(handleChatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadMentionCountUpdated(qlonglong, int)));
|
connect(tdLibWrapper, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadMentionCountUpdated(qlonglong, int)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadReactionCountUpdated(qlonglong, int)));
|
connect(tdLibWrapper, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SLOT(handleChatUnreadReactionCountUpdated(qlonglong, int)));
|
||||||
|
connect(tdLibWrapper, SIGNAL(chatAvailableReactionsUpdated(qlonglong,QVariantMap)), this, SLOT(handleChatAvailableReactionsUpdated(qlonglong,QVariantMap)));
|
||||||
|
|
||||||
// Don't start the timer until we have at least one chat
|
// Don't start the timer until we have at least one chat
|
||||||
relativeTimeRefreshTimer = new QTimer(this);
|
relativeTimeRefreshTimer = new QTimer(this);
|
||||||
|
@ -436,6 +444,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
|
||||||
roles.insert(ChatListModel::RoleUnreadCount, "unread_count");
|
roles.insert(ChatListModel::RoleUnreadCount, "unread_count");
|
||||||
roles.insert(ChatListModel::RoleUnreadMentionCount, "unread_mention_count");
|
roles.insert(ChatListModel::RoleUnreadMentionCount, "unread_mention_count");
|
||||||
roles.insert(ChatListModel::RoleUnreadReactionCount, "unread_reaction_count");
|
roles.insert(ChatListModel::RoleUnreadReactionCount, "unread_reaction_count");
|
||||||
|
roles.insert(ChatListModel::RoleAvailableReactions, "available_reactions");
|
||||||
roles.insert(ChatListModel::RoleLastReadInboxMessageId, "last_read_inbox_message_id");
|
roles.insert(ChatListModel::RoleLastReadInboxMessageId, "last_read_inbox_message_id");
|
||||||
roles.insert(ChatListModel::RoleLastMessageSenderId, "last_message_sender_id");
|
roles.insert(ChatListModel::RoleLastMessageSenderId, "last_message_sender_id");
|
||||||
roles.insert(ChatListModel::RoleLastMessageDate, "last_message_date");
|
roles.insert(ChatListModel::RoleLastMessageDate, "last_message_date");
|
||||||
|
@ -472,6 +481,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
|
||||||
case ChatListModel::RolePhotoSmall: return data->photoSmall();
|
case ChatListModel::RolePhotoSmall: return data->photoSmall();
|
||||||
case ChatListModel::RoleUnreadCount: return data->unreadCount();
|
case ChatListModel::RoleUnreadCount: return data->unreadCount();
|
||||||
case ChatListModel::RoleUnreadMentionCount: return data->unreadMentionCount();
|
case ChatListModel::RoleUnreadMentionCount: return data->unreadMentionCount();
|
||||||
|
case ChatListModel::RoleAvailableReactions: return data->availableReactions();
|
||||||
case ChatListModel::RoleUnreadReactionCount: return data->unreadReactionCount();
|
case ChatListModel::RoleUnreadReactionCount: return data->unreadReactionCount();
|
||||||
case ChatListModel::RoleLastReadInboxMessageId: return data->lastReadInboxMessageId();
|
case ChatListModel::RoleLastReadInboxMessageId: return data->lastReadInboxMessageId();
|
||||||
case ChatListModel::RoleLastMessageSenderId: return data->senderUserId();
|
case ChatListModel::RoleLastMessageSenderId: return data->senderUserId();
|
||||||
|
@ -561,6 +571,15 @@ int ChatListModel::updateChatOrder(int chatIndex)
|
||||||
return newIndex;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatListModel::enableRefreshTimer()
|
||||||
|
{
|
||||||
|
// Start timestamp refresh timer if not yet active (usually when the first visible chat is discovered)
|
||||||
|
if (!relativeTimeRefreshTimer->isActive()) {
|
||||||
|
LOG("Enabling refresh timer");
|
||||||
|
relativeTimeRefreshTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatListModel::calculateUnreadState()
|
void ChatListModel::calculateUnreadState()
|
||||||
{
|
{
|
||||||
if (this->appSettings->onlineOnlyMode()) {
|
if (this->appSettings->onlineOnlyMode()) {
|
||||||
|
@ -599,6 +618,7 @@ void ChatListModel::addVisibleChat(ChatData *chat)
|
||||||
this->tdLibWrapper->registerJoinChat();
|
this->tdLibWrapper->registerJoinChat();
|
||||||
emit chatJoined(chat->chatId, chat->chatData.value("title").toString());
|
emit chatJoined(chat->chatId, chat->chatData.value("title").toString());
|
||||||
}
|
}
|
||||||
|
enableRefreshTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatListModel::updateChatVisibility(const TDLibWrapper::Group *group)
|
void ChatListModel::updateChatVisibility(const TDLibWrapper::Group *group)
|
||||||
|
@ -687,6 +707,7 @@ void ChatListModel::setShowAllChats(bool showAll)
|
||||||
|
|
||||||
void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded)
|
void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded)
|
||||||
{
|
{
|
||||||
|
LOG("New chat discovered");
|
||||||
ChatData *chat = new ChatData(tdLibWrapper, chatToBeAdded);
|
ChatData *chat = new ChatData(tdLibWrapper, chatToBeAdded);
|
||||||
|
|
||||||
const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId);
|
const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId);
|
||||||
|
@ -705,12 +726,8 @@ void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &cha
|
||||||
LOG("Hidden chat" << chat->chatId);
|
LOG("Hidden chat" << chat->chatId);
|
||||||
hiddenChats.insert(chat->chatId, chat);
|
hiddenChats.insert(chat->chatId, chat);
|
||||||
} else {
|
} else {
|
||||||
|
LOG("Visible chat" << chat->chatId);
|
||||||
addVisibleChat(chat);
|
addVisibleChat(chat);
|
||||||
|
|
||||||
// Start timestamp refresh timer when the first visible chat is discovered
|
|
||||||
if (!relativeTimeRefreshTimer->isActive()) {
|
|
||||||
relativeTimeRefreshTimer->start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,10 +1046,31 @@ void ChatListModel::handleChatUnreadReactionCountUpdated(qlonglong chatId, int u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatListModel::handleChatAvailableReactionsUpdated(qlonglong chatId, const QVariantMap availableReactions)
|
||||||
|
{
|
||||||
|
if (chatIndexMap.contains(chatId)) {
|
||||||
|
LOG("Updating available reaction type for" << chatId << availableReactions);
|
||||||
|
const int chatIndex = chatIndexMap.value(chatId);
|
||||||
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
|
chat->chatData.insert(AVAILABLE_REACTIONS, availableReactions);
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
changedRoles.append(ChatListModel::RoleAvailableReactions);
|
||||||
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
|
} else {
|
||||||
|
ChatData *chat = hiddenChats.value(chatId);
|
||||||
|
if (chat) {
|
||||||
|
LOG("Updating available reaction type for hidden chat" << chatId << availableReactions);
|
||||||
|
chat->chatData.insert(AVAILABLE_REACTIONS, availableReactions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatListModel::handleRelativeTimeRefreshTimer()
|
void ChatListModel::handleRelativeTimeRefreshTimer()
|
||||||
{
|
{
|
||||||
LOG("Refreshing timestamps");
|
LOG("Refreshing timestamps");
|
||||||
QVector<int> roles;
|
QVector<int> roles;
|
||||||
roles.append(ChatListModel::RoleLastMessageDate);
|
roles.append(ChatListModel::RoleLastMessageDate);
|
||||||
|
roles.append(ChatListModel::RoleLastMessageStatus);
|
||||||
emit dataChanged(index(0), index(chatList.size() - 1), roles);
|
emit dataChanged(index(0), index(chatList.size() - 1), roles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
RoleUnreadCount,
|
RoleUnreadCount,
|
||||||
RoleUnreadMentionCount,
|
RoleUnreadMentionCount,
|
||||||
RoleUnreadReactionCount,
|
RoleUnreadReactionCount,
|
||||||
|
RoleAvailableReactions,
|
||||||
RoleLastReadInboxMessageId,
|
RoleLastReadInboxMessageId,
|
||||||
RoleLastMessageSenderId,
|
RoleLastMessageSenderId,
|
||||||
RoleLastMessageDate,
|
RoleLastMessageDate,
|
||||||
|
@ -93,6 +94,7 @@ private slots:
|
||||||
void handleChatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
void handleChatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
||||||
void handleChatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
void handleChatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
||||||
void handleChatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
|
void handleChatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
|
||||||
|
void handleChatAvailableReactionsUpdated(qlonglong chatId, const QVariantMap availableReactions);
|
||||||
void handleRelativeTimeRefreshTimer();
|
void handleRelativeTimeRefreshTimer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -108,6 +110,7 @@ private:
|
||||||
void updateChatVisibility(const TDLibWrapper::Group *group);
|
void updateChatVisibility(const TDLibWrapper::Group *group);
|
||||||
void updateSecretChatVisibility(const QVariantMap secretChatDetails);
|
void updateSecretChatVisibility(const QVariantMap secretChatDetails);
|
||||||
int updateChatOrder(int chatIndex);
|
int updateChatOrder(int chatIndex);
|
||||||
|
void enableRefreshTimer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TDLibWrapper *tdLibWrapper;
|
TDLibWrapper *tdLibWrapper;
|
||||||
|
|
|
@ -363,6 +363,15 @@ void ChatModel::initialize(const QVariantMap &chatInformation)
|
||||||
tdLibWrapper->getChatHistory(chatId, this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toLongLong());
|
tdLibWrapper->getChatHistory(chatId, this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toLongLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatModel::triggerLoadHistoryForMessage(qlonglong messageId)
|
||||||
|
{
|
||||||
|
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
||||||
|
LOG("Trigger loading message with id..." << messageId);
|
||||||
|
this->inIncrementalUpdate = true;
|
||||||
|
this->tdLibWrapper->getChatHistory(chatId, messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatModel::triggerLoadMoreHistory()
|
void ChatModel::triggerLoadMoreHistory()
|
||||||
{
|
{
|
||||||
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
||||||
|
@ -400,6 +409,17 @@ QVariantMap ChatModel::getMessage(int index)
|
||||||
return QVariantMap();
|
return QVariantMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ChatModel::getMessageIndex(qlonglong messageId)
|
||||||
|
{
|
||||||
|
if (messages.size() == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (messageIndexMap.contains(messageId)) {
|
||||||
|
return messageIndexMap.value(messageId);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int ChatModel::getLastReadMessageIndex()
|
int ChatModel::getLastReadMessageIndex()
|
||||||
{
|
{
|
||||||
LOG("Obtaining last read message index");
|
LOG("Obtaining last read message index");
|
||||||
|
|
|
@ -40,12 +40,14 @@ public:
|
||||||
Q_INVOKABLE void clear(bool contentOnly = false);
|
Q_INVOKABLE void clear(bool contentOnly = false);
|
||||||
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
||||||
Q_INVOKABLE void triggerLoadMoreHistory();
|
Q_INVOKABLE void triggerLoadMoreHistory();
|
||||||
|
Q_INVOKABLE void triggerLoadHistoryForMessage(qlonglong messageId);
|
||||||
Q_INVOKABLE void triggerLoadMoreFuture();
|
Q_INVOKABLE void triggerLoadMoreFuture();
|
||||||
Q_INVOKABLE QVariantMap getChatInformation();
|
Q_INVOKABLE QVariantMap getChatInformation();
|
||||||
Q_INVOKABLE QVariantMap getMessage(int index);
|
Q_INVOKABLE QVariantMap getMessage(int index);
|
||||||
Q_INVOKABLE int getLastReadMessageIndex();
|
Q_INVOKABLE int getLastReadMessageIndex();
|
||||||
Q_INVOKABLE void setSearchQuery(const QString newSearchQuery);
|
Q_INVOKABLE void setSearchQuery(const QString newSearchQuery);
|
||||||
|
|
||||||
|
Q_INVOKABLE int getMessageIndex(qlonglong messageId);
|
||||||
QVariantMap smallPhoto() const;
|
QVariantMap smallPhoto() const;
|
||||||
qlonglong getChatId() const;
|
qlonglong getChatId() const;
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ QVariant ContactsModel::data(const QModelIndex &index, int role) const
|
||||||
case ContactRole::RoleDisplay: return requestedContact;
|
case ContactRole::RoleDisplay: return requestedContact;
|
||||||
case ContactRole::RoleTitle: return QString(requestedContact.value("first_name").toString() + " " + requestedContact.value("last_name").toString()).trimmed();
|
case ContactRole::RoleTitle: return QString(requestedContact.value("first_name").toString() + " " + requestedContact.value("last_name").toString()).trimmed();
|
||||||
case ContactRole::RoleUserId: return requestedContact.value("id");
|
case ContactRole::RoleUserId: return requestedContact.value("id");
|
||||||
case ContactRole::RoleUsername: return requestedContact.value("username");
|
case ContactRole::RoleUsername: return requestedContact.value("usernames").toMap().value("editable_username").toString();
|
||||||
case ContactRole::RolePhotoSmall: return requestedContact.value("profile_photo").toMap().value("small");
|
case ContactRole::RolePhotoSmall: return requestedContact.value("profile_photo").toMap().value("small");
|
||||||
case ContactRole::RoleUserStatus: return requestedContact.value("status").toMap().value("@type");
|
case ContactRole::RoleUserStatus: return requestedContact.value("status").toMap().value("@type");
|
||||||
case ContactRole::RoleUserLastOnline: return requestedContact.value("status").toMap().value("was_online");
|
case ContactRole::RoleUserLastOnline: return requestedContact.value("status").toMap().value("was_online");
|
||||||
|
|
|
@ -56,10 +56,10 @@ QVariant KnownUsersModel::data(const QModelIndex &index, int role) const
|
||||||
case KnownUserRole::RoleDisplay: return requestedUser;
|
case KnownUserRole::RoleDisplay: return requestedUser;
|
||||||
case KnownUserRole::RoleUserId: return requestedUser.value("id");
|
case KnownUserRole::RoleUserId: return requestedUser.value("id");
|
||||||
case KnownUserRole::RoleTitle: return QString(requestedUser.value("first_name").toString() + " " + requestedUser.value("last_name").toString()).trimmed();
|
case KnownUserRole::RoleTitle: return QString(requestedUser.value("first_name").toString() + " " + requestedUser.value("last_name").toString()).trimmed();
|
||||||
case KnownUserRole::RoleUsername: return requestedUser.value("username");
|
case KnownUserRole::RoleUsername: return requestedUser.value("usernames").toMap().value("editable_username").toString();
|
||||||
case KnownUserRole::RoleUserHandle: return QString("@" + (requestedUser.value("username").toString().isEmpty() ? requestedUser.value("id").toString() : requestedUser.value("username").toString()));
|
case KnownUserRole::RoleUserHandle: return QString("@" + (requestedUser.value("usernames").toMap().value("editable_username").toString().isEmpty() ? requestedUser.value("id").toString() : requestedUser.value("usernames").toMap().value("editable_username").toString()));
|
||||||
case KnownUserRole::RolePhotoSmall: return requestedUser.value("profile_photo").toMap().value("small");
|
case KnownUserRole::RolePhotoSmall: return requestedUser.value("profile_photo").toMap().value("small");
|
||||||
case KnownUserRole::RoleFilter: return QString(requestedUser.value("first_name").toString() + " " + requestedUser.value("last_name").toString() + " " + requestedUser.value("username").toString()).trimmed();
|
case KnownUserRole::RoleFilter: return QString(requestedUser.value("first_name").toString() + " " + requestedUser.value("last_name").toString() + " " + requestedUser.value("usernames").toMap().value("editable_username").toString()).trimmed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
|
@ -341,8 +341,18 @@ void NotificationManager::publishNotification(const NotificationGroup *notificat
|
||||||
|
|
||||||
QString notificationBody;
|
QString notificationBody;
|
||||||
const QVariantMap senderInformation = messageMap.value(SENDER_ID).toMap();
|
const QVariantMap senderInformation = messageMap.value(SENDER_ID).toMap();
|
||||||
if (notificationGroup->totalCount == 1 && !messageMap.isEmpty()) {
|
bool outputMessageCount = notificationGroup->totalCount > 1;
|
||||||
|
bool messageIsEmpty = messageMap.isEmpty();
|
||||||
|
if (outputMessageCount || messageIsEmpty) {
|
||||||
|
// Either we have more than one notification or we have no content to display
|
||||||
|
LOG("Group" << notificationGroup->notificationGroupId << "has" << notificationGroup->totalCount << "notifications");
|
||||||
|
notificationBody = tr("%Ln unread messages", "", notificationGroup->totalCount);
|
||||||
|
}
|
||||||
|
if ((!outputMessageCount || appSettings->notificationAlwaysShowPreview()) && !messageIsEmpty) {
|
||||||
LOG("Group" << notificationGroup->notificationGroupId << "has 1 notification");
|
LOG("Group" << notificationGroup->notificationGroupId << "has 1 notification");
|
||||||
|
if (outputMessageCount) {
|
||||||
|
notificationBody += "; ";
|
||||||
|
}
|
||||||
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
||||||
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
||||||
// Add author
|
// Add author
|
||||||
|
@ -352,15 +362,9 @@ void NotificationManager::publishNotification(const NotificationGroup *notificat
|
||||||
} else {
|
} else {
|
||||||
fullName = FernschreiberUtils::getUserName(tdLibWrapper->getUserInformation(senderInformation.value(USER_ID).toString()));
|
fullName = FernschreiberUtils::getUserName(tdLibWrapper->getUserInformation(senderInformation.value(USER_ID).toString()));
|
||||||
}
|
}
|
||||||
|
notificationBody += fullName.trimmed() + ": ";
|
||||||
notificationBody = notificationBody + fullName.trimmed() + ": ";
|
|
||||||
}
|
}
|
||||||
notificationBody += FernschreiberUtils::getMessageShortText(tdLibWrapper, messageMap.value(CONTENT).toMap(), (chatInformation ? chatInformation->isChannel : false), tdLibWrapper->getUserInformation().value(ID).toLongLong(), senderInformation );
|
notificationBody += FernschreiberUtils::getMessageShortText(tdLibWrapper, messageMap.value(CONTENT).toMap(), (chatInformation ? chatInformation->isChannel : false), tdLibWrapper->getUserInformation().value(ID).toLongLong(), senderInformation );
|
||||||
nemoNotification->setBody(notificationBody);
|
|
||||||
} else {
|
|
||||||
// Either we have more than one notification or we have no content to display
|
|
||||||
LOG("Group" << notificationGroup->notificationGroupId << "has" << notificationGroup->totalCount << "notifications");
|
|
||||||
notificationBody = tr("%Ln unread messages", "", notificationGroup->totalCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString summary(chatInformation ? chatInformation->title : QString());
|
const QString summary(chatInformation ? chatInformation->title : QString());
|
||||||
|
@ -377,7 +381,11 @@ void NotificationManager::publishNotification(const NotificationGroup *notificat
|
||||||
nemoNotification->setHintValue(HINT_VISIBILITY, QString());
|
nemoNotification->setHintValue(HINT_VISIBILITY, QString());
|
||||||
nemoNotification->setUrgency(Notification::Low);
|
nemoNotification->setUrgency(Notification::Low);
|
||||||
} else {
|
} else {
|
||||||
nemoNotification->setPreviewBody(notificationBody);
|
if (!appSettings->notificationSuppressContent()) {
|
||||||
|
nemoNotification->setPreviewBody(notificationBody);
|
||||||
|
} else {
|
||||||
|
nemoNotification->setPreviewBody(tr("%Ln unread messages", "", notificationGroup->totalCount));
|
||||||
|
}
|
||||||
nemoNotification->setPreviewSummary(summary);
|
nemoNotification->setPreviewSummary(summary);
|
||||||
nemoNotification->setHintValue(HINT_SUPPRESS_SOUND, !appSettings->notificationSoundsEnabled());
|
nemoNotification->setHintValue(HINT_SUPPRESS_SOUND, !appSettings->notificationSoundsEnabled());
|
||||||
nemoNotification->setHintValue(HINT_DISPLAY_ON, appSettings->notificationTurnsDisplayOn());
|
nemoNotification->setHintValue(HINT_DISPLAY_ON, appSettings->notificationTurnsDisplayOn());
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace {
|
||||||
const QString UNREAD_COUNT("unread_count");
|
const QString UNREAD_COUNT("unread_count");
|
||||||
const QString UNREAD_MENTION_COUNT("unread_mention_count");
|
const QString UNREAD_MENTION_COUNT("unread_mention_count");
|
||||||
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
|
const QString UNREAD_REACTION_COUNT("unread_reaction_count");
|
||||||
|
const QString AVAILABLE_REACTIONS("available_reactions");
|
||||||
const QString TEXT("text");
|
const QString TEXT("text");
|
||||||
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
||||||
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
||||||
|
@ -60,6 +61,11 @@ namespace {
|
||||||
const QString CONTENT("content");
|
const QString CONTENT("content");
|
||||||
const QString NEW_CONTENT("new_content");
|
const QString NEW_CONTENT("new_content");
|
||||||
const QString SETS("sets");
|
const QString SETS("sets");
|
||||||
|
const QString EMOJIS("emojis");
|
||||||
|
const QString REPLY_TO("reply_to");
|
||||||
|
const QString REPLY_IN_CHAT_ID("reply_in_chat_id");
|
||||||
|
const QString REPLY_TO_MESSAGE_ID("reply_to_message_id");
|
||||||
|
const QString DRAFT_MESSAGE("draft_message");
|
||||||
|
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
const QString _EXTRA("@extra");
|
const QString _EXTRA("@extra");
|
||||||
|
@ -70,8 +76,11 @@ namespace {
|
||||||
const QString TYPE_MESSAGE("message");
|
const QString TYPE_MESSAGE("message");
|
||||||
const QString TYPE_STICKER("sticker");
|
const QString TYPE_STICKER("sticker");
|
||||||
const QString TYPE_MESSAGE_STICKER("messageSticker");
|
const QString TYPE_MESSAGE_STICKER("messageSticker");
|
||||||
|
const QString TYPE_MESSAGE_REPLY_TO_MESSAGE("messageReplyToMessage");
|
||||||
const QString TYPE_MESSAGE_ANIMATED_EMOJI("messageAnimatedEmoji");
|
const QString TYPE_MESSAGE_ANIMATED_EMOJI("messageAnimatedEmoji");
|
||||||
const QString TYPE_ANIMATED_EMOJI("animatedEmoji");
|
const QString TYPE_ANIMATED_EMOJI("animatedEmoji");
|
||||||
|
const QString TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE("inputMessageReplyToMessage");
|
||||||
|
const QString TYPE_DRAFT_MESSAGE("draftMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getChatPositionOrder(const QVariantMap &position)
|
static QString getChatPositionOrder(const QVariantMap &position)
|
||||||
|
@ -115,11 +124,14 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("updateChatPosition", &TDLibReceiver::processUpdateChatPosition);
|
handlers.insert("updateChatPosition", &TDLibReceiver::processUpdateChatPosition);
|
||||||
handlers.insert("updateChatReadInbox", &TDLibReceiver::processUpdateChatReadInbox);
|
handlers.insert("updateChatReadInbox", &TDLibReceiver::processUpdateChatReadInbox);
|
||||||
handlers.insert("updateChatReadOutbox", &TDLibReceiver::processUpdateChatReadOutbox);
|
handlers.insert("updateChatReadOutbox", &TDLibReceiver::processUpdateChatReadOutbox);
|
||||||
|
handlers.insert("updateChatAvailableReactions", &TDLibReceiver::processUpdateChatAvailableReactions);
|
||||||
handlers.insert("updateBasicGroup", &TDLibReceiver::processUpdateBasicGroup);
|
handlers.insert("updateBasicGroup", &TDLibReceiver::processUpdateBasicGroup);
|
||||||
handlers.insert("updateSupergroup", &TDLibReceiver::processUpdateSuperGroup);
|
handlers.insert("updateSupergroup", &TDLibReceiver::processUpdateSuperGroup);
|
||||||
handlers.insert("updateChatOnlineMemberCount", &TDLibReceiver::processChatOnlineMemberCountUpdated);
|
handlers.insert("updateChatOnlineMemberCount", &TDLibReceiver::processChatOnlineMemberCountUpdated);
|
||||||
handlers.insert("messages", &TDLibReceiver::processMessages);
|
handlers.insert("messages", &TDLibReceiver::processMessages);
|
||||||
handlers.insert("sponsoredMessage", &TDLibReceiver::processSponsoredMessage);
|
handlers.insert("foundChatMessages", &TDLibReceiver::processFoundChatMessages);
|
||||||
|
handlers.insert("sponsoredMessage", &TDLibReceiver::processSponsoredMessage); // TdLib <= 1.8.7
|
||||||
|
handlers.insert("sponsoredMessages", &TDLibReceiver::processSponsoredMessages); // TdLib >= 1.8.8
|
||||||
handlers.insert("updateNewMessage", &TDLibReceiver::processUpdateNewMessage);
|
handlers.insert("updateNewMessage", &TDLibReceiver::processUpdateNewMessage);
|
||||||
handlers.insert("message", &TDLibReceiver::processMessage);
|
handlers.insert("message", &TDLibReceiver::processMessage);
|
||||||
handlers.insert("messageLinkInfo", &TDLibReceiver::processMessageLinkInfo);
|
handlers.insert("messageLinkInfo", &TDLibReceiver::processMessageLinkInfo);
|
||||||
|
@ -150,6 +162,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("updateChatPinnedMessage", &TDLibReceiver::processUpdateChatPinnedMessage);
|
handlers.insert("updateChatPinnedMessage", &TDLibReceiver::processUpdateChatPinnedMessage);
|
||||||
handlers.insert("updateMessageIsPinned", &TDLibReceiver::processUpdateMessageIsPinned);
|
handlers.insert("updateMessageIsPinned", &TDLibReceiver::processUpdateMessageIsPinned);
|
||||||
handlers.insert("users", &TDLibReceiver::processUsers);
|
handlers.insert("users", &TDLibReceiver::processUsers);
|
||||||
|
handlers.insert("messageSenders", &TDLibReceiver::processMessageSenders);
|
||||||
handlers.insert("error", &TDLibReceiver::processError);
|
handlers.insert("error", &TDLibReceiver::processError);
|
||||||
handlers.insert("ok", &TDLibReceiver::ok);
|
handlers.insert("ok", &TDLibReceiver::ok);
|
||||||
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
||||||
|
@ -165,8 +178,10 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("updateMessageInteractionInfo", &TDLibReceiver::processUpdateMessageInteractionInfo);
|
handlers.insert("updateMessageInteractionInfo", &TDLibReceiver::processUpdateMessageInteractionInfo);
|
||||||
handlers.insert("sessions", &TDLibReceiver::processSessions);
|
handlers.insert("sessions", &TDLibReceiver::processSessions);
|
||||||
handlers.insert("availableReactions", &TDLibReceiver::processAvailableReactions);
|
handlers.insert("availableReactions", &TDLibReceiver::processAvailableReactions);
|
||||||
|
handlers.insert("updateMessageMentionRead", &TDLibReceiver::processUpdateChatUnreadMentionCount);
|
||||||
handlers.insert("updateChatUnreadMentionCount", &TDLibReceiver::processUpdateChatUnreadMentionCount);
|
handlers.insert("updateChatUnreadMentionCount", &TDLibReceiver::processUpdateChatUnreadMentionCount);
|
||||||
handlers.insert("updateChatUnreadReactionCount", &TDLibReceiver::processUpdateChatUnreadReactionCount);
|
handlers.insert("updateChatUnreadReactionCount", &TDLibReceiver::processUpdateChatUnreadReactionCount);
|
||||||
|
handlers.insert("updateActiveEmojiReactions", &TDLibReceiver::processUpdateActiveEmojiReactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::setActive(bool active)
|
void TDLibReceiver::setActive(bool active)
|
||||||
|
@ -350,6 +365,14 @@ void TDLibReceiver::processUpdateChatReadOutbox(const QVariantMap &receivedInfor
|
||||||
emit chatReadOutboxUpdated(chat_id, last_read_outbox_message_id);
|
emit chatReadOutboxUpdated(chat_id, last_read_outbox_message_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processUpdateChatAvailableReactions(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
const qlonglong chat_id(receivedInformation.value(CHAT_ID).toLongLong());
|
||||||
|
const QVariantMap available_reactions(receivedInformation.value(AVAILABLE_REACTIONS).toMap());
|
||||||
|
LOG("Available reactions updated for" << chat_id << "new information:" << available_reactions);
|
||||||
|
emit chatAvailableReactionsUpdated(chat_id, available_reactions);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processUpdateBasicGroup(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateBasicGroup(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
const QVariantMap basicGroup(receivedInformation.value(BASIC_GROUP).toMap());
|
const QVariantMap basicGroup(receivedInformation.value(BASIC_GROUP).toMap());
|
||||||
|
@ -380,13 +403,33 @@ void TDLibReceiver::processMessages(const QVariantMap &receivedInformation)
|
||||||
emit messagesReceived(cleanupList(receivedInformation.value(MESSAGES).toList()), total_count);
|
emit messagesReceived(cleanupList(receivedInformation.value(MESSAGES).toList()), total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processFoundChatMessages(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
const int total_count = receivedInformation.value(TOTAL_COUNT).toInt();
|
||||||
|
LOG("Received found chat messages, amount: " << total_count);
|
||||||
|
emit messagesReceived(cleanupList(receivedInformation.value(MESSAGES).toList()), total_count);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processSponsoredMessage(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processSponsoredMessage(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
|
// TdLib <= 1.8.7
|
||||||
const qlonglong chatId = receivedInformation.value(_EXTRA).toLongLong(); // See TDLibWrapper::getChatSponsoredMessage
|
const qlonglong chatId = receivedInformation.value(_EXTRA).toLongLong(); // See TDLibWrapper::getChatSponsoredMessage
|
||||||
LOG("Received sponsored message for chat" << chatId);
|
LOG("Received sponsored message for chat" << chatId);
|
||||||
emit sponsoredMessageReceived(chatId, receivedInformation);
|
emit sponsoredMessageReceived(chatId, receivedInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processSponsoredMessages(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
// TdLib >= 1.8.8
|
||||||
|
const qlonglong chatId = receivedInformation.value(_EXTRA).toLongLong(); // See TDLibWrapper::getChatSponsoredMessage
|
||||||
|
const QVariantList messages(receivedInformation.value(MESSAGES).toList());
|
||||||
|
LOG("Received" << messages.count() << "sponsored messages for chat" << chatId);
|
||||||
|
QListIterator<QVariant> it(messages);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
emit sponsoredMessageReceived(chatId, it.next().toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processUpdateNewMessage(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateNewMessage(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
const QVariantMap message = receivedInformation.value(MESSAGE).toMap();
|
const QVariantMap message = receivedInformation.value(MESSAGE).toMap();
|
||||||
|
@ -400,7 +443,7 @@ void TDLibReceiver::processMessage(const QVariantMap &receivedInformation)
|
||||||
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
|
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
|
||||||
const qlonglong messageId = receivedInformation.value(ID).toLongLong();
|
const qlonglong messageId = receivedInformation.value(ID).toLongLong();
|
||||||
LOG("Received message " << chatId << messageId);
|
LOG("Received message " << chatId << messageId);
|
||||||
emit messageInformation(chatId, messageId, receivedInformation);
|
emit messageInformation(chatId, messageId, cleanupMap(receivedInformation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processMessageLinkInfo(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processMessageLinkInfo(const QVariantMap &receivedInformation)
|
||||||
|
@ -425,7 +468,7 @@ void TDLibReceiver::processMessageSendSucceeded(const QVariantMap &receivedInfor
|
||||||
const QVariantMap message = receivedInformation.value(MESSAGE).toMap();
|
const QVariantMap message = receivedInformation.value(MESSAGE).toMap();
|
||||||
const qlonglong messageId = message.value(ID).toLongLong();
|
const qlonglong messageId = message.value(ID).toLongLong();
|
||||||
LOG("Message send succeeded" << messageId << oldMessageId);
|
LOG("Message send succeeded" << messageId << oldMessageId);
|
||||||
emit messageSendSucceeded(messageId, oldMessageId, message);
|
emit messageSendSucceeded(messageId, oldMessageId, cleanupMap(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processUpdateActiveNotifications(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateActiveNotifications(const QVariantMap &receivedInformation)
|
||||||
|
@ -602,6 +645,12 @@ void TDLibReceiver::processUsers(const QVariantMap &receivedInformation)
|
||||||
emit usersReceived(receivedInformation.value(_EXTRA).toString(), receivedInformation.value("user_ids").toList(), receivedInformation.value(TOTAL_COUNT).toInt());
|
emit usersReceived(receivedInformation.value(_EXTRA).toString(), receivedInformation.value("user_ids").toList(), receivedInformation.value(TOTAL_COUNT).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processMessageSenders(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
LOG("Received Message Senders");
|
||||||
|
emit messageSendersReceived(receivedInformation.value(_EXTRA).toString(), receivedInformation.value("senders").toList(), receivedInformation.value(TOTAL_COUNT).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processError(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processError(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
LOG("Received an error");
|
LOG("Received an error");
|
||||||
|
@ -652,7 +701,7 @@ void TDLibReceiver::processUpdateChatIsMarkedAsUnread(const QVariantMap &receive
|
||||||
void TDLibReceiver::processUpdateChatDraftMessage(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateChatDraftMessage(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
LOG("Draft message was updated");
|
LOG("Draft message was updated");
|
||||||
emit chatDraftMessageUpdated(receivedInformation.value(CHAT_ID).toLongLong(), receivedInformation.value("draft_message").toMap(), findChatPositionOrder(receivedInformation.value(POSITIONS).toList()));
|
emit chatDraftMessageUpdated(receivedInformation.value(CHAT_ID).toLongLong(), cleanupMap(receivedInformation.value(DRAFT_MESSAGE).toMap()), findChatPositionOrder(receivedInformation.value(POSITIONS).toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processInlineQueryResults(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processInlineQueryResults(const QVariantMap &receivedInformation)
|
||||||
|
@ -689,8 +738,9 @@ void TDLibReceiver::processUpdateMessageInteractionInfo(const QVariantMap &recei
|
||||||
|
|
||||||
void TDLibReceiver::processSessions(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processSessions(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
|
int inactive_session_ttl_days = receivedInformation.value("inactive_session_ttl_days").toInt();
|
||||||
QVariantList sessions = receivedInformation.value("sessions").toList();
|
QVariantList sessions = receivedInformation.value("sessions").toList();
|
||||||
emit sessionsReceived(sessions);
|
emit sessionsReceived(inactive_session_ttl_days, sessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processAvailableReactions(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processAvailableReactions(const QVariantMap &receivedInformation)
|
||||||
|
@ -704,6 +754,8 @@ void TDLibReceiver::processAvailableReactions(const QVariantMap &receivedInforma
|
||||||
|
|
||||||
void TDLibReceiver::processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
|
// Handles both updateMessageMentionRead and updateChatUnreadMentionCount
|
||||||
|
// They both have chat_id and unread_mention_count which is all we need
|
||||||
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
|
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
|
||||||
const int unreadMentionCount = receivedInformation.value(UNREAD_MENTION_COUNT).toInt();
|
const int unreadMentionCount = receivedInformation.value(UNREAD_MENTION_COUNT).toInt();
|
||||||
LOG("Chat unread mention count updated" << chatId << unreadMentionCount);
|
LOG("Chat unread mention count updated" << chatId << unreadMentionCount);
|
||||||
|
@ -718,6 +770,13 @@ void TDLibReceiver::processUpdateChatUnreadReactionCount(const QVariantMap &rece
|
||||||
emit chatUnreadReactionCountUpdated(chatId, unreadReactionCount);
|
emit chatUnreadReactionCountUpdated(chatId, unreadReactionCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processUpdateActiveEmojiReactions(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
// updateActiveEmojiReactions was introduced between 1.8.5 and 1.8.6
|
||||||
|
// See https://github.com/tdlib/td/commit/d29d367
|
||||||
|
emit activeEmojiReactionsUpdated(receivedInformation.value(EMOJIS).toStringList());
|
||||||
|
}
|
||||||
|
|
||||||
// Recursively removes (some) unused entries from QVariantMaps to reduce
|
// Recursively removes (some) unused entries from QVariantMaps to reduce
|
||||||
// memory usage. QStrings allocated by QVariantMaps are the top consumers
|
// memory usage. QStrings allocated by QVariantMaps are the top consumers
|
||||||
// of memory. The biggest saving is achieved by removing "outline" from
|
// of memory. The biggest saving is achieved by removing "outline" from
|
||||||
|
@ -747,17 +806,65 @@ const QVariantMap TDLibReceiver::cleanupMap(const QVariantMap& map, bool *update
|
||||||
return animated_emoji;
|
return animated_emoji;
|
||||||
}
|
}
|
||||||
} else if (type == TYPE_MESSAGE) {
|
} else if (type == TYPE_MESSAGE) {
|
||||||
bool cleaned = false;
|
QVariantMap message(map);
|
||||||
const QVariantMap content(cleanupMap(map.value(CONTENT).toMap(), &cleaned));
|
bool messageChanged = false;
|
||||||
if (cleaned) {
|
const QVariantMap content(cleanupMap(map.value(CONTENT).toMap(), &messageChanged));
|
||||||
QVariantMap message(map);
|
if (messageChanged) {
|
||||||
message.remove(CONTENT);
|
message.remove(CONTENT);
|
||||||
message.insert(CONTENT, content);
|
message.insert(CONTENT, content);
|
||||||
|
}
|
||||||
|
if (map.contains(REPLY_TO)) {
|
||||||
|
// In TdLib 1.8.15 reply_to_message_id and reply_in_chat_id attributes
|
||||||
|
// had been replaced with reply_to structure, e.g:
|
||||||
|
//
|
||||||
|
// "reply_to": {
|
||||||
|
// "@type": "messageReplyToMessage",
|
||||||
|
// "chat_id": -1001234567890,
|
||||||
|
// "is_quote_manual": false,
|
||||||
|
// "message_id": 234567890,
|
||||||
|
// "origin_send_date": 0
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
QVariantMap reply_to(message.value(REPLY_TO).toMap());
|
||||||
|
if (reply_to.value(_TYPE).toString() == TYPE_MESSAGE_REPLY_TO_MESSAGE) {
|
||||||
|
if (reply_to.contains(MESSAGE_ID) &&
|
||||||
|
!message.contains(REPLY_TO_MESSAGE_ID)) {
|
||||||
|
message.insert(REPLY_TO_MESSAGE_ID, reply_to.value(MESSAGE_ID));
|
||||||
|
}
|
||||||
|
if (reply_to.contains(CHAT_ID) &&
|
||||||
|
!message.contains(REPLY_IN_CHAT_ID)) {
|
||||||
|
message.insert(REPLY_IN_CHAT_ID, reply_to.value(CHAT_ID));
|
||||||
|
}
|
||||||
|
reply_to.remove(_TYPE);
|
||||||
|
reply_to.insert(_TYPE, TYPE_MESSAGE_REPLY_TO_MESSAGE);
|
||||||
|
message.insert(REPLY_TO, reply_to);
|
||||||
|
messageChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messageChanged) {
|
||||||
message.remove(_TYPE);
|
message.remove(_TYPE);
|
||||||
message.insert(_TYPE, TYPE_MESSAGE); // Replace with a shared value
|
message.insert(_TYPE, TYPE_MESSAGE); // Replace with a shared value
|
||||||
if (updated) *updated = true;
|
if (updated) *updated = true;
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
} else if (type == TYPE_DRAFT_MESSAGE) {
|
||||||
|
QVariantMap draftMessage(map);
|
||||||
|
QVariantMap reply_to(draftMessage.value(REPLY_TO).toMap());
|
||||||
|
// In TdLib 1.8.21 reply_to_message_id has been replaced with reply_to
|
||||||
|
if (reply_to.value(_TYPE).toString() == TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE) {
|
||||||
|
if (reply_to.contains(MESSAGE_ID) &&
|
||||||
|
!draftMessage.contains(REPLY_TO_MESSAGE_ID)) {
|
||||||
|
// reply_to_message_id is what QML (still) expects
|
||||||
|
draftMessage.insert(REPLY_TO_MESSAGE_ID, reply_to.value(MESSAGE_ID));
|
||||||
|
}
|
||||||
|
reply_to.remove(_TYPE);
|
||||||
|
reply_to.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE); // Shared value
|
||||||
|
draftMessage.insert(REPLY_TO, reply_to);
|
||||||
|
draftMessage.remove(_TYPE);
|
||||||
|
draftMessage.insert(_TYPE, DRAFT_MESSAGE); // Shared value
|
||||||
|
if (updated) *updated = true;
|
||||||
|
return draftMessage;
|
||||||
|
}
|
||||||
} else if (type == TYPE_MESSAGE_STICKER) {
|
} else if (type == TYPE_MESSAGE_STICKER) {
|
||||||
bool cleaned = false;
|
bool cleaned = false;
|
||||||
const QVariantMap content(cleanupMap(map.value(CONTENT).toMap(), &cleaned));
|
const QVariantMap content(cleanupMap(map.value(CONTENT).toMap(), &cleaned));
|
||||||
|
|
|
@ -52,6 +52,7 @@ signals:
|
||||||
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
||||||
void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
|
void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
|
||||||
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
|
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
|
||||||
|
void chatAvailableReactionsUpdated(const qlonglong &chatId, const QVariantMap &availableReactions);
|
||||||
void basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
void basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
||||||
void superGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
void superGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
||||||
void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
|
void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
|
||||||
|
@ -88,7 +89,8 @@ signals:
|
||||||
void chatTitleUpdated(const QString &chatId, const QString &title);
|
void chatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
||||||
void messageIsPinnedUpdated(qlonglong chatId, qlonglong messageId, bool isPinned);
|
void messageIsPinnedUpdated(qlonglong chatId, qlonglong messageId, bool isPinned);
|
||||||
void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
void usersReceived(const QString &extra, const QVariantList &senders, int totalUsers);
|
||||||
|
void messageSendersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||||
void errorReceived(const int code, const QString &message, const QString &extra);
|
void errorReceived(const int code, const QString &message, const QString &extra);
|
||||||
void secretChat(qlonglong secretChatId, const QVariantMap &secretChat);
|
void secretChat(qlonglong secretChatId, const QVariantMap &secretChat);
|
||||||
void secretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
|
void secretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
|
||||||
|
@ -101,10 +103,11 @@ signals:
|
||||||
void userPrivacySettingRulesUpdated(const QVariantMap &updatedRules);
|
void userPrivacySettingRulesUpdated(const QVariantMap &updatedRules);
|
||||||
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
|
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
|
||||||
void okReceived(const QString &request);
|
void okReceived(const QString &request);
|
||||||
void sessionsReceived(const QVariantList &sessions);
|
void sessionsReceived(int inactive_session_ttl_days, const QVariantList &sessions);
|
||||||
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
|
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
|
||||||
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
||||||
void chatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
|
void chatUnreadReactionCountUpdated(qlonglong chatId, int unreadReactionCount);
|
||||||
|
void activeEmojiReactionsUpdated(const QStringList& emojis);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
||||||
|
@ -134,11 +137,14 @@ private:
|
||||||
void processUpdateChatPosition(const QVariantMap &receivedInformation);
|
void processUpdateChatPosition(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatReadInbox(const QVariantMap &receivedInformation);
|
void processUpdateChatReadInbox(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatReadOutbox(const QVariantMap &receivedInformation);
|
void processUpdateChatReadOutbox(const QVariantMap &receivedInformation);
|
||||||
|
void processUpdateChatAvailableReactions(const QVariantMap &receivedInformation);
|
||||||
void processUpdateBasicGroup(const QVariantMap &receivedInformation);
|
void processUpdateBasicGroup(const QVariantMap &receivedInformation);
|
||||||
void processUpdateSuperGroup(const QVariantMap &receivedInformation);
|
void processUpdateSuperGroup(const QVariantMap &receivedInformation);
|
||||||
void processChatOnlineMemberCountUpdated(const QVariantMap &receivedInformation);
|
void processChatOnlineMemberCountUpdated(const QVariantMap &receivedInformation);
|
||||||
void processMessages(const QVariantMap &receivedInformation);
|
void processMessages(const QVariantMap &receivedInformation);
|
||||||
|
void processFoundChatMessages(const QVariantMap &receivedInformation);
|
||||||
void processSponsoredMessage(const QVariantMap &receivedInformation);
|
void processSponsoredMessage(const QVariantMap &receivedInformation);
|
||||||
|
void processSponsoredMessages(const QVariantMap &receivedInformation);
|
||||||
void processUpdateNewMessage(const QVariantMap &receivedInformation);
|
void processUpdateNewMessage(const QVariantMap &receivedInformation);
|
||||||
void processMessage(const QVariantMap &receivedInformation);
|
void processMessage(const QVariantMap &receivedInformation);
|
||||||
void processMessageLinkInfo(const QVariantMap &receivedInformation);
|
void processMessageLinkInfo(const QVariantMap &receivedInformation);
|
||||||
|
@ -170,6 +176,7 @@ private:
|
||||||
void processUpdateChatPinnedMessage(const QVariantMap &receivedInformation);
|
void processUpdateChatPinnedMessage(const QVariantMap &receivedInformation);
|
||||||
void processUpdateMessageIsPinned(const QVariantMap &receivedInformation);
|
void processUpdateMessageIsPinned(const QVariantMap &receivedInformation);
|
||||||
void processUsers(const QVariantMap &receivedInformation);
|
void processUsers(const QVariantMap &receivedInformation);
|
||||||
|
void processMessageSenders(const QVariantMap &receivedInformation);
|
||||||
void processError(const QVariantMap &receivedInformation);
|
void processError(const QVariantMap &receivedInformation);
|
||||||
void processSecretChat(const QVariantMap &receivedInformation);
|
void processSecretChat(const QVariantMap &receivedInformation);
|
||||||
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
||||||
|
@ -186,6 +193,7 @@ private:
|
||||||
void processAvailableReactions(const QVariantMap &receivedInformation);
|
void processAvailableReactions(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation);
|
void processUpdateChatUnreadMentionCount(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatUnreadReactionCount(const QVariantMap &receivedInformation);
|
void processUpdateChatUnreadReactionCount(const QVariantMap &receivedInformation);
|
||||||
|
void processUpdateActiveEmojiReactions(const QVariantMap &receivedInformation);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TDLIBRECEIVER_H
|
#endif // TDLIBRECEIVER_H
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
#define DEBUG_MODULE TDLibWrapper
|
#define DEBUG_MODULE TDLibWrapper
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
|
||||||
|
#define VERSION_NUMBER(x,y,z) \
|
||||||
|
((((x) & 0x3ff) << 20) | (((y) & 0x3ff) << 10) | ((z) & 0x3ff))
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const QString STATUS("status");
|
const QString STATUS("status");
|
||||||
const QString ID("id");
|
const QString ID("id");
|
||||||
|
@ -45,26 +48,40 @@ namespace {
|
||||||
const QString LAST_NAME("last_name");
|
const QString LAST_NAME("last_name");
|
||||||
const QString FIRST_NAME("first_name");
|
const QString FIRST_NAME("first_name");
|
||||||
const QString USERNAME("username");
|
const QString USERNAME("username");
|
||||||
|
const QString USERNAMES("usernames");
|
||||||
|
const QString EDITABLE_USERNAME("editable_username");
|
||||||
const QString THREAD_ID("thread_id");
|
const QString THREAD_ID("thread_id");
|
||||||
const QString VALUE("value");
|
const QString VALUE("value");
|
||||||
const QString CHAT_LIST_TYPE("chat_list_type");
|
const QString CHAT_LIST_TYPE("chat_list_type");
|
||||||
|
const QString REPLY_TO_MESSAGE_ID("reply_to_message_id");
|
||||||
|
const QString REPLY_TO("reply_to");
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
const QString _EXTRA("@extra");
|
const QString _EXTRA("@extra");
|
||||||
const QString CHAT_LIST_MAIN("chatListMain");
|
const QString CHAT_LIST_MAIN("chatListMain");
|
||||||
|
const QString CHAT_AVAILABLE_REACTIONS("available_reactions");
|
||||||
|
const QString CHAT_AVAILABLE_REACTIONS_ALL("chatAvailableReactionsAll");
|
||||||
|
const QString CHAT_AVAILABLE_REACTIONS_SOME("chatAvailableReactionsSome");
|
||||||
|
const QString REACTIONS("reactions");
|
||||||
|
const QString REACTION_TYPE("reaction_type");
|
||||||
|
const QString REACTION_TYPE_EMOJI("reactionTypeEmoji");
|
||||||
|
const QString EMOJI("emoji");
|
||||||
|
const QString TYPE_MESSAGE_REPLY_TO_MESSAGE("messageReplyToMessage");
|
||||||
|
const QString TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE("inputMessageReplyToMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface, QObject *parent)
|
TDLibWrapper::TDLibWrapper(AppSettings *settings, MceInterface *mce, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, tdLibClient(td_json_client_create())
|
||||||
, manager(new QNetworkAccessManager(this))
|
, manager(new QNetworkAccessManager(this))
|
||||||
, networkConfigurationManager(new QNetworkConfigurationManager(this))
|
, networkConfigurationManager(new QNetworkConfigurationManager(this))
|
||||||
|
, appSettings(settings)
|
||||||
|
, mceInterface(mce)
|
||||||
|
, authorizationState(AuthorizationState::Closed)
|
||||||
|
, versionNumber(0)
|
||||||
, joinChatRequested(false)
|
, joinChatRequested(false)
|
||||||
|
, isLoggingOut(false)
|
||||||
{
|
{
|
||||||
LOG("Initializing TD Lib...");
|
LOG("Initializing TD Lib...");
|
||||||
this->appSettings = appSettings;
|
|
||||||
this->mceInterface = mceInterface;
|
|
||||||
this->tdLibClient = td_json_client_create();
|
|
||||||
this->authorizationState = AuthorizationState::Closed;
|
|
||||||
this->isLoggingOut = false;
|
|
||||||
|
|
||||||
initializeTDLibReceiver();
|
initializeTDLibReceiver();
|
||||||
|
|
||||||
|
@ -120,6 +137,7 @@ void TDLibWrapper::initializeTDLibReceiver() {
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatOrderUpdated(QString, QString)), this, SIGNAL(chatOrderUpdated(QString, QString)));
|
connect(this->tdLibReceiver, SIGNAL(chatOrderUpdated(QString, QString)), this, SIGNAL(chatOrderUpdated(QString, QString)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SIGNAL(chatReadInboxUpdated(QString, QString, int)));
|
connect(this->tdLibReceiver, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SIGNAL(chatReadInboxUpdated(QString, QString, int)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SIGNAL(chatReadOutboxUpdated(QString, QString)));
|
connect(this->tdLibReceiver, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SIGNAL(chatReadOutboxUpdated(QString, QString)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(chatAvailableReactionsUpdated(qlonglong, QVariantMap)), this, SLOT(handleAvailableReactionsUpdated(qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(basicGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleBasicGroupUpdated(qlonglong, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(basicGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleBasicGroupUpdated(qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleSuperGroupUpdated(qlonglong, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleSuperGroupUpdated(qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SIGNAL(chatOnlineMemberCountUpdated(QString, int)));
|
connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SIGNAL(chatOnlineMemberCountUpdated(QString, int)));
|
||||||
|
@ -159,6 +177,7 @@ void TDLibWrapper::initializeTDLibReceiver() {
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(messageIsPinnedUpdated(qlonglong, qlonglong, bool)), this, SLOT(handleMessageIsPinnedUpdated(qlonglong, qlonglong, bool)));
|
connect(this->tdLibReceiver, SIGNAL(messageIsPinnedUpdated(qlonglong, qlonglong, bool)), this, SLOT(handleMessageIsPinnedUpdated(qlonglong, qlonglong, bool)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(messageSendersReceived(QString, QVariantList, int)), this, SIGNAL(messageSendersReceived(QString, QVariantList, int)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString, QString)), this, SLOT(handleErrorReceived(int, QString, QString)));
|
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString, QString)), this, SLOT(handleErrorReceived(int, QString, QString)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
|
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)));
|
||||||
|
@ -170,10 +189,11 @@ void TDLibWrapper::initializeTDLibReceiver() {
|
||||||
connect(this->tdLibReceiver, SIGNAL(userPrivacySettingRulesUpdated(QVariantMap)), this, SLOT(handleUpdatedUserPrivacySettingRules(QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(userPrivacySettingRulesUpdated(QVariantMap)), this, SLOT(handleUpdatedUserPrivacySettingRules(QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(okReceived(QString)), this, SIGNAL(okReceived(QString)));
|
connect(this->tdLibReceiver, SIGNAL(okReceived(QString)), this, SIGNAL(okReceived(QString)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(sessionsReceived(QVariantList)), this, SIGNAL(sessionsReceived(QVariantList)));
|
connect(this->tdLibReceiver, SIGNAL(sessionsReceived(int, QVariantList)), this, SIGNAL(sessionsReceived(int, QVariantList)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(availableReactionsReceived(qlonglong, QStringList)), this, SIGNAL(availableReactionsReceived(qlonglong, QStringList)));
|
connect(this->tdLibReceiver, SIGNAL(availableReactionsReceived(qlonglong, QStringList)), this, SIGNAL(availableReactionsReceived(qlonglong, QStringList)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)));
|
connect(this->tdLibReceiver, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadMentionCountUpdated(qlonglong, int)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)));
|
connect(this->tdLibReceiver, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)), this, SIGNAL(chatUnreadReactionCountUpdated(qlonglong, int)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(activeEmojiReactionsUpdated(QStringList)), this, SLOT(handleActiveEmojiReactionsUpdated(QStringList)));
|
||||||
|
|
||||||
this->tdLibReceiver->start();
|
this->tdLibReceiver->start();
|
||||||
}
|
}
|
||||||
|
@ -192,7 +212,7 @@ void TDLibWrapper::sendRequest(const QVariantMap &requestObject)
|
||||||
|
|
||||||
QString TDLibWrapper::getVersion()
|
QString TDLibWrapper::getVersion()
|
||||||
{
|
{
|
||||||
return this->version;
|
return this->versionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDLibWrapper::AuthorizationState TDLibWrapper::getAuthorizationState()
|
TDLibWrapper::AuthorizationState TDLibWrapper::getAuthorizationState()
|
||||||
|
@ -255,7 +275,7 @@ void TDLibWrapper::logout()
|
||||||
{
|
{
|
||||||
LOG("Logging out");
|
LOG("Logging out");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert("@type", "logOut");
|
requestObject.insert(_TYPE, "logOut");
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
this->isLoggingOut = true;
|
this->isLoggingOut = true;
|
||||||
|
|
||||||
|
@ -389,15 +409,24 @@ static bool compareReplacements(const QVariant &replacement1, const QVariant &re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message, const QString &replyToMessageId)
|
QVariantMap TDLibWrapper::newSendMessageRequest(qlonglong chatId, qlonglong replyToMessageId)
|
||||||
|
{
|
||||||
|
QVariantMap request;
|
||||||
|
request.insert(_TYPE, "sendMessage");
|
||||||
|
request.insert(CHAT_ID, chatId);
|
||||||
|
if (replyToMessageId) {
|
||||||
|
QVariantMap replyTo;
|
||||||
|
replyTo.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE);
|
||||||
|
replyTo.insert(MESSAGE_ID, replyToMessageId);
|
||||||
|
request.insert(REPLY_TO, replyTo);
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::sendTextMessage(qlonglong chatId, const QString &message, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending text message" << chatId << message << replyToMessageId);
|
LOG("Sending text message" << chatId << message << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageText");
|
inputMessageContent.insert(_TYPE, "inputMessageText");
|
||||||
|
|
||||||
|
@ -436,7 +465,7 @@ void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message
|
||||||
QVariantMap entityType;
|
QVariantMap entityType;
|
||||||
entityType.insert(_TYPE, "textEntityTypeMentionName");
|
entityType.insert(_TYPE, "textEntityTypeMentionName");
|
||||||
entityType.insert("user_id", nextReplacement.value("userId").toString());
|
entityType.insert("user_id", nextReplacement.value("userId").toString());
|
||||||
entity.insert("type", entityType);
|
entity.insert(TYPE, entityType);
|
||||||
entities.append(entity);
|
entities.append(entity);
|
||||||
offsetCorrection += replacementLength - replacementPlainText.length();
|
offsetCorrection += replacementLength - replacementPlainText.length();
|
||||||
}
|
}
|
||||||
|
@ -450,17 +479,13 @@ void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId)
|
void TDLibWrapper::sendPhotoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending photo message" << chatId << filePath << message << replyToMessageId);
|
LOG("Sending photo message" << chatId << filePath << message << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessagePhoto");
|
inputMessageContent.insert(_TYPE, "inputMessagePhoto");
|
||||||
|
|
||||||
QVariantMap formattedText;
|
QVariantMap formattedText;
|
||||||
formattedText.insert("text", message);
|
formattedText.insert("text", message);
|
||||||
formattedText.insert(_TYPE, "formattedText");
|
formattedText.insert(_TYPE, "formattedText");
|
||||||
|
@ -474,17 +499,13 @@ void TDLibWrapper::sendPhotoMessage(const QString &chatId, const QString &filePa
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId)
|
void TDLibWrapper::sendVideoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending video message" << chatId << filePath << message << replyToMessageId);
|
LOG("Sending video message" << chatId << filePath << message << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageVideo");
|
inputMessageContent.insert(_TYPE, "inputMessageVideo");
|
||||||
|
|
||||||
QVariantMap formattedText;
|
QVariantMap formattedText;
|
||||||
formattedText.insert("text", message);
|
formattedText.insert("text", message);
|
||||||
formattedText.insert(_TYPE, "formattedText");
|
formattedText.insert(_TYPE, "formattedText");
|
||||||
|
@ -498,17 +519,13 @@ void TDLibWrapper::sendVideoMessage(const QString &chatId, const QString &filePa
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId)
|
void TDLibWrapper::sendDocumentMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending document message" << chatId << filePath << message << replyToMessageId);
|
LOG("Sending document message" << chatId << filePath << message << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageDocument");
|
inputMessageContent.insert(_TYPE, "inputMessageDocument");
|
||||||
|
|
||||||
QVariantMap formattedText;
|
QVariantMap formattedText;
|
||||||
formattedText.insert("text", message);
|
formattedText.insert("text", message);
|
||||||
formattedText.insert(_TYPE, "formattedText");
|
formattedText.insert(_TYPE, "formattedText");
|
||||||
|
@ -522,17 +539,13 @@ void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &fil
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId)
|
void TDLibWrapper::sendVoiceNoteMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending voice note message" << chatId << filePath << message << replyToMessageId);
|
LOG("Sending voice note message" << chatId << filePath << message << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageVoiceNote");
|
inputMessageContent.insert(_TYPE, "inputMessageVoiceNote");
|
||||||
|
|
||||||
QVariantMap formattedText;
|
QVariantMap formattedText;
|
||||||
formattedText.insert("text", message);
|
formattedText.insert("text", message);
|
||||||
formattedText.insert(_TYPE, "formattedText");
|
formattedText.insert(_TYPE, "formattedText");
|
||||||
|
@ -546,24 +559,19 @@ void TDLibWrapper::sendVoiceNoteMessage(const QString &chatId, const QString &fi
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, const QString &replyToMessageId)
|
void TDLibWrapper::sendLocationMessage(qlonglong chatId, double latitude, double longitude, double horizontalAccuracy, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending location message" << chatId << latitude << longitude << horizontalAccuracy << replyToMessageId);
|
LOG("Sending location message" << chatId << latitude << longitude << horizontalAccuracy << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageLocation");
|
inputMessageContent.insert(_TYPE, "inputMessageLocation");
|
||||||
|
|
||||||
QVariantMap location;
|
QVariantMap location;
|
||||||
location.insert("latitude", latitude);
|
location.insert("latitude", latitude);
|
||||||
location.insert("longitude", longitude);
|
location.insert("longitude", longitude);
|
||||||
location.insert("horizontal_accuracy", horizontalAccuracy);
|
location.insert("horizontal_accuracy", horizontalAccuracy);
|
||||||
location.insert(_TYPE, "location");
|
location.insert(_TYPE, "location");
|
||||||
inputMessageContent.insert("location", location);
|
inputMessageContent.insert("location", location);
|
||||||
|
|
||||||
inputMessageContent.insert("live_period", 0);
|
inputMessageContent.insert("live_period", 0);
|
||||||
inputMessageContent.insert("heading", 0);
|
inputMessageContent.insert("heading", 0);
|
||||||
inputMessageContent.insert("proximity_alert_radius", 0);
|
inputMessageContent.insert("proximity_alert_radius", 0);
|
||||||
|
@ -572,21 +580,16 @@ void TDLibWrapper::sendLocationMessage(const QString &chatId, double latitude, d
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId)
|
void TDLibWrapper::sendStickerMessage(qlonglong chatId, const QString &fileId, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending sticker message" << chatId << fileId << replyToMessageId);
|
LOG("Sending sticker message" << chatId << fileId << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageSticker");
|
inputMessageContent.insert(_TYPE, "inputMessageSticker");
|
||||||
|
|
||||||
QVariantMap stickerInputFile;
|
QVariantMap stickerInputFile;
|
||||||
stickerInputFile.insert(_TYPE, "inputFileRemote");
|
stickerInputFile.insert(_TYPE, "inputFileRemote");
|
||||||
stickerInputFile.insert("id", fileId);
|
stickerInputFile.insert(ID, fileId);
|
||||||
|
|
||||||
inputMessageContent.insert("sticker", stickerInputFile);
|
inputMessageContent.insert("sticker", stickerInputFile);
|
||||||
|
|
||||||
|
@ -594,15 +597,10 @@ void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &file
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, const QString &replyToMessageId)
|
void TDLibWrapper::sendPollMessage(qlonglong chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, qlonglong replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending poll message" << chatId << question << replyToMessageId);
|
LOG("Sending poll message" << chatId << question << replyToMessageId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId));
|
||||||
requestObject.insert(_TYPE, "sendMessage");
|
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
|
||||||
if (replyToMessageId != "0") {
|
|
||||||
requestObject.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
}
|
|
||||||
QVariantMap inputMessageContent;
|
QVariantMap inputMessageContent;
|
||||||
inputMessageContent.insert(_TYPE, "inputMessagePoll");
|
inputMessageContent.insert(_TYPE, "inputMessagePoll");
|
||||||
|
|
||||||
|
@ -620,7 +618,7 @@ void TDLibWrapper::sendPollMessage(const QString &chatId, const QString &questio
|
||||||
pollType.insert("allow_multiple_answers", multiple);
|
pollType.insert("allow_multiple_answers", multiple);
|
||||||
}
|
}
|
||||||
|
|
||||||
inputMessageContent.insert("type", pollType);
|
inputMessageContent.insert(TYPE, pollType);
|
||||||
inputMessageContent.insert("question", question);
|
inputMessageContent.insert("question", question);
|
||||||
inputMessageContent.insert("options", options);
|
inputMessageContent.insert("options", options);
|
||||||
inputMessageContent.insert("is_anonymous", anonymous);
|
inputMessageContent.insert("is_anonymous", anonymous);
|
||||||
|
@ -709,7 +707,11 @@ void TDLibWrapper::getChatSponsoredMessage(qlonglong chatId)
|
||||||
{
|
{
|
||||||
LOG("Retrieving sponsored message" << chatId);
|
LOG("Retrieving sponsored message" << chatId);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "getChatSponsoredMessage");
|
// getChatSponsoredMessage has been replaced with getChatSponsoredMessages
|
||||||
|
// between 1.8.7 and 1.8.8
|
||||||
|
// See https://github.com/tdlib/td/commit/ec1310a
|
||||||
|
requestObject.insert(_TYPE, QString((versionNumber > VERSION_NUMBER(1,8,7)) ?
|
||||||
|
"getChatSponsoredMessages" : "getChatSponsoredMessage"));
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
requestObject.insert(_EXTRA, chatId); // see TDLibReceiver::processSponsoredMessage
|
requestObject.insert(_EXTRA, chatId); // see TDLibReceiver::processSponsoredMessage
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
|
@ -1171,9 +1173,18 @@ void TDLibWrapper::setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlo
|
||||||
inputMessageContent.insert(_TYPE, "inputMessageText");
|
inputMessageContent.insert(_TYPE, "inputMessageText");
|
||||||
inputMessageContent.insert("text", formattedText);
|
inputMessageContent.insert("text", formattedText);
|
||||||
draftMessage.insert(_TYPE, "draftMessage");
|
draftMessage.insert(_TYPE, "draftMessage");
|
||||||
draftMessage.insert("reply_to_message_id", replyToMessageId);
|
|
||||||
draftMessage.insert("input_message_text", inputMessageContent);
|
draftMessage.insert("input_message_text", inputMessageContent);
|
||||||
|
|
||||||
|
if (versionNumber > VERSION_NUMBER(1,8,20)) {
|
||||||
|
QVariantMap replyTo;
|
||||||
|
replyTo.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE);
|
||||||
|
replyTo.insert(CHAT_ID, chatId);
|
||||||
|
replyTo.insert(MESSAGE_ID, replyToMessageId);
|
||||||
|
draftMessage.insert(REPLY_TO, replyTo);
|
||||||
|
} else {
|
||||||
|
draftMessage.insert(REPLY_TO_MESSAGE_ID, replyToMessageId);
|
||||||
|
}
|
||||||
|
|
||||||
requestObject.insert("draft_message", draftMessage);
|
requestObject.insert("draft_message", draftMessage);
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
@ -1433,8 +1444,8 @@ void TDLibWrapper::getMessageAvailableReactions(qlonglong chatId, qlonglong mess
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "getMessageAvailableReactions");
|
requestObject.insert(_TYPE, "getMessageAvailableReactions");
|
||||||
requestObject.insert(_EXTRA, QString::number(messageId));
|
requestObject.insert(_EXTRA, QString::number(messageId));
|
||||||
requestObject.insert("chat_id", chatId);
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
requestObject.insert("message_id", messageId);
|
requestObject.insert(MESSAGE_ID, messageId);
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,11 +1468,23 @@ void TDLibWrapper::setMessageReaction(qlonglong chatId, qlonglong messageId, con
|
||||||
{
|
{
|
||||||
LOG("Set message reaction" << chatId << messageId << reaction);
|
LOG("Set message reaction" << chatId << messageId << reaction);
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "setMessageReaction");
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
requestObject.insert("chat_id", chatId);
|
requestObject.insert(MESSAGE_ID, messageId);
|
||||||
requestObject.insert("message_id", messageId);
|
|
||||||
requestObject.insert("reaction", reaction);
|
|
||||||
requestObject.insert("is_big", false);
|
requestObject.insert("is_big", false);
|
||||||
|
if (versionNumber > VERSION_NUMBER(1,8,5)) {
|
||||||
|
// "reaction_type": {
|
||||||
|
// "@type": "reactionTypeEmoji",
|
||||||
|
// "emoji": "..."
|
||||||
|
// }
|
||||||
|
QVariantMap reactionType;
|
||||||
|
reactionType.insert(_TYPE, REACTION_TYPE_EMOJI);
|
||||||
|
reactionType.insert(EMOJI, reaction);
|
||||||
|
requestObject.insert(REACTION_TYPE, reactionType);
|
||||||
|
requestObject.insert(_TYPE, "addMessageReaction");
|
||||||
|
} else {
|
||||||
|
requestObject.insert("reaction", reaction);
|
||||||
|
requestObject.insert(_TYPE, "setMessageReaction");
|
||||||
|
}
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1494,11 +1517,19 @@ void TDLibWrapper::setNetworkType(NetworkType networkType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
requestObject.insert("type", networkTypeObject);
|
requestObject.insert(TYPE, networkTypeObject);
|
||||||
|
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::setInactiveSessionTtl(int days)
|
||||||
|
{
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "setInactiveSessionTtl");
|
||||||
|
requestObject.insert("inactive_session_ttl_days", days);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::searchEmoji(const QString &queryString)
|
void TDLibWrapper::searchEmoji(const QString &queryString)
|
||||||
{
|
{
|
||||||
LOG("Searching emoji" << queryString);
|
LOG("Searching emoji" << queryString);
|
||||||
|
@ -1575,6 +1606,49 @@ QVariantMap TDLibWrapper::getChat(const QString &chatId)
|
||||||
return this->chats.value(chatId).toMap();
|
return this->chats.value(chatId).toMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList TDLibWrapper::getChatReactions(const QString &chatId)
|
||||||
|
{
|
||||||
|
LOG("Obtaining chat reactions for chat" << chatId);
|
||||||
|
const QVariant available_reactions(chats.value(chatId).toMap().value(CHAT_AVAILABLE_REACTIONS));
|
||||||
|
const QVariantMap map(available_reactions.toMap());
|
||||||
|
const QString reactions_type(map.value(_TYPE).toString());
|
||||||
|
if (reactions_type == CHAT_AVAILABLE_REACTIONS_ALL) {
|
||||||
|
LOG("Chat uses all available reactions, currently available number" << activeEmojiReactions.size());
|
||||||
|
return activeEmojiReactions;
|
||||||
|
} else if (reactions_type == CHAT_AVAILABLE_REACTIONS_SOME) {
|
||||||
|
LOG("Chat uses reduced set of reactions");
|
||||||
|
const QVariantList reactions(map.value(REACTIONS).toList());
|
||||||
|
const int n = reactions.count();
|
||||||
|
QStringList emojis;
|
||||||
|
|
||||||
|
// "available_reactions": {
|
||||||
|
// "@type": "chatAvailableReactionsSome",
|
||||||
|
// "reactions": [
|
||||||
|
// {
|
||||||
|
// "@type": "reactionTypeEmoji",
|
||||||
|
// "emoji": "..."
|
||||||
|
// },
|
||||||
|
emojis.reserve(n);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
const QVariantMap reaction(reactions.at(i).toMap());
|
||||||
|
if (reaction.value(_TYPE).toString() == REACTION_TYPE_EMOJI) {
|
||||||
|
const QString emoji(reaction.value(EMOJI).toString());
|
||||||
|
if (!emoji.isEmpty()) {
|
||||||
|
emojis.append(emoji);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("Found emojis for this chat" << emojis.size());
|
||||||
|
return emojis;
|
||||||
|
} else if (reactions_type.isEmpty()) {
|
||||||
|
LOG("No chat reaction type specified, using all reactions");
|
||||||
|
return available_reactions.toStringList();
|
||||||
|
} else {
|
||||||
|
LOG("Unknown chat reaction type" << reactions_type);
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap TDLibWrapper::getSecretChatFromCache(qlonglong secretChatId)
|
QVariantMap TDLibWrapper::getSecretChatFromCache(qlonglong secretChatId)
|
||||||
{
|
{
|
||||||
return this->secretChats.value(secretChatId);
|
return this->secretChats.value(secretChatId);
|
||||||
|
@ -1645,7 +1719,16 @@ DBusAdaptor *TDLibWrapper::getDBusAdaptor()
|
||||||
|
|
||||||
void TDLibWrapper::handleVersionDetected(const QString &version)
|
void TDLibWrapper::handleVersionDetected(const QString &version)
|
||||||
{
|
{
|
||||||
this->version = version;
|
this->versionString = version;
|
||||||
|
const QStringList parts(version.split('.'));
|
||||||
|
uint major, minor, release;
|
||||||
|
bool ok;
|
||||||
|
if (parts.count() >= 3 &&
|
||||||
|
(major = parts.at(0).toInt(&ok), ok) &&
|
||||||
|
(minor = parts.at(1).toInt(&ok), ok) &&
|
||||||
|
(release = parts.at(2).toInt(&ok), ok)) {
|
||||||
|
versionNumber = VERSION_NUMBER(major, minor, release);
|
||||||
|
}
|
||||||
emit versionDetected(version);
|
emit versionDetected(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1758,15 +1841,15 @@ void TDLibWrapper::handleConnectionStateChanged(const QString &connectionState)
|
||||||
|
|
||||||
void TDLibWrapper::handleUserUpdated(const QVariantMap &userInformation)
|
void TDLibWrapper::handleUserUpdated(const QVariantMap &userInformation)
|
||||||
{
|
{
|
||||||
QString updatedUserId = userInformation.value("id").toString();
|
QString updatedUserId = userInformation.value(ID).toString();
|
||||||
if (updatedUserId == this->options.value("my_id").toString()) {
|
if (updatedUserId == this->options.value("my_id").toString()) {
|
||||||
LOG("Own user information updated :)");
|
LOG("Own user information updated :)");
|
||||||
this->userInformation = userInformation;
|
this->userInformation = userInformation;
|
||||||
emit ownUserUpdated(userInformation);
|
emit ownUserUpdated(userInformation);
|
||||||
}
|
}
|
||||||
LOG("User information updated:" << userInformation.value(USERNAME).toString() << userInformation.value(FIRST_NAME).toString() << userInformation.value(LAST_NAME).toString());
|
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->allUsers.insert(updatedUserId, userInformation);
|
||||||
this->allUserNames.insert(userInformation.value(USERNAME).toString(), userInformation);
|
this->allUserNames.insert(userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString(), userInformation);
|
||||||
emit userUpdated(updatedUserId, userInformation);
|
emit userUpdated(updatedUserId, userInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,24 +1857,24 @@ void TDLibWrapper::handleUserStatusUpdated(const QString &userId, const QVariant
|
||||||
{
|
{
|
||||||
if (userId == this->options.value("my_id").toString()) {
|
if (userId == this->options.value("my_id").toString()) {
|
||||||
LOG("Own user status information updated :)");
|
LOG("Own user status information updated :)");
|
||||||
this->userInformation.insert("status", userStatusInformation);
|
this->userInformation.insert(STATUS, userStatusInformation);
|
||||||
}
|
}
|
||||||
LOG("User status information updated:" << userId << userStatusInformation.value(_TYPE).toString());
|
LOG("User status information updated:" << userId << userStatusInformation.value(_TYPE).toString());
|
||||||
QVariantMap updatedUserInformation = this->allUsers.value(userId).toMap();
|
QVariantMap updatedUserInformation = this->allUsers.value(userId).toMap();
|
||||||
updatedUserInformation.insert("status", userStatusInformation);
|
updatedUserInformation.insert(STATUS, userStatusInformation);
|
||||||
this->allUsers.insert(userId, updatedUserInformation);
|
this->allUsers.insert(userId, updatedUserInformation);
|
||||||
this->allUserNames.insert(userInformation.value(USERNAME).toString(), userInformation);
|
this->allUserNames.insert(userInformation.value(USERNAMES).toMap().value(EDITABLE_USERNAME).toString(), userInformation);
|
||||||
emit userUpdated(userId, updatedUserInformation);
|
emit userUpdated(userId, updatedUserInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::handleFileUpdated(const QVariantMap &fileInformation)
|
void TDLibWrapper::handleFileUpdated(const QVariantMap &fileInformation)
|
||||||
{
|
{
|
||||||
emit fileUpdated(fileInformation.value("id").toInt(), fileInformation);
|
emit fileUpdated(fileInformation.value(ID).toInt(), fileInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::handleNewChatDiscovered(const QVariantMap &chatInformation)
|
void TDLibWrapper::handleNewChatDiscovered(const QVariantMap &chatInformation)
|
||||||
{
|
{
|
||||||
QString chatId = chatInformation.value("id").toString();
|
QString chatId = chatInformation.value(ID).toString();
|
||||||
this->chats.insert(chatId, chatInformation);
|
this->chats.insert(chatId, chatInformation);
|
||||||
emit newChatDiscovered(chatId, chatInformation);
|
emit newChatDiscovered(chatId, chatInformation);
|
||||||
}
|
}
|
||||||
|
@ -1831,6 +1914,17 @@ void TDLibWrapper::handleUnreadChatCountUpdated(const QVariantMap &chatCountInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::handleAvailableReactionsUpdated(qlonglong chatId, const QVariantMap &availableReactions)
|
||||||
|
{
|
||||||
|
LOG("Updating available reactions for chat" << chatId << availableReactions);
|
||||||
|
QString chatIdString = QString::number(chatId);
|
||||||
|
QVariantMap chatInformation = this->getChat(chatIdString);
|
||||||
|
chatInformation.insert(CHAT_AVAILABLE_REACTIONS, availableReactions);
|
||||||
|
this->chats.insert(chatIdString, chatInformation);
|
||||||
|
emit chatAvailableReactionsUpdated(chatId, availableReactions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation)
|
void TDLibWrapper::handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation)
|
||||||
{
|
{
|
||||||
emit basicGroupUpdated(updateGroup(groupId, groupInformation, &basicGroups)->groupId);
|
emit basicGroupUpdated(updateGroup(groupId, groupInformation, &basicGroups)->groupId);
|
||||||
|
@ -1856,7 +1950,7 @@ void TDLibWrapper::handleStickerSets(const QVariantList &stickerSets)
|
||||||
QListIterator<QVariant> stickerSetIterator(stickerSets);
|
QListIterator<QVariant> stickerSetIterator(stickerSets);
|
||||||
while (stickerSetIterator.hasNext()) {
|
while (stickerSetIterator.hasNext()) {
|
||||||
QVariantMap stickerSet = stickerSetIterator.next().toMap();
|
QVariantMap stickerSet = stickerSetIterator.next().toMap();
|
||||||
this->getStickerSet(stickerSet.value("id").toString());
|
this->getStickerSet(stickerSet.value(ID).toString());
|
||||||
}
|
}
|
||||||
emit this->stickerSetsReceived(stickerSets);
|
emit this->stickerSetsReceived(stickerSets);
|
||||||
}
|
}
|
||||||
|
@ -1988,6 +2082,13 @@ void TDLibWrapper::handleSponsoredMessage(qlonglong chatId, const QVariantMap &m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::handleActiveEmojiReactionsUpdated(const QStringList& emojis)
|
||||||
|
{
|
||||||
|
if (activeEmojiReactions != emojis) {
|
||||||
|
activeEmojiReactions = emojis;
|
||||||
|
LOG(emojis.count() << "reaction(s) available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
|
void TDLibWrapper::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
|
||||||
{
|
{
|
||||||
|
@ -2077,28 +2178,40 @@ void TDLibWrapper::handleGetPageSourceFinished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap& TDLibWrapper::fillTdlibParameters(QVariantMap& parameters)
|
||||||
|
{
|
||||||
|
parameters.insert("api_id", TDLIB_API_ID);
|
||||||
|
parameters.insert("api_hash", TDLIB_API_HASH);
|
||||||
|
parameters.insert("database_directory", QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tdlib");
|
||||||
|
bool onlineOnlyMode = this->appSettings->onlineOnlyMode();
|
||||||
|
parameters.insert("use_file_database", !onlineOnlyMode);
|
||||||
|
parameters.insert("use_chat_info_database", !onlineOnlyMode);
|
||||||
|
parameters.insert("use_message_database", !onlineOnlyMode);
|
||||||
|
parameters.insert("use_secret_chats", true);
|
||||||
|
parameters.insert("system_language_code", QLocale::system().name());
|
||||||
|
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
|
||||||
|
parameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
|
||||||
|
parameters.insert("system_version", QSysInfo::prettyProductName());
|
||||||
|
parameters.insert("application_version", "0.17");
|
||||||
|
parameters.insert("enable_storage_optimizer", appSettings->storageOptimizer());
|
||||||
|
// parameters.insert("use_test_dc", true);
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::setInitialParameters()
|
void TDLibWrapper::setInitialParameters()
|
||||||
{
|
{
|
||||||
LOG("Sending initial parameters to TD Lib");
|
LOG("Sending initial parameters to TD Lib");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "setTdlibParameters");
|
requestObject.insert(_TYPE, "setTdlibParameters");
|
||||||
QVariantMap initialParameters;
|
// tdlibParameters were inlined between 1.8.5 and 1.8.6
|
||||||
initialParameters.insert("api_id", TDLIB_API_ID);
|
// See https://github.com/tdlib/td/commit/f6a2ecd
|
||||||
initialParameters.insert("api_hash", TDLIB_API_HASH);
|
if (versionNumber > VERSION_NUMBER(1,8,5)) {
|
||||||
initialParameters.insert("database_directory", QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tdlib");
|
fillTdlibParameters(requestObject);
|
||||||
bool onlineOnlyMode = this->appSettings->onlineOnlyMode();
|
} else {
|
||||||
initialParameters.insert("use_file_database", !onlineOnlyMode);
|
QVariantMap initialParameters;
|
||||||
initialParameters.insert("use_chat_info_database", !onlineOnlyMode);
|
fillTdlibParameters(initialParameters);
|
||||||
initialParameters.insert("use_message_database", !onlineOnlyMode);
|
requestObject.insert("parameters", initialParameters);
|
||||||
initialParameters.insert("use_secret_chats", true);
|
}
|
||||||
initialParameters.insert("system_language_code", QLocale::system().name());
|
|
||||||
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
|
|
||||||
initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
|
|
||||||
initialParameters.insert("system_version", QSysInfo::prettyProductName());
|
|
||||||
initialParameters.insert("application_version", "0.17");
|
|
||||||
initialParameters.insert("enable_storage_optimizer", appSettings->storageOptimizer());
|
|
||||||
// initialParameters.insert("use_test_dc", true);
|
|
||||||
requestObject.insert("parameters", initialParameters);
|
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,7 @@ public:
|
||||||
Q_INVOKABLE QVariantMap getSuperGroup(qlonglong groupId) const;
|
Q_INVOKABLE QVariantMap getSuperGroup(qlonglong groupId) const;
|
||||||
Q_INVOKABLE QVariantMap getChat(const QString &chatId);
|
Q_INVOKABLE QVariantMap getChat(const QString &chatId);
|
||||||
Q_INVOKABLE QVariantMap getSecretChatFromCache(qlonglong secretChatId);
|
Q_INVOKABLE QVariantMap getSecretChatFromCache(qlonglong secretChatId);
|
||||||
|
Q_INVOKABLE QStringList getChatReactions(const QString &chatId);
|
||||||
Q_INVOKABLE QString getOptionString(const QString &optionName);
|
Q_INVOKABLE QString getOptionString(const QString &optionName);
|
||||||
Q_INVOKABLE void copyFileToDownloads(const QString &filePath, bool openAfterCopy = false);
|
Q_INVOKABLE void copyFileToDownloads(const QString &filePath, bool openAfterCopy = false);
|
||||||
Q_INVOKABLE void openFileOnDevice(const QString &filePath);
|
Q_INVOKABLE void openFileOnDevice(const QString &filePath);
|
||||||
|
@ -175,14 +176,14 @@ public:
|
||||||
Q_INVOKABLE void viewMessage(qlonglong chatId, qlonglong messageId, bool force);
|
Q_INVOKABLE void viewMessage(qlonglong chatId, qlonglong messageId, bool force);
|
||||||
Q_INVOKABLE void pinMessage(const QString &chatId, const QString &messageId, bool disableNotification = false);
|
Q_INVOKABLE void pinMessage(const QString &chatId, const QString &messageId, bool disableNotification = false);
|
||||||
Q_INVOKABLE void unpinMessage(const QString &chatId, const QString &messageId);
|
Q_INVOKABLE void unpinMessage(const QString &chatId, const QString &messageId);
|
||||||
Q_INVOKABLE void sendTextMessage(const QString &chatId, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendTextMessage(qlonglong chatId, const QString &message, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendPhotoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendVideoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendDocumentMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendVoiceNoteMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendLocationMessage(qlonglong chatId, double latitude, double longitude, double horizontalAccuracy, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendStickerMessage(qlonglong chatId, const QString &fileId, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendPollMessage(qlonglong chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, qlonglong replyToMessageId = 0);
|
||||||
Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, bool sendCopy, bool removeCaption);
|
Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, bool sendCopy, bool removeCaption);
|
||||||
Q_INVOKABLE void getMessage(qlonglong chatId, qlonglong messageId);
|
Q_INVOKABLE void getMessage(qlonglong chatId, qlonglong messageId);
|
||||||
Q_INVOKABLE void getMessageLinkInfo(const QString &url, const QString &extra = "");
|
Q_INVOKABLE void getMessageLinkInfo(const QString &url, const QString &extra = "");
|
||||||
|
@ -250,6 +251,7 @@ public:
|
||||||
Q_INVOKABLE void getPageSource(const QString &address);
|
Q_INVOKABLE void getPageSource(const QString &address);
|
||||||
Q_INVOKABLE void setMessageReaction(qlonglong chatId, qlonglong messageId, const QString &reaction);
|
Q_INVOKABLE void setMessageReaction(qlonglong chatId, qlonglong messageId, const QString &reaction);
|
||||||
Q_INVOKABLE void setNetworkType(NetworkType networkType);
|
Q_INVOKABLE void setNetworkType(NetworkType networkType);
|
||||||
|
Q_INVOKABLE void setInactiveSessionTtl(int days);
|
||||||
|
|
||||||
// Others (candidates for extraction ;))
|
// Others (candidates for extraction ;))
|
||||||
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
||||||
|
@ -277,6 +279,7 @@ signals:
|
||||||
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
||||||
void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
|
void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
|
||||||
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
|
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
|
||||||
|
void chatAvailableReactionsUpdated(const qlonglong &chatId, const QVariantMap &availableReactions);
|
||||||
void userUpdated(const QString &userId, const QVariantMap &userInformation);
|
void userUpdated(const QString &userId, const QVariantMap &userInformation);
|
||||||
void ownUserUpdated(const QVariantMap &userInformation);
|
void ownUserUpdated(const QVariantMap &userInformation);
|
||||||
void basicGroupUpdated(qlonglong groupId);
|
void basicGroupUpdated(qlonglong groupId);
|
||||||
|
@ -320,6 +323,7 @@ signals:
|
||||||
void chatTitleUpdated(const QString &chatId, const QString &title);
|
void chatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
||||||
void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||||
|
void messageSendersReceived(const QString &extra, const QVariantList &senders, int totalUsers);
|
||||||
void errorReceived(int code, const QString &message, const QString &extra);
|
void errorReceived(int code, const QString &message, const QString &extra);
|
||||||
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
||||||
void messageNotFound(qlonglong chatId, qlonglong messageId);
|
void messageNotFound(qlonglong chatId, qlonglong messageId);
|
||||||
|
@ -330,7 +334,7 @@ signals:
|
||||||
void userPrivacySettingUpdated(UserPrivacySetting setting, UserPrivacySettingRule rule);
|
void userPrivacySettingUpdated(UserPrivacySetting setting, UserPrivacySettingRule rule);
|
||||||
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
|
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
|
||||||
void okReceived(const QString &request);
|
void okReceived(const QString &request);
|
||||||
void sessionsReceived(const QVariantList &sessions);
|
void sessionsReceived(int inactive_session_ttl_days, const QVariantList &sessions);
|
||||||
void openFileExternally(const QString &filePath);
|
void openFileExternally(const QString &filePath);
|
||||||
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
|
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
|
||||||
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
void chatUnreadMentionCountUpdated(qlonglong chatId, int unreadMentionCount);
|
||||||
|
@ -349,6 +353,7 @@ public slots:
|
||||||
void handleChatReceived(const QVariantMap &chatInformation);
|
void handleChatReceived(const QVariantMap &chatInformation);
|
||||||
void handleUnreadMessageCountUpdated(const QVariantMap &messageCountInformation);
|
void handleUnreadMessageCountUpdated(const QVariantMap &messageCountInformation);
|
||||||
void handleUnreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
void handleUnreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
||||||
|
void handleAvailableReactionsUpdated(qlonglong chatId, const QVariantMap &availableReactions);
|
||||||
void handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
void handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
||||||
void handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
void handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
||||||
void handleStickerSets(const QVariantList &stickerSets);
|
void handleStickerSets(const QVariantList &stickerSets);
|
||||||
|
@ -364,7 +369,7 @@ public slots:
|
||||||
void handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules);
|
void handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules);
|
||||||
void handleSponsoredMessage(qlonglong chatId, const QVariantMap &message);
|
void handleSponsoredMessage(qlonglong chatId, const QVariantMap &message);
|
||||||
void handleNetworkConfigurationChanged(const QNetworkConfiguration &config);
|
void handleNetworkConfigurationChanged(const QNetworkConfiguration &config);
|
||||||
|
void handleActiveEmojiReactionsUpdated(const QStringList& emojis);
|
||||||
void handleGetPageSourceFinished();
|
void handleGetPageSourceFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -372,7 +377,9 @@ private:
|
||||||
void setInitialParameters();
|
void setInitialParameters();
|
||||||
void setEncryptionKey();
|
void setEncryptionKey();
|
||||||
void setLogVerbosityLevel();
|
void setLogVerbosityLevel();
|
||||||
|
QVariantMap &fillTdlibParameters(QVariantMap ¶meters);
|
||||||
const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash<qlonglong,Group*> *groups);
|
const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash<qlonglong,Group*> *groups);
|
||||||
|
QVariantMap newSendMessageRequest(qlonglong chatId, qlonglong replyToMessageId);
|
||||||
void initializeTDLibReceiver();
|
void initializeTDLibReceiver();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -383,7 +390,7 @@ private:
|
||||||
MceInterface *mceInterface;
|
MceInterface *mceInterface;
|
||||||
TDLibReceiver *tdLibReceiver;
|
TDLibReceiver *tdLibReceiver;
|
||||||
DBusInterface *dbusInterface;
|
DBusInterface *dbusInterface;
|
||||||
QString version;
|
QString versionString;
|
||||||
TDLibWrapper::AuthorizationState authorizationState;
|
TDLibWrapper::AuthorizationState authorizationState;
|
||||||
QVariantMap authorizationStateData;
|
QVariantMap authorizationStateData;
|
||||||
TDLibWrapper::ConnectionState connectionState;
|
TDLibWrapper::ConnectionState connectionState;
|
||||||
|
@ -399,7 +406,9 @@ private:
|
||||||
QHash<qlonglong,Group*> basicGroups;
|
QHash<qlonglong,Group*> basicGroups;
|
||||||
QHash<qlonglong,Group*> superGroups;
|
QHash<qlonglong,Group*> superGroups;
|
||||||
EmojiSearchWorker emojiSearchWorker;
|
EmojiSearchWorker emojiSearchWorker;
|
||||||
|
QStringList activeEmojiReactions;
|
||||||
|
|
||||||
|
int versionNumber;
|
||||||
QString activeChatSearchName;
|
QString activeChatSearchName;
|
||||||
bool joinChatRequested;
|
bool joinChatRequested;
|
||||||
bool isLoggingOut;
|
bool isLoggingOut;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
@ -23,7 +23,7 @@ namespace td {
|
||||||
* Requests can be sent using the method ClientManager::send from any thread.
|
* Requests can be sent using the method ClientManager::send from any thread.
|
||||||
* New updates and responses to requests can be received using the method ClientManager::receive from any thread after
|
* New updates and responses to requests can be received using the method ClientManager::receive from any thread after
|
||||||
* the first request has been sent to the client instance. ClientManager::receive must not be called simultaneously from
|
* the first request has been sent to the client instance. ClientManager::receive must not be called simultaneously from
|
||||||
* two different threads. Also note that all updates and responses to requests should be applied in the same order as
|
* two different threads. Also, note that all updates and responses to requests should be applied in the same order as
|
||||||
* they were received, to ensure consistency.
|
* they were received, to ensure consistency.
|
||||||
* Some TDLib requests can be executed synchronously from any thread using the method ClientManager::execute.
|
* Some TDLib requests can be executed synchronously from any thread using the method ClientManager::execute.
|
||||||
*
|
*
|
||||||
|
@ -96,7 +96,7 @@ class ClientManager final {
|
||||||
ClientId client_id;
|
ClientId client_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request identifier, to which the response corresponds, or 0 for incoming updates from TDLib.
|
* Request identifier to which the response corresponds, or 0 for incoming updates from TDLib.
|
||||||
*/
|
*/
|
||||||
RequestId request_id;
|
RequestId request_id;
|
||||||
|
|
||||||
|
@ -126,10 +126,10 @@ class ClientManager final {
|
||||||
/**
|
/**
|
||||||
* A type of callback function that will be called when a message is added to the internal TDLib log.
|
* A type of callback function that will be called when a message is added to the internal TDLib log.
|
||||||
*
|
*
|
||||||
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
|
* \param verbosity_level Log verbosity level with which the message was added from -1 up to 1024.
|
||||||
* If 0, then TDLib will crash as soon as the callback returns.
|
* If 0, then TDLib will crash as soon as the callback returns.
|
||||||
* None of the TDLib methods can be called from the callback.
|
* None of the TDLib methods can be called from the callback.
|
||||||
* \param message Null-terminated string with the message added to the log.
|
* \param message Null-terminated UTF-8-encoded string with the message added to the log.
|
||||||
*/
|
*/
|
||||||
using LogMessageCallbackPtr = void (*)(int verbosity_level, const char *message);
|
using LogMessageCallbackPtr = void (*)(int verbosity_level, const char *message);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ class ClientManager final {
|
||||||
* The TDLib instance is created for the lifetime of the Client object.
|
* The TDLib instance is created for the lifetime of the Client object.
|
||||||
* Requests to TDLib can be sent using the Client::send method from any thread.
|
* Requests to TDLib can be sent using the Client::send method from any thread.
|
||||||
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
||||||
* this function must not be called simultaneously from two different threads. Also note that all updates and
|
* this function must not be called simultaneously from two different threads. Also, note that all updates and
|
||||||
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
||||||
* Given this information, it's advisable to call this function from a dedicated thread.
|
* Given this information, it's advisable to call this function from a dedicated thread.
|
||||||
* Some service TDLib requests can be executed synchronously from any thread using the Client::execute method.
|
* Some service TDLib requests can be executed synchronously from any thread using the Client::execute method.
|
||||||
|
@ -199,7 +199,7 @@ class ClientManager final {
|
||||||
* if (response.id == 0) {
|
* if (response.id == 0) {
|
||||||
* // process response.object as an incoming update of type td_api::Update
|
* // process response.object as an incoming update of type td_api::Update
|
||||||
* } else {
|
* } else {
|
||||||
* // process response.object as an answer to a sent request with id response.id
|
* // process response.object as an answer to a sent request with identifier response.id
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* \endcode
|
* \endcode
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
* Requests can be sent using td_send and the received client identifier.
|
* Requests can be sent using td_send and the received client identifier.
|
||||||
* New updates and responses to requests can be received through td_receive from any thread after the first request
|
* New updates and responses to requests can be received through td_receive from any thread after the first request
|
||||||
* has been sent to the client instance. This function must not be called simultaneously from two different threads.
|
* has been sent to the client instance. This function must not be called simultaneously from two different threads.
|
||||||
* Also note that all updates and responses to requests must be applied in the order they were received for consistency.
|
* Also, note that all updates and responses to requests must be applied in the order they were received for consistency.
|
||||||
* Some TDLib requests can be executed synchronously from any thread using td_execute.
|
* Some TDLib requests can be executed synchronously from any thread using td_execute.
|
||||||
* TDLib client instances are destroyed automatically after they are closed.
|
* TDLib client instances are destroyed automatically after they are closed.
|
||||||
* All TDLib client instances must be closed before application termination to ensure data consistency.
|
* All TDLib client instances must be closed before application termination to ensure data consistency.
|
||||||
|
@ -88,10 +88,10 @@ TDJSON_EXPORT const char *td_execute(const char *request);
|
||||||
/**
|
/**
|
||||||
* A type of callback function that will be called when a message is added to the internal TDLib log.
|
* A type of callback function that will be called when a message is added to the internal TDLib log.
|
||||||
*
|
*
|
||||||
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
|
* \param verbosity_level Log verbosity level with which the message was added from -1 up to 1024.
|
||||||
* If 0, then TDLib will crash as soon as the callback returns.
|
* If 0, then TDLib will crash as soon as the callback returns.
|
||||||
* None of the TDLib methods can be called from the callback.
|
* None of the TDLib methods can be called from the callback.
|
||||||
* \param message Null-terminated string with the logged message.
|
* \param message Null-terminated UTF-8-encoded string with the message added to the log.
|
||||||
*/
|
*/
|
||||||
typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char *message);
|
typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char *message);
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ TDJSON_EXPORT void td_set_log_message_callback(int max_verbosity_level, td_log_m
|
||||||
* A TDLib client instance can be created through td_json_client_create.
|
* A TDLib client instance can be created through td_json_client_create.
|
||||||
* Requests then can be sent using td_json_client_send from any thread.
|
* Requests then can be sent using td_json_client_send from any thread.
|
||||||
* New updates and request responses can be received through td_json_client_receive from any thread. This function
|
* New updates and request responses can be received through td_json_client_receive from any thread. This function
|
||||||
* must not be called simultaneously from two different threads. Also note that all updates and request responses
|
* must not be called simultaneously from two different threads. Also, note that all updates and request responses
|
||||||
* must be applied in the order they were received to ensure consistency.
|
* must be applied in the order they were received to ensure consistency.
|
||||||
* Given this information, it's advisable to call this function from a dedicated thread.
|
* Given this information, it's advisable to call this function from a dedicated thread.
|
||||||
* Some service TDLib requests can be executed synchronously from any thread by using td_json_client_execute.
|
* Some service TDLib requests can be executed synchronously from any thread by using td_json_client_execute.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
@ -97,8 +97,8 @@ class unique_ptr {
|
||||||
using element_type = T;
|
using element_type = T;
|
||||||
|
|
||||||
unique_ptr() noexcept = default;
|
unique_ptr() noexcept = default;
|
||||||
unique_ptr(const unique_ptr &other) = delete;
|
unique_ptr(const unique_ptr &) = delete;
|
||||||
unique_ptr &operator=(const unique_ptr &other) = delete;
|
unique_ptr &operator=(const unique_ptr &) = delete;
|
||||||
unique_ptr(unique_ptr &&other) noexcept : ptr_(other.release()) {
|
unique_ptr(unique_ptr &&other) noexcept : ptr_(other.release()) {
|
||||||
}
|
}
|
||||||
unique_ptr &operator=(unique_ptr &&other) noexcept {
|
unique_ptr &operator=(unique_ptr &&other) noexcept {
|
||||||
|
@ -187,11 +187,11 @@ using tl_object_ptr = tl::unique_ptr<Type>;
|
||||||
* A function to create a dynamically allocated TL-object. Can be treated as an analogue of std::make_unique.
|
* A function to create a dynamically allocated TL-object. Can be treated as an analogue of std::make_unique.
|
||||||
* Usage example:
|
* Usage example:
|
||||||
* \code
|
* \code
|
||||||
* auto get_authorization_state_request = td::make_tl_object<td::td_api::getAuthorizationState>();
|
* auto get_me_request = td::make_tl_object<td::td_api::getMe>();
|
||||||
* auto message_text = td::make_tl_object<td::td_api::formattedText>("Hello, world!!!",
|
* auto message_text = td::make_tl_object<td::td_api::formattedText>("Hello, world!!!",
|
||||||
* td::td_api::array<td::tl_object_ptr<td::td_api::textEntity>>());
|
* td::td_api::array<td::tl_object_ptr<td::td_api::textEntity>>());
|
||||||
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, 0, nullptr, nullptr,
|
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, nullptr, nullptr, nullptr,
|
||||||
* td::make_tl_object<td::td_api::inputMessageText>(std::move(message_text), false, true));
|
* td::make_tl_object<td::td_api::inputMessageText>(std::move(message_text), nullptr, true));
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* \tparam Type Type of the TL-object to construct.
|
* \tparam Type Type of the TL-object to construct.
|
||||||
|
|
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Gelöschtes Konto</translation>
|
<translation>Gelöschtes Konto</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation>Drücke zweimal auf eine Nachricht, um eine Reaktion auszuwählen</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>Sie haben noch keine Chats.</translation>
|
<translation>Sie haben noch keine Chats.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Konnte Ihre Kontakte nicht mit Telegram synchronisieren.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1582,6 +1579,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Wenn Töne eingeschaltet sind, wird Fernschreiber den aktuellen Sailfish OS-Hinweiston für Chats verwenden, der in den Systemeinstellungen konfiguriert werden kann.</translation>
|
<translation>Wenn Töne eingeschaltet sind, wird Fernschreiber den aktuellen Sailfish OS-Hinweiston für Chats verwenden, der in den Systemeinstellungen konfiguriert werden kann.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation>Immer bei Hinweisen die Nachricht ausgeben</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation>Zusätzlich zur Anzahl der ungelesenen Nachrichten wird immer die neuste Nachricht an Hinweise angefügt.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation>Ungelesene Nachrichten hervorheben</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation>Unterhaltungen mit ungelesenen Nachrichten hervorheben</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation>Inhalte in Hinweisen verbergen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation>Zu zitierter Nachricht springen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation>Beim Tippen auf eine zitierte Nachricht zu dieser springen anstatt es in einem Overlay anzuzeigen.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1679,10 +1704,6 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Diese App</translation>
|
<translation>Diese App</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP-Adresse: %1, Herkunft: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Aktiv seit: %1, zuletzt online: %2</translation>
|
<translation>Aktiv seit: %1, zuletzt online: %2</translation>
|
||||||
|
@ -1695,6 +1716,41 @@
|
||||||
<source>Sessions</source>
|
<source>Sessions</source>
|
||||||
<translation>Sitzungen</translation>
|
<translation>Sitzungen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%1 Tag</numerusform>
|
||||||
|
<numerusform>%1 Tage</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation>1 Woche</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation>1 Monat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation>3 Monate</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation>6 Monate</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation>1 Jahr</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation>Timeout von Sitzungen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation>Inaktive Sitzungen werden nach dieser Zeitdauer abgeschaltet</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Deleted User</translation>
|
<translation>Deleted User</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>You don't have any chats yet.</translation>
|
<translation>You don't have any chats yet.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished">Could not synchronize your contacts with Telegram.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1584,6 +1581,34 @@ messages</numerusform>
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</translation>
|
<translation>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation>Always append message preview to notifications</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1689,14 +1714,45 @@ messages</numerusform>
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>This app</translation>
|
<translation>This app</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP address: %1, origin: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Active since: %1, last online: %2</translation>
|
<translation>Active since: %1, last online: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%1 day</numerusform>
|
||||||
|
<numerusform>%1 days</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>Sinulla ei ole vielä keskusteluja.</translation>
|
<translation>Sinulla ei ole vielä keskusteluja.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished">Yhteystietojasi ei voitu synkronoida Telegramin kanssa.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1583,6 +1580,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Kun äänet ovat käytössä, Fernschreiber käyttää Sailfish OS:n ilmoitusääniä keskusteluille, jotia voit muuttaa järjestelmäasetuksista.</translation>
|
<translation>Kun äänet ovat käytössä, Fernschreiber käyttää Sailfish OS:n ilmoitusääniä keskusteluille, jotia voit muuttaa järjestelmäasetuksista.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1688,14 +1713,45 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Tämä sovellus</translation>
|
<translation>Tämä sovellus</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP-osoite: %1, sijainti: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Aktiivinen %1 alkaen, viimeksi paikalla: %2</translation>
|
<translation>Aktiivinen %1 alkaen, viimeksi paikalla: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="en">
|
<TS version="2.1" language="fr">
|
||||||
<context>
|
<context>
|
||||||
<name>AboutPage</name>
|
<name>AboutPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Supprimer l'utilisateur</translation>
|
<translation>Supprimer l'utilisateur</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation>Toucher deux fois sur un message pour réagir</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>Vous n'avez aucune conversation.</translation>
|
<translation>Vous n'avez aucune conversation.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Impossible de synchroniser vos contacts avec Telegram.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1166,7 +1163,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>No contacts found.</source>
|
<source>No contacts found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Aucun contact trouvé</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1582,6 +1579,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Lorsque le son est activé, Fernschreiber utilisera le réglage de Sailfish OS. Celui-ci est paramétrable depuis les paramètres du système.</translation>
|
<translation>Lorsque le son est activé, Fernschreiber utilisera le réglage de Sailfish OS. Celui-ci est paramétrable depuis les paramètres du système.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation>Toujours visualiser le message dans les notifications</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation>En plus d'afficher le nombre de messages non-lus, le dernier message sera également ajouté aux notifications.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation>Mettre en valeur les messages non-lus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation>Mettre en valeur les conversations avec des messages non-lus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation>Masquer le contenu dans les notifications</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1687,14 +1712,45 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Cette app</translation>
|
<translation>Cette app</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>Adresse IP : %1, origine : %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Actif depuis : %1, en ligne : %2</translation>
|
<translation>Actif depuis : %1, en ligne : %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%1 jour(s)</numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation>1 semaine</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation>1 mois</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation>3 mois</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation>6 mois</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation>1 année</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation>Délai d'inactivité de session</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation>Sessions inactives seront terminées après ce délai</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -473,6 +473,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -485,13 +489,6 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1555,6 +1552,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1661,11 +1686,41 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>IP address: %1, origin: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>Nessuna chat presente</translation>
|
<translation>Nessuna chat presente</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished">Sincronizzazione contatti con Telegram non riuscita</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1582,6 +1579,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Quando i suoni di notifica sono attivi, Fernschreiber utilizza l'attuale suono di notifica per i messaggi scelto per Sailfish OS, il quale può essere modificato dalle impostazioni di sistema.</translation>
|
<translation>Quando i suoni di notifica sono attivi, Fernschreiber utilizza l'attuale suono di notifica per i messaggi scelto per Sailfish OS, il quale può essere modificato dalle impostazioni di sistema.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1688,11 +1713,42 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>IP address: %1, origin: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
|
@ -493,6 +493,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Usunięty użytkownik</translation>
|
<translation>Usunięty użytkownik</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -505,13 +509,6 @@
|
||||||
<translation>Nie masz jeszcze żadnych czatów.</translation>
|
<translation>Nie masz jeszcze żadnych czatów.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Nie można zsynchonizaować kontaktów z Telegramem.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1609,6 +1606,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Gdy dźwięki są włączone, Fernschreiber użyje bieżącego dźwięku powiadomienia Sailfish OS do czatów, które można skonfigurować w ustawieniach systemu.</translation>
|
<translation>Gdy dźwięki są włączone, Fernschreiber użyje bieżącego dźwięku powiadomienia Sailfish OS do czatów, które można skonfigurować w ustawieniach systemu.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1714,14 +1739,46 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Ta aplikacja</translation>
|
<translation>Ta aplikacja</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>Adres IP: %1, oryginalny: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Aktywny od: %1, ostatnio aktywny: %2</translation>
|
<translation>Aktywny od: %1, ostatnio aktywny: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -348,11 +348,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Leave Chat</source>
|
<source>Leave Chat</source>
|
||||||
<translation>Выйти из Чата</translation>
|
<translation>Выйти из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Join Chat</source>
|
<source>Join Chat</source>
|
||||||
<translation>Зайти в Чат</translation>
|
<translation>Зайти в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
|
@ -427,7 +427,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation>Найти в Чате</translation>
|
<translation>Поиск в чате</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
|
@ -493,6 +493,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Удалённый пользователь</translation>
|
<translation>Удалённый пользователь</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -505,13 +509,6 @@
|
||||||
<translation>Тут пока ничего нет</translation>
|
<translation>Тут пока ничего нет</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Невозможно синхронизировать ваши контакты с Телеграм.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1159,7 +1156,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Secret Chat</source>
|
<source>Secret Chat</source>
|
||||||
<translation>Секретный Чат</translation>
|
<translation>Секретный чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>End-to-end-encrypted, accessible on this device only</source>
|
<source>End-to-end-encrypted, accessible on this device only</source>
|
||||||
|
@ -1241,7 +1238,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Новый Чат</translation>
|
<translation>Новый чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
|
@ -1249,7 +1246,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation>Найти Чаты</translation>
|
<translation>Поиск чатов</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
|
@ -1460,7 +1457,7 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation>Чаты не найдены</translation>
|
<translation>Ничего не найдено</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
|
@ -1468,7 +1465,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation>Приватный Чат</translation>
|
<translation>Приватный чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
|
@ -1496,7 +1493,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation>Найти Чаты</translation>
|
<translation>Поиск чатов</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
|
@ -1612,6 +1609,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Если звуки разрешены, Fernschreiber использует звук, выбранный для чатов в настройках Sailfish OS.</translation>
|
<translation>Если звуки разрешены, Fernschreiber использует звук, выбранный для чатов в настройках Sailfish OS.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation>Всегда показывать последнее сообщение на экране событий</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation>Включать в текст на экране событий не только количество непрочитанных сообщений, но и содержимое последнего сообщения.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation>Выделять непрочитанные сообщения</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation>Помечать чаты и каналы с непрочитанными сообщениями другим шрифтом и цветом.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation>Не показывать содержимое сообщений в уведомлениях</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation>Переходить к цитируемому сообщению</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation>По нажатию на цитируемое сообщение, переходить к нему в чате вместо отображения во всплывающем окне.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1717,14 +1742,46 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Это приложение</translation>
|
<translation>Это приложение</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP-адрес: %1, регион: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Активен с: %1, был онлайн: %2</translation>
|
<translation>Активен с: %1, был онлайн: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%1 день</numerusform>
|
||||||
|
<numerusform>%1 дня</numerusform>
|
||||||
|
<numerusform>%1 дней</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation>1 неделя</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation>1 месяц</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation>3 месяца</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation>6 месяцев</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation>1 год</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation>Таймаут неактивности</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation>Неактивные сеансы будут автоматически завершены через указанное время.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -493,6 +493,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Odstránený používateľ</translation>
|
<translation>Odstránený používateľ</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -505,13 +509,6 @@
|
||||||
<translation>Nemáte žiadne čety.</translation>
|
<translation>Nemáte žiadne čety.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Nemožno synchonizovať kontakty s Telegramom.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1609,6 +1606,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>Keď sú povolené zvukové upozornenia, Fernschreiber použije aktuálne zvukové upozornenia Sailfish OS pre čety, ktoré môžu byť upravené v nastaveniach systému.</translation>
|
<translation>Keď sú povolené zvukové upozornenia, Fernschreiber použije aktuálne zvukové upozornenia Sailfish OS pre čety, ktoré môžu byť upravené v nastaveniach systému.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1714,14 +1739,46 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Táto aplikácia</translation>
|
<translation>Táto aplikácia</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP adresa: %1, pôvod: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Aktívna od: %1, naposledy pripojená: %2</translation>
|
<translation>Aktívna od: %1, naposledy pripojená: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation>Tog bort användare</translation>
|
<translation>Tog bort användare</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>Du har inga chattar än.</translation>
|
<translation>Du har inga chattar än.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation>Kunde inte synkronisera dina kontakter med Telegram.</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1582,6 +1579,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>När ljud är aktiverat, använder Fernschreiber aktuell Sailfish-signal för chatt-avisering, vilken kan ställas in i systemets ljudinställningar.</translation>
|
<translation>När ljud är aktiverat, använder Fernschreiber aktuell Sailfish-signal för chatt-avisering, vilken kan ställas in i systemets ljudinställningar.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1687,14 +1712,45 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>Denna app</translation>
|
<translation>Denna app</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP-adress: %1, ursprung: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>Aktiv sedan: %1, senast online: %2</translation>
|
<translation>Aktiv sedan: %1, senast online: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -473,6 +473,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -485,13 +489,6 @@
|
||||||
<translation>你还没有任何对话。</translation>
|
<translation>你还没有任何对话。</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished">无法同步你的云端 Telegram 联系人。</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1556,6 +1553,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation>如果开启声音,Fernschreiber 会采用当前旗鱼系统通知声音作为对话通知声音,你可以在系统设置进行配置。</translation>
|
<translation>如果开启声音,Fernschreiber 会采用当前旗鱼系统通知声音作为对话通知声音,你可以在系统设置进行配置。</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1661,14 +1686,44 @@
|
||||||
<source>This app</source>
|
<source>This app</source>
|
||||||
<translation>此应用</translation>
|
<translation>此应用</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>IP address: %1, origin: %2</source>
|
|
||||||
<translation>IP 地址: %1, 地点: %2</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
<translation>活跃时间: %1, 上次在线: %2</translation>
|
<translation>活跃时间: %1, 上次在线: %2</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsStorage</name>
|
<name>SettingsStorage</name>
|
||||||
|
|
|
@ -483,6 +483,10 @@
|
||||||
<source>Deleted User</source>
|
<source>Deleted User</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Double-tap on a message to choose a reaction</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -495,13 +499,6 @@
|
||||||
<translation>You don't have any chats yet.</translation>
|
<translation>You don't have any chats yet.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ContactSync</name>
|
|
||||||
<message>
|
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1582,6 +1579,34 @@
|
||||||
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
<source>When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Always append message preview to notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>In addition to showing the number of unread messages, the latest message will also be appended to notifications.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Highlight Conversations with unread messages</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide content in notifications</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Go to quoted message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When tapping a quoted message, open it in chat instead of showing it in an overlay.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
|
@ -1688,11 +1713,42 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>IP address: %1, origin: %2</source>
|
<source>Active since: %1, last online: %2</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%1 day(s)</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 week</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Active since: %1, last online: %2</source>
|
<source>1 month</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>3 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>6 months</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>1 year</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Session Timeout</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inactive sessions will be terminated after this timeframe</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
Loading…
Reference in a new issue