Merge branch 'master' into logout
This commit is contained in:
commit
063df54e94
52 changed files with 2975 additions and 135 deletions
|
@ -45,12 +45,15 @@ DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/components/BackgroundImage.qml \
|
qml/components/BackgroundImage.qml \
|
||||||
qml/components/ChatListViewItem.qml \
|
qml/components/ChatListViewItem.qml \
|
||||||
qml/components/DocumentPreview.qml \
|
qml/components/DocumentPreview.qml \
|
||||||
|
qml/components/GamePreview.qml \
|
||||||
qml/components/ImagePreview.qml \
|
qml/components/ImagePreview.qml \
|
||||||
qml/components/InReplyToRow.qml \
|
qml/components/InReplyToRow.qml \
|
||||||
|
qml/components/InlineQuery.qml \
|
||||||
qml/components/LocationPreview.qml \
|
qml/components/LocationPreview.qml \
|
||||||
qml/components/MessageListViewItem.qml \
|
qml/components/MessageListViewItem.qml \
|
||||||
qml/components/MessageListViewItemSimple.qml \
|
qml/components/MessageListViewItemSimple.qml \
|
||||||
qml/components/MessageOverlayFlickable.qml \
|
qml/components/MessageOverlayFlickable.qml \
|
||||||
|
qml/components/MessageViaLabel.qml \
|
||||||
qml/components/MultilineEmojiLabel.qml \
|
qml/components/MultilineEmojiLabel.qml \
|
||||||
qml/components/PinnedMessageItem.qml \
|
qml/components/PinnedMessageItem.qml \
|
||||||
qml/components/PollPreview.qml \
|
qml/components/PollPreview.qml \
|
||||||
|
@ -72,6 +75,20 @@ DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationTextItem.qml \
|
qml/components/chatInformationPage/ChatInformationTextItem.qml \
|
||||||
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \
|
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \
|
||||||
qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \
|
qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResult.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultAnimation.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultArticle.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultAudio.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultContact.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultDefaultBase.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultDocument.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultGame.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultLocation.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultPhoto.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultSticker.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultVenue.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultVideo.qml \
|
||||||
|
qml/components/inlineQueryResults/InlineQueryResultVoiceNote.qml \
|
||||||
qml/js/debug.js \
|
qml/js/debug.js \
|
||||||
qml/js/functions.js \
|
qml/js/functions.js \
|
||||||
qml/pages/ChatInformationPage.qml \
|
qml/pages/ChatInformationPage.qml \
|
||||||
|
|
125
qml/components/GamePreview.qml
Normal file
125
qml/components/GamePreview.qml
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: gamePreviewItem
|
||||||
|
|
||||||
|
property ListItem messageListItem
|
||||||
|
property MessageOverlayFlickable overlayFlickable
|
||||||
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
|
property bool highlighted
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
text: Emoji.emojify(rawMessage.content.game.title || "", font.pixelSize)
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
text: Emoji.emojify(rawMessage.content.game.description || "", font.pixelSize)
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
text: Emoji.emojify(Functions.enhanceMessageText(rawMessage.content.game.text) || "", font.pixelSize)
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
onLinkActivated: {
|
||||||
|
var chatCommand = Functions.handleLink(link);
|
||||||
|
if(chatCommand) {
|
||||||
|
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: thumbnail
|
||||||
|
source: thumbnailFile.isDownloadingCompleted ? thumbnailFile.path : ""
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
asynchronous: true
|
||||||
|
visible: opacity > 0
|
||||||
|
opacity: status === Image.Ready ? 1.0 : 0.0
|
||||||
|
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: thumbnail }
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: thumbnailFile
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: width
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
topMargin: Theme.paddingSmall
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: Theme.paddingSmall
|
||||||
|
}
|
||||||
|
|
||||||
|
color: Theme.rgba(Theme.overlayBackgroundColor, 0.2)
|
||||||
|
radius: Theme.paddingSmall
|
||||||
|
Icon {
|
||||||
|
id: icon
|
||||||
|
source: "image://theme/icon-m-game-controller"
|
||||||
|
asynchronous: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (rawMessage.content.game.photo) {
|
||||||
|
// Check first which size fits best...
|
||||||
|
var photo
|
||||||
|
for (var i = 0; i < rawMessage.content.game.photo.sizes.length; i++) {
|
||||||
|
photo = rawMessage.content.game.photo.sizes[i].photo
|
||||||
|
if (rawMessage.content.game.photo.sizes[i].width >= gamePreviewItem.width) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (photo) {
|
||||||
|
thumbnailFile.fileInformation = photo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,6 @@ Item {
|
||||||
property ListItem messageListItem
|
property ListItem messageListItem
|
||||||
property MessageOverlayFlickable overlayFlickable
|
property MessageOverlayFlickable overlayFlickable
|
||||||
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
||||||
property var photoData: rawMessage.content.photo
|
|
||||||
readonly property int defaultHeight: Math.round(width * 2 / 3)
|
readonly property int defaultHeight: Math.round(width * 2 / 3)
|
||||||
property bool highlighted
|
property bool highlighted
|
||||||
|
|
||||||
|
@ -35,15 +34,19 @@ Item {
|
||||||
|
|
||||||
function clicked() {
|
function clicked() {
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), {
|
pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), {
|
||||||
"photoData" : imagePreviewItem.photoData,
|
"photoData" : imagePreviewItem.rawMessage.content.photo
|
||||||
"pictureFileInformation" : imageFile.fileInformation
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: updateImage()
|
||||||
if (photoData) {
|
|
||||||
|
onRawMessageChanged: updateImage()
|
||||||
|
|
||||||
|
function updateImage() {
|
||||||
|
if (rawMessage.content.photo) {
|
||||||
// Check first which size fits best...
|
// Check first which size fits best...
|
||||||
var photo
|
var photo
|
||||||
|
var photoData = rawMessage.content.photo
|
||||||
for (var i = 0; i < photoData.sizes.length; i++) {
|
for (var i = 0; i < photoData.sizes.length; i++) {
|
||||||
photo = photoData.sizes[i].photo
|
photo = photoData.sizes[i].photo
|
||||||
if (photoData.sizes[i].width >= imagePreviewItem.width) {
|
if (photoData.sizes[i].width >= imagePreviewItem.width) {
|
||||||
|
|
399
qml/components/InlineQuery.qml
Normal file
399
qml/components/InlineQuery.qml
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: inlineQueryLoader
|
||||||
|
active: userName.length > 1
|
||||||
|
asynchronous: true
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
bottom: active ? parent.bottom : parent.top
|
||||||
|
}
|
||||||
|
property bool hasOverlay: active && userNameIsValid && status === Loader.Ready && item.overlay && item.overlay.status === Loader.Ready
|
||||||
|
property bool hasButton: active && userNameIsValid && status === Loader.Ready && item.button && item.button.status === Loader.Ready
|
||||||
|
|
||||||
|
property int buttonPadding: hasButton ? item.button.height + Theme.paddingSmall : 0
|
||||||
|
Behavior on buttonPadding { NumberAnimation { duration: 200} }
|
||||||
|
|
||||||
|
property string chatId
|
||||||
|
property string userName
|
||||||
|
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.username.toLowerCase()
|
||||||
|
property string query
|
||||||
|
property int currentOffset: 0
|
||||||
|
property string responseExtra: chatId+"|"+userName+"|"+query+"|"+currentOffset
|
||||||
|
|
||||||
|
property bool queued: false
|
||||||
|
property TextArea textField
|
||||||
|
property bool isLoading
|
||||||
|
property var inlineBotInformation: null
|
||||||
|
onIsLoadingChanged: {
|
||||||
|
requestTimeout.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
inlineBotInformation = null;
|
||||||
|
if(status === Loader.Ready && userName !== "") {
|
||||||
|
isLoading = true; inlineQueryLoader.chatId
|
||||||
|
tdLibWrapper.searchPublicChat(userName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUserNameChanged: {
|
||||||
|
inlineBotInformation = null;
|
||||||
|
|
||||||
|
if(status === Loader.Ready && userName !== "") {
|
||||||
|
isLoading = true;
|
||||||
|
tdLibWrapper.searchPublicChat(userName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onQueryChanged: {
|
||||||
|
if(userName.length > 0) {
|
||||||
|
isLoading = true;
|
||||||
|
requestTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuery(name, query, offset) {
|
||||||
|
if(!name) {
|
||||||
|
inlineQueryLoader.userName = "";
|
||||||
|
inlineQueryLoader.query = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(inlineQueryLoader.userName !== name) {
|
||||||
|
inlineQueryLoader.userName = name
|
||||||
|
}
|
||||||
|
if(inlineQueryLoader.query !== query) {
|
||||||
|
inlineQueryLoader.query = query
|
||||||
|
}
|
||||||
|
inlineQueryLoader.currentOffset = offset || 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function request() {
|
||||||
|
if(!inlineBotInformation || !userNameIsValid) {
|
||||||
|
queued = true;
|
||||||
|
} else {
|
||||||
|
queued = false;
|
||||||
|
var location = null;
|
||||||
|
if(inlineBotInformation.type.need_location && fernschreiberUtils.supportsGeoLocation()) {
|
||||||
|
fernschreiberUtils.startGeoLocationUpdates();
|
||||||
|
if(!attachmentPreviewRow.locationData.latitude) {
|
||||||
|
queued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tdLibWrapper.getInlineQueryResults(inlineBotInformation.id, chatId, location, query, inlineQueryLoader.currentOffset, inlineQueryLoader.responseExtra);
|
||||||
|
isLoading = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: requestTimeout
|
||||||
|
interval: 5000
|
||||||
|
onTriggered: {
|
||||||
|
inlineQueryLoader.isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: requestTimer
|
||||||
|
interval: 1000
|
||||||
|
onTriggered: {
|
||||||
|
request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: fernschreiberUtils
|
||||||
|
onNewPositionInformation: {
|
||||||
|
attachmentPreviewRow.locationData = positionInformation;
|
||||||
|
if (inlineQueryLoader.queued) {
|
||||||
|
inlineQueryLoader.queued = false;
|
||||||
|
inlineQueryLoader.request()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: textField
|
||||||
|
onTextChanged: {
|
||||||
|
if(textField.text.charAt(0) === '@') {
|
||||||
|
var queryMatch = textField.text.match(/^@([a-zA-Z0-9_]+)\s(.*)/);
|
||||||
|
if(queryMatch) {
|
||||||
|
inlineQueryLoader.handleQuery(queryMatch[1], queryMatch[2]);
|
||||||
|
} else {
|
||||||
|
inlineQueryLoader.handleQuery();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inlineQueryLoader.handleQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: Component {
|
||||||
|
Item {
|
||||||
|
id: inlineQueryComponent
|
||||||
|
anchors.fill: parent
|
||||||
|
property alias overlay: resultsOverlay
|
||||||
|
property alias button: switchToPmLoader
|
||||||
|
property string nextOffset
|
||||||
|
property string inlineQueryId
|
||||||
|
property string switchPmText
|
||||||
|
property string switchPmParameter
|
||||||
|
property ListModel resultModel: ListModel {
|
||||||
|
dynamicRoles: true
|
||||||
|
}
|
||||||
|
property string inlineQueryPlaceholder: inlineBotInformation ? inlineBotInformation.type.inline_query_placeholder : ""
|
||||||
|
property bool showInlineQueryPlaceholder: !!inlineQueryPlaceholder && query === ""
|
||||||
|
property string useDelegateSize: "default"
|
||||||
|
property var dimensions: ({
|
||||||
|
"default": [[Screen.width, Screen.height / 2], [Theme.itemSizeLarge, Theme.itemSizeLarge]], // whole line (portrait half)
|
||||||
|
"inlineQueryResultAnimation": [[Screen.width / 3, Screen.height / 6], [Screen.width / 3, Screen.height / 6]],
|
||||||
|
"inlineQueryResultVideo": [[Screen.width / 2, Screen.height / 4], [Theme.itemSizeLarge, Theme.itemSizeLarge]],
|
||||||
|
"inlineQueryResultSticker": [[Screen.width / 3, Screen.height / 6], [Screen.width / 3, Screen.height / 6]],
|
||||||
|
"inlineQueryResultPhoto": [[Screen.width/2, Screen.height / 3], [Theme.itemSizeExtraLarge, Theme.itemSizeExtraLarge]],
|
||||||
|
})
|
||||||
|
property int delegateWidth: chatPage.isPortrait ? dimensions[useDelegateSize][0][0] : dimensions[useDelegateSize][0][1]
|
||||||
|
property int delegateHeight: chatPage.isPortrait ? dimensions[useDelegateSize][1][0] : dimensions[useDelegateSize][1][1]
|
||||||
|
|
||||||
|
function setDelegateSizes() {
|
||||||
|
var sizeKey = "default";
|
||||||
|
var modelCount = resultModel.count;
|
||||||
|
if(modelCount > 0) {
|
||||||
|
var firstType = resultModel.get(0)["@type"];
|
||||||
|
if(firstType && dimensions[firstType]) {
|
||||||
|
var startIndex = inlineQueryLoader.currentOffset === 0 ? 1 : inlineQueryLoader.currentOffset;
|
||||||
|
var same = true;
|
||||||
|
for(var i = startIndex; i < modelCount; i += 1) {
|
||||||
|
if(resultModel.get(i)["@type"] !== firstType) {
|
||||||
|
same = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(same) {
|
||||||
|
sizeKey = firstType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useDelegateSize = sizeKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadMore() {
|
||||||
|
if(nextOffset && inlineQueryLoader.userNameIsValid) {
|
||||||
|
inlineQueryLoader.currentOffset = nextOffset;
|
||||||
|
inlineQueryLoader.request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
|
||||||
|
onChatReceived: {
|
||||||
|
if(chat["@extra"] === "searchPublicChat:"+inlineQueryLoader.userName) {
|
||||||
|
requestTimeout.stop();
|
||||||
|
inlineQueryLoader.isLoading = false;
|
||||||
|
var inlineBotInformation = tdLibWrapper.getUserInformation(chat.type.user_id);
|
||||||
|
if(inlineBotInformation && inlineBotInformation.type["@type"] === "userTypeBot" && inlineBotInformation.type.is_inline) {
|
||||||
|
inlineQueryLoader.inlineBotInformation = inlineBotInformation;
|
||||||
|
requestTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onInlineQueryResults: {
|
||||||
|
if(extra === inlineQueryLoader.responseExtra) {
|
||||||
|
requestTimeout.stop();
|
||||||
|
inlineQueryLoader.isLoading = false;
|
||||||
|
inlineQueryComponent.inlineQueryId = inlineQueryId
|
||||||
|
inlineQueryComponent.nextOffset = nextOffset
|
||||||
|
inlineQueryComponent.switchPmText = switchPmText
|
||||||
|
inlineQueryComponent.switchPmParameter = switchPmParameter
|
||||||
|
|
||||||
|
if(inlineQueryLoader.currentOffset === 0) {
|
||||||
|
inlineQueryComponent.resultModel.clear()
|
||||||
|
}
|
||||||
|
for(var i = 0; i < results.length; i++) {
|
||||||
|
inlineQueryComponent.resultModel.append(results[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inlineQueryLoader.currentOffset === 0 || inlineQueryLoader.useDelegateSize !== "default") {
|
||||||
|
inlineQueryComponent.setDelegateSizes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// switch to pm Button
|
||||||
|
Loader {
|
||||||
|
id: switchToPmLoader
|
||||||
|
asynchronous: true
|
||||||
|
active: inlineQueryComponent.switchPmText.length > 0
|
||||||
|
opacity: status === Loader.Ready ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
height: Theme.itemSizeSmall
|
||||||
|
anchors {
|
||||||
|
top: parent.bottom
|
||||||
|
topMargin: Theme.paddingSmall
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: Theme.horizontalPageMargin
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.horizontalPageMargin
|
||||||
|
}
|
||||||
|
sourceComponent: Component {
|
||||||
|
MouseArea {
|
||||||
|
id: customButton
|
||||||
|
onClicked: {
|
||||||
|
tdLibWrapper.createPrivateChat(inlineQueryLoader.inlineBotInformation.id, "openAndSendStartToBot:"+(inlineQueryComponent.switchPmParameter.length > 0 ? " "+inlineQueryComponent.switchPmParameter:""));
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Theme.paddingSmall
|
||||||
|
color: parent.pressed ? Theme.highlightBackgroundColor : Theme.rgba(Theme.DarkOnLight ? Qt.lighter(Theme.primaryColor) : Qt.darker(Theme.primaryColor), Theme.opacityFaint)
|
||||||
|
Label {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: Theme.paddingLarge
|
||||||
|
rightMargin: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
fontSizeMode: Text.Fit;
|
||||||
|
minimumPixelSize: Theme.fontSizeTiny;
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
|
||||||
|
color: customButton.pressed ? Theme.highlightColor : Theme.primaryColor
|
||||||
|
text: Emoji.emojify(inlineQueryComponent.switchPmText, font.pixelSize)// + "we are gonna make this a bit longer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// results grid overlay
|
||||||
|
Loader {
|
||||||
|
id: resultsOverlay
|
||||||
|
asynchronous: true
|
||||||
|
active: inlineQueryComponent.resultModel.count > 0
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: !!item ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
property var supportedResultTypes: [
|
||||||
|
"inlineQueryResultAnimation",
|
||||||
|
"inlineQueryResultArticle",
|
||||||
|
"inlineQueryResultAudio",
|
||||||
|
"inlineQueryResultContact",
|
||||||
|
"inlineQueryResultDocument",
|
||||||
|
"inlineQueryResultGame",
|
||||||
|
"inlineQueryResultLocation",
|
||||||
|
"inlineQueryResultPhoto",
|
||||||
|
"inlineQueryResultSticker",
|
||||||
|
"inlineQueryResultVenue",
|
||||||
|
"inlineQueryResultVideo",
|
||||||
|
"inlineQueryResultVoiceNote",
|
||||||
|
]
|
||||||
|
sourceComponent: Component {
|
||||||
|
Item {
|
||||||
|
Rectangle {
|
||||||
|
id: messageContentBackground
|
||||||
|
color: Theme.overlayBackgroundColor
|
||||||
|
opacity: 0.7
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: autoLoadMoreTimer
|
||||||
|
interval: 400
|
||||||
|
onTriggered: {
|
||||||
|
if (inlineQueryComponent.nextOffset && resultView.height > resultView.contentHeight - Theme.itemSizeHuge) {
|
||||||
|
inlineQueryComponent.loadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SilicaGridView {
|
||||||
|
id: resultView
|
||||||
|
anchors.fill: parent
|
||||||
|
cellWidth: inlineQueryComponent.delegateWidth
|
||||||
|
cellHeight: inlineQueryComponent.delegateHeight
|
||||||
|
|
||||||
|
signal requestPlayback(url playbackSource)
|
||||||
|
clip: true
|
||||||
|
model: inlineQueryComponent.resultModel
|
||||||
|
delegate: Loader {
|
||||||
|
id: queryResultDelegate
|
||||||
|
height: resultView.cellHeight
|
||||||
|
width: resultView.cellWidth
|
||||||
|
source: "inlineQueryResults/" + (resultsOverlay.supportedResultTypes.indexOf(model["@type"]) > -1 ? (model["@type"].charAt(0).toUpperCase() + model["@type"].substring(1)) : "InlineQueryResultDefaultBase") +".qml"
|
||||||
|
}
|
||||||
|
footer: Component {
|
||||||
|
Item {
|
||||||
|
width: resultView.width
|
||||||
|
visible: height > 0
|
||||||
|
height: inlineQueryComponent.nextOffset ? Theme.itemSizeLarge : 0
|
||||||
|
Behavior on height { NumberAnimation { duration: 500 } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onContentYChanged: {
|
||||||
|
if(!inlineQueryLoader.isLoading && inlineQueryComponent.nextOffset && contentHeight - contentY - height < Theme.itemSizeHuge) {
|
||||||
|
inlineQueryComponent.loadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollDecorator { flickable: resultView }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// textarea placeholder
|
||||||
|
Loader {
|
||||||
|
asynchronous: true
|
||||||
|
active: inlineQueryComponent.showInlineQueryPlaceholder
|
||||||
|
sourceComponent: Component {
|
||||||
|
Label {
|
||||||
|
text: Emoji.emojify(inlineQueryComponent.inlineQueryPlaceholder, font.pixelSize);
|
||||||
|
parent: textField
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: textMetrics.boundingRect.width + Theme.paddingSmall
|
||||||
|
font: textField.font
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
TextMetrics {
|
||||||
|
id: textMetrics
|
||||||
|
font: textField.font
|
||||||
|
text: textField.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ Item {
|
||||||
property var pictureFileInformation;
|
property var pictureFileInformation;
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: width / 2
|
height: width / 2
|
||||||
|
property string fileExtra
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
updatePicture();
|
updatePicture();
|
||||||
|
@ -47,14 +48,18 @@ Item {
|
||||||
function updatePicture() {
|
function updatePicture() {
|
||||||
imagePreviewItem.pictureFileInformation = null;
|
imagePreviewItem.pictureFileInformation = null;
|
||||||
if (locationData) {
|
if (locationData) {
|
||||||
tdLibWrapper.getMapThumbnailFile(chatId, locationData.latitude, locationData.longitude, Math.round(imagePreviewItem.width), Math.round(imagePreviewItem.height));
|
fileExtra = "location:" + locationData.latitude + ":" + locationData.longitude + ":" + Math.round(imagePreviewItem.width) + ":" + Math.round(imagePreviewItem.height);
|
||||||
|
tdLibWrapper.getMapThumbnailFile(chatId, locationData.latitude, locationData.longitude, Math.round(imagePreviewItem.width), Math.round(imagePreviewItem.height), fileExtra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onFileUpdated: {
|
onFileUpdated: {
|
||||||
// we do not have a way of knowing if this is the correct file, so we have to guess the first new one should be right.
|
if(fileInformation["@extra"] !== imagePreviewItem.fileExtra) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!imagePreviewItem.pictureFileInformation) {
|
if(!imagePreviewItem.pictureFileInformation) {
|
||||||
imagePreviewItem.pictureFileInformation = fileInformation;
|
imagePreviewItem.pictureFileInformation = fileInformation;
|
||||||
tdLibWrapper.downloadFile(imagePreviewItem.pictureFileInformation.id);
|
tdLibWrapper.downloadFile(imagePreviewItem.pictureFileInformation.id);
|
||||||
|
|
|
@ -241,7 +241,7 @@ ListItem {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
|
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,11 +299,15 @@ ListItem {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
|
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id, "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageViaLabel {
|
||||||
|
message: myMessage
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: messageInReplyToLoader
|
id: messageInReplyToLoader
|
||||||
active: myMessage.reply_to_message_id !== 0
|
active: myMessage.reply_to_message_id !== 0
|
||||||
|
|
|
@ -20,12 +20,14 @@ import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: messageListItem
|
id: messageListItem
|
||||||
property var myMessage: display
|
property var myMessage: display
|
||||||
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
||||||
property bool isOwnMessage: chatPage.myUserId === myMessage.sender.user_id
|
property bool isOwnMessage: chatPage.myUserId === myMessage.sender.user_id
|
||||||
|
property var linkedMessage
|
||||||
height: backgroundRectangle.height + Theme.paddingMedium
|
height: backgroundRectangle.height + Theme.paddingMedium
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -43,11 +45,40 @@ Item {
|
||||||
color: Theme.highlightColor
|
color: Theme.highlightColor
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: Theme.fontSizeExtraSmall
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
text: "<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + messageListItem.userInformation.id + "\">" + (!messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You")) + "</a> " + Emoji.emojify(Functions.getMessageText(messageListItem.myMessage, false, chatPage.myUserId, false), font.pixelSize)
|
property string messageContentText: Functions.getMessageText(messageListItem.myMessage, false, chatPage.myUserId, false)
|
||||||
|
text: "<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + messageListItem.userInformation.id + "\">" + (!messageListItem.isOwnMessage ? Emoji.emojify(Functions.getUserName(messageListItem.userInformation), font.pixelSize) : qsTr("You")) + "</a> " + Emoji.emojify(messageContentText, font.pixelSize)
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
|
if(link === "linkedmessage" && linkedMessage) {
|
||||||
|
messageOverlayLoader.overlayMessage = linkedMessage;
|
||||||
|
messageOverlayLoader.active = true;
|
||||||
|
} else {
|
||||||
Functions.handleLink(link);
|
Functions.handleLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
id: gameScoreInfoLoader
|
||||||
|
active: myMessage.content["@type"] === "messageGameScore"
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: Component {
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onReceivedMessage: {
|
||||||
|
if(chatId === chatPage.chatInformation.id && messageId === myMessage.content.game_message_id) {
|
||||||
|
messageListItem.linkedMessage = message;
|
||||||
|
messageText.messageContentText = messageListItem.isOwnMessage ?
|
||||||
|
qsTr("scored %Ln points in %2", "myself", myMessage.content.score).arg("<a href=\"linkedmessage\" style=\"text-decoration: none; color:"+Theme.primaryColor+"\">"+message.content.game.title+"</a>") :
|
||||||
|
|
||||||
|
qsTr("scored %Ln points in %2", "", myMessage.content.score).arg("<a href=\"linkedmessage\" style=\"text-decoration: none; color:"+Theme.primaryColor+"\" >"+message.content.game.title+"</a>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
tdLibWrapper.getMessage(chatPage.chatInformation.id, myMessage.content.game_message_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
import "../components"
|
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../js/twemoji.js" as Emoji
|
import "../js/twemoji.js" as Emoji
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: messageOverlayFlickable
|
id: messageOverlayFlickable
|
||||||
|
@ -124,6 +124,10 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageViaLabel {
|
||||||
|
message: overlayMessage
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: overlayForwardedInfoText
|
id: overlayForwardedInfoText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -179,6 +183,16 @@ Flickable {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: replyMarkupLoader
|
||||||
|
property var myMessage: overlayMessage
|
||||||
|
width: parent.width
|
||||||
|
height: active ? (overlayMessage.reply_markup.rows.length * (Theme.itemSizeSmall + Theme.paddingSmall) - Theme.paddingSmall) : 0
|
||||||
|
asynchronous: true
|
||||||
|
active: !!overlayMessage.reply_markup && myMessage.reply_markup.rows
|
||||||
|
source: Qt.resolvedUrl("ReplyMarkupButtons.qml")
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: messageDateUpdater
|
id: messageDateUpdater
|
||||||
interval: 60000
|
interval: 60000
|
||||||
|
|
49
qml/components/MessageViaLabel.qml
Normal file
49
qml/components/MessageViaLabel.qml
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: botUserLoader
|
||||||
|
active: !!message.via_bot_user_id
|
||||||
|
width: parent.width
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: Label {
|
||||||
|
property var botUserInformation: tdLibWrapper.getUserInformation(message.via_bot_user_id)
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
font.pixelSize: Theme.fontSizeExtraSmall
|
||||||
|
text: qsTr("via %1", "message posted via bot user").arg("<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + message.via_bot_user_id + "\">@" + Emoji.emojify(botUserInformation.username, font.pixelSize)+"</a>")
|
||||||
|
textFormat: Text.RichText
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
onLinkActivated: {
|
||||||
|
if(link === "userId://" + message.via_bot_user_id && botUserInformation.type.is_inline) {
|
||||||
|
newMessageTextField.text = "@"+botUserInformation.username+" "
|
||||||
|
newMessageTextField.cursorPosition = newMessageTextField.text.length
|
||||||
|
lostFocusTimer.start();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Functions.handleLink(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property var message
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import "../js/functions.js" as Functions
|
||||||
import "../js/debug.js" as Debug
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
id: replyMarkupButtons
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
|
@ -36,7 +37,7 @@ Column {
|
||||||
Repeater {
|
Repeater {
|
||||||
id: buttonsRepeater
|
id: buttonsRepeater
|
||||||
model: modelData
|
model: modelData
|
||||||
property int itemWidth:precalculatedValues.textColumnWidth / count
|
property int itemWidth: replyMarkupButtons.width / count
|
||||||
delegate: MouseArea {
|
delegate: MouseArea {
|
||||||
/*
|
/*
|
||||||
Unimplemented callback types:
|
Unimplemented callback types:
|
||||||
|
@ -48,15 +49,35 @@ Column {
|
||||||
*/
|
*/
|
||||||
property var callbacks: ({
|
property var callbacks: ({
|
||||||
inlineKeyboardButtonTypeCallback: function(){
|
inlineKeyboardButtonTypeCallback: function(){
|
||||||
tdLibWrapper.getCallbackQueryAnswer(messageListItem.chatId, messageListItem.messageId, {data: modelData.type.data, "@type": "callbackQueryPayloadData"})
|
tdLibWrapper.getCallbackQueryAnswer(myMessage.chat_id, myMessage.id, {data: modelData.type.data, "@type": "callbackQueryPayloadData"})
|
||||||
|
},
|
||||||
|
|
||||||
|
inlineKeyboardButtonTypeCallbackGame: function(){
|
||||||
|
tdLibWrapper.getCallbackQueryAnswer(myMessage.chat_id, myMessage.id, {game_short_name: myMessage.content.game.short_name, "@type": "callbackQueryPayloadGame"})
|
||||||
},
|
},
|
||||||
inlineKeyboardButtonTypeUrl: function() {
|
inlineKeyboardButtonTypeUrl: function() {
|
||||||
Functions.handleLink(modelData.type.url);
|
Functions.handleLink(modelData.type.url);
|
||||||
|
},
|
||||||
|
inlineKeyboardButtonTypeSwitchInline: function() {
|
||||||
|
if(modelData.type.in_current_chat) {
|
||||||
|
chatPage.setMessageText("@" + userInformation.username + " "+(modelData.type.query || ""))
|
||||||
|
} else {
|
||||||
|
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
|
||||||
|
myUserId: chatPage.myUserId,
|
||||||
|
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.username + " "+(modelData.type.query || "")},
|
||||||
|
state: "fillTextArea"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
keyboardButtonTypeText: function() {
|
||||||
|
chatPage.setMessageText(modelData.text, true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
enabled: !!callbacks[modelData.type["@type"]]
|
enabled: !!callbacks[modelData.type["@type"]]
|
||||||
height: Theme.itemSizeSmall
|
height: Theme.itemSizeSmall
|
||||||
width: (precalculatedValues.textColumnWidth + Theme.paddingSmall) / buttonsRepeater.count - (Theme.paddingSmall)
|
width: (replyMarkupButtons.width + Theme.paddingSmall) / buttonsRepeater.count - (Theme.paddingSmall)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
callbacks[modelData.type["@type"]]();
|
callbacks[modelData.type["@type"]]();
|
||||||
}
|
}
|
||||||
|
@ -71,17 +92,18 @@ Column {
|
||||||
width: Math.min(parent.width - Theme.paddingSmall*2, contentWidth)
|
width: Math.min(parent.width - Theme.paddingSmall*2, contentWidth)
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
text: Emoji.emojify(modelData.text, Theme.fontSizeSmall)
|
text: Emoji.emojify(modelData.text, Theme.fontSizeSmall)
|
||||||
color: parent.pressed ? Theme.highlightColor : Theme.primaryColor
|
color: parent.parent.pressed ? Theme.highlightColor : Theme.primaryColor
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
}
|
}
|
||||||
Icon {
|
Icon {
|
||||||
property var sources: ({
|
property var sources: ({
|
||||||
inlineKeyboardButtonTypeUrl: "../../images/icon-s-link.svg",
|
inlineKeyboardButtonTypeUrl: "../../images/icon-s-link.svg",
|
||||||
inlineKeyboardButtonTypeSwitchInline: "image://theme/icon-s-repost",
|
inlineKeyboardButtonTypeSwitchInline: !modelData.type.in_current_chat ? "image://theme/icon-s-repost" : "image://theme/icon-s-edit",
|
||||||
inlineKeyboardButtonTypeCallbackWithPassword: "image://theme/icon-s-asterisk"
|
inlineKeyboardButtonTypeCallbackWithPassword: "image://theme/icon-s-asterisk"
|
||||||
})
|
})
|
||||||
visible: !!sources[modelData.type["@type"]]
|
visible: !!sources[modelData.type["@type"]]
|
||||||
|
opacity: 0.6
|
||||||
source: sources[modelData.type["@type"]] || ""
|
source: sources[modelData.type["@type"]] || ""
|
||||||
sourceSize: Qt.size(Theme.iconSizeSmall, Theme.iconSizeSmall)
|
sourceSize: Qt.size(Theme.iconSizeSmall, Theme.iconSizeSmall)
|
||||||
highlighted: parent.pressed
|
highlighted: parent.pressed
|
||||||
|
|
|
@ -232,7 +232,7 @@ SilicaFlickable {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: chatInformationPage.isPrivateChat
|
visible: chatInformationPage.isPrivateChat
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId);
|
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId, "openDirectly");
|
||||||
}
|
}
|
||||||
text: qsTr("New Secret Chat")
|
text: qsTr("New Secret Chat")
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ ChatInformationTabItemBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(user_id);
|
tdLibWrapper.createPrivateChat(user_id, "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
footer: Component {
|
footer: Component {
|
||||||
|
@ -162,7 +162,7 @@ ChatInformationTabItemBase {
|
||||||
interval: 600
|
interval: 600
|
||||||
property int fetchLimit: 50
|
property int fetchLimit: 50
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if(chatInformationPage.isSuperGroup && !chatInformationPage.isChannel && (chatInformationPage.groupInformation.member_count > membersView.count)) { //
|
if(chatInformationPage.isSuperGroup && (!chatInformationPage.isChannel || chatInformationPage.canGetMembers) && (chatInformationPage.groupInformation.member_count > membersView.count)) {
|
||||||
tabBase.loading = true
|
tabBase.loading = true
|
||||||
tdLibWrapper.getSupergroupMembers(chatInformationPage.chatPartnerGroupId, fetchLimit, pageContent.membersList.count);
|
tdLibWrapper.getSupergroupMembers(chatInformationPage.chatPartnerGroupId, fetchLimit, pageContent.membersList.count);
|
||||||
fetchLimit = 200
|
fetchLimit = 200
|
||||||
|
|
33
qml/components/inlineQueryResults/InlineQueryResult.qml
Normal file
33
qml/components/inlineQueryResults/InlineQueryResult.qml
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
|
BackgroundItem {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
function sendInlineQueryResultMessage() {
|
||||||
|
tdLibWrapper.sendInlineQueryResultMessage(inlineQueryLoader.chatId, 0, 0, inlineQueryComponent.inlineQueryId, model.id);
|
||||||
|
inlineQueryLoader.textField.text = "";
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
sendInlineQueryResultMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
291
qml/components/inlineQueryResults/InlineQueryResultAnimation.qml
Normal file
291
qml/components/inlineQueryResults/InlineQueryResultAnimation.qml
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import QtMultimedia 5.6
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import Nemo.Thumbnailer 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
import "../../js/debug.js" as Debug
|
||||||
|
|
||||||
|
InlineQueryResult {
|
||||||
|
id: queryResultItem
|
||||||
|
property bool isAnimation: true
|
||||||
|
property bool loopPreview: isAnimation
|
||||||
|
property bool mutePreview: isAnimation
|
||||||
|
enabled: false // don't send on click
|
||||||
|
layer.enabled: mouseArea.pressed
|
||||||
|
layer.effect: PressEffect { source: queryResultItem }
|
||||||
|
|
||||||
|
property string animationKey: "animation"
|
||||||
|
property bool hasThumbnail: !!model[queryResultItem.animationKey].thumbnail
|
||||||
|
|
||||||
|
property string videoMimeType: "video/mp4"
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: file
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
fileInformation: hasThumbnail ? model[queryResultItem.animationKey].thumbnail.file : (queryResultItem.isAnimation ? model[queryResultItem.animationKey].animation : model[queryResultItem.animationKey].video)
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: miniThumbnail
|
||||||
|
asynchronous: true
|
||||||
|
source: model[queryResultItem.animationKey].minithumbnail ? "data:image/jpg;base64,"+model[queryResultItem.animationKey].minithumbnail.data : ""
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: miniThumbnail }
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: videoThumbnail
|
||||||
|
Thumbnail {
|
||||||
|
id: thumbnail
|
||||||
|
source: file.path
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
mimeType: queryResultItem.videoMimeType
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: thumbnail }
|
||||||
|
opacity: status === Thumbnail.Ready ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: imageThumbnail
|
||||||
|
Image {
|
||||||
|
id: thumbnail
|
||||||
|
source: file.path
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: thumbnail }
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
opacity: status === Image.Ready ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
onStatusChanged: {
|
||||||
|
// we don't get many hints what may be wrong, so we guess it may be a webp image ;)
|
||||||
|
if(status === Image.Error) {
|
||||||
|
Debug.log("Inline Query Video: Thumbnail invalid. Blindly trying webp, which might work.")
|
||||||
|
queryResultItem.videoMimeType = "image/webp";
|
||||||
|
thumbnailLoader.sourceComponent = videoThumbnail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
id: thumbnailLoader
|
||||||
|
asynchronous: true
|
||||||
|
active: file.isDownloadingCompleted
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: queryResultItem.hasThumbnail ? (model[queryResultItem.animationKey].thumbnail.format["@type"] === "thumbnailFormatMpeg4" ? videoThumbnail : imageThumbnail) : model[queryResultItem.animationKey].mime_type === "video/mp4" ? videoThumbnail : imageThumbnail
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
id: texts
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
margins: Theme.paddingSmall
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: titleLabel
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
visible: text.length > 0
|
||||||
|
text: Emoji.emojify(model.title || "", font.pixelSize);
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: descriptionLabel
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
visible: text.length > 0
|
||||||
|
text: Emoji.emojify(model.description || "", font.pixelSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: texts
|
||||||
|
asynchronous: true
|
||||||
|
active: titleLabel.visible || descriptionLabel.visible
|
||||||
|
sourceComponent: Component {
|
||||||
|
DropShadow {
|
||||||
|
horizontalOffset: 0
|
||||||
|
verticalOffset: 0
|
||||||
|
radius: Theme.paddingSmall
|
||||||
|
spread: 0.5
|
||||||
|
samples: 17
|
||||||
|
color: Theme.overlayBackgroundColor
|
||||||
|
source: texts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
// dialog
|
||||||
|
|
||||||
|
var dialog = pageStack.push(dialogComponent,{})
|
||||||
|
dialog.accepted.connect(function() {
|
||||||
|
queryResultItem.sendInlineQueryResultMessage();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: dialogComponent
|
||||||
|
Dialog {
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: previewFile
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: model[queryResultItem.animationKey].mime_type !== "text/html"
|
||||||
|
fileInformation: queryResultItem.isAnimation ? model[queryResultItem.animationKey].animation : model[queryResultItem.animationKey].video
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogHeader { id: dialogHeader }
|
||||||
|
|
||||||
|
ProgressCircle {
|
||||||
|
value: previewFile.downloadedSize / previewFile.expectedSize
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: Theme.iconSizeMedium
|
||||||
|
anchors.centerIn: parent
|
||||||
|
opacity: previewFile.isDownloadingActive ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
visible: !previewFile.autoLoad
|
||||||
|
spacing: Theme.paddingLarge
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: Theme.horizontalPageMargin
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.horizontalPageMargin
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
text: Emoji.emojify(model.title || "", font.pixelSize);
|
||||||
|
visible: text.length > 1
|
||||||
|
linkColor: Theme.primaryColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.highlightColor
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
text: '<a href="'+Emoji.emojify(previewFile.fileInformation.remote.id, font.pixelSize)+'">'+Emoji.emojify(previewFile.fileInformation.remote.id, font.pixelSize)+'</a> '
|
||||||
|
linkColor: Theme.primaryColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
text: Emoji.emojify(model.description || "", font.pixelSize)
|
||||||
|
visible: text.length > 1
|
||||||
|
linkColor: Theme.secondaryColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: videoLoader
|
||||||
|
anchors {
|
||||||
|
top: dialogHeader.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
active: previewFile.isDownloadingCompleted
|
||||||
|
asynchronous: true
|
||||||
|
sourceComponent: Component {
|
||||||
|
Item {
|
||||||
|
Connections {
|
||||||
|
target: resultView
|
||||||
|
onRequestPlayback: {
|
||||||
|
if(previewVideo.playbackState === MediaPlayer.PlayingState && previewVideo.source !== playbackSource) {
|
||||||
|
previewVideo.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: loopTimer
|
||||||
|
interval: 0
|
||||||
|
onTriggered: previewVideo.play()
|
||||||
|
}
|
||||||
|
|
||||||
|
Video {
|
||||||
|
id: previewVideo
|
||||||
|
source: previewFile.path
|
||||||
|
autoPlay: true
|
||||||
|
muted: queryResultItem.mutePreview
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status == MediaPlayer.EndOfMedia) {
|
||||||
|
if(queryResultItem.loopPreview) {
|
||||||
|
loopTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPlaybackStateChanged: {
|
||||||
|
if(playbackState === MediaPlayer.PlayingState) {
|
||||||
|
resultView.requestPlayback(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layer.enabled: playPauseMouseArea.pressed
|
||||||
|
layer.effect: PressEffect { source: previewVideo }
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: playPauseMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if(previewVideo.playbackState === MediaPlayer.PlayingState) {
|
||||||
|
previewVideo.pause();
|
||||||
|
} else {
|
||||||
|
previewVideo.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
InlineQueryResultDefaultBase {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
title: Emoji.emojify(model.title || "", titleLable.font.pixelSize)
|
||||||
|
description: Emoji.emojify(model.description || "", descriptionLabel.font.pixelSize)
|
||||||
|
descriptionLabel {
|
||||||
|
maximumLineCount: 3
|
||||||
|
wrapMode: extraText.length === 0 ? Text.Wrap : Text.NoWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
extraText: model.url || ""
|
||||||
|
extraTextLabel.visible: !model.hide_url && extraText.length > 0
|
||||||
|
|
||||||
|
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
||||||
|
|
||||||
|
icon.source: "image://theme/icon-m-link"
|
||||||
|
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
||||||
|
|
||||||
|
thumbnail.visible: model.thumbnail || !!model.url
|
||||||
|
}
|
183
qml/components/inlineQueryResults/InlineQueryResultAudio.qml
Normal file
183
qml/components/inlineQueryResults/InlineQueryResultAudio.qml
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import QtMultimedia 5.6
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
InlineQueryResult {
|
||||||
|
id: queryResultItem
|
||||||
|
property var resultData: model.audio || model.voice_note
|
||||||
|
property var audioData: resultData.audio || resultData.voice
|
||||||
|
|
||||||
|
enabled: false // don't send on click
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: resultView
|
||||||
|
onRequestPlayback: {
|
||||||
|
if(audioPlayer.playbackState === Audio.PlayingState && audioPlayer.source !== playbackSource) {
|
||||||
|
audioPlayer.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: file
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: false
|
||||||
|
fileInformation: queryResultItem.audioData
|
||||||
|
}
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: thumbnail
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
fileInformation: queryResultItem.resultData.album_cover_thumbnail ? queryResultItem.resultData.album_cover_thumbnail.file : {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: thumbnailLoader
|
||||||
|
asynchronous: true
|
||||||
|
active: thumbnail.isDownloadingCompleted
|
||||||
|
height: parent.height
|
||||||
|
width: height
|
||||||
|
opacity: item && item.status === Image.Ready ? 0.5 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
sourceComponent: Component {
|
||||||
|
Image {
|
||||||
|
id: thumbnailImage
|
||||||
|
source: thumbnail.path
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
|
||||||
|
layer.enabled: playPauseButton.pressed
|
||||||
|
layer.effect: PressEffect { source: thumbnailImage }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: playPauseButton
|
||||||
|
anchors.centerIn: thumbnailLoader
|
||||||
|
icon {
|
||||||
|
asynchronous: true
|
||||||
|
source: audioPlayer.playbackState === Audio.PlayingState || (file.isDownloadingActive && audioPlayer.autoPlay) ? "image://theme/icon-m-pause": "image://theme/icon-m-play"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
if(!file.isDownloadingCompleted && !file.isDownloadingActive) {
|
||||||
|
file.load();
|
||||||
|
audioPlayer.autoPlay = true
|
||||||
|
} else if(file.isDownloadingActive) {
|
||||||
|
// cancel playback intent?
|
||||||
|
audioPlayer.autoPlay = false
|
||||||
|
} else if(file.isDownloadingCompleted) {
|
||||||
|
//playPause
|
||||||
|
if(audioPlayer.playbackState === Audio.PlayingState) {
|
||||||
|
audioPlayer.pause();
|
||||||
|
} else {
|
||||||
|
audioPlayer.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProgressCircle {
|
||||||
|
value: file.downloadedSize / file.expectedSize
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: Theme.iconSizeMedium
|
||||||
|
anchors.centerIn: playPauseButton
|
||||||
|
opacity: file.isDownloadingActive ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio {
|
||||||
|
id: audioPlayer
|
||||||
|
source: file.isDownloadingCompleted ? file.path : ""
|
||||||
|
autoPlay: false
|
||||||
|
onPlaybackStateChanged: {
|
||||||
|
if(playbackState === Audio.PlayingState) {
|
||||||
|
resultView.requestPlayback(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
left: thumbnailLoader.right
|
||||||
|
leftMargin: Theme.paddingSmall
|
||||||
|
right: sendButton.left
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.highlightColor
|
||||||
|
text: Emoji.emojify(queryResultItem.resultData.performer || "", font.pixelSize)
|
||||||
|
visible: text.length > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: Theme.secondaryHighlightColor
|
||||||
|
text: Emoji.emojify(queryResultItem.resultData.title || model.title || "", font.pixelSize)
|
||||||
|
visible: text.length > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
height: sizeLabel.height
|
||||||
|
width: parent.width
|
||||||
|
Label {
|
||||||
|
id: durationLabel
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
text: (audioPlayer.position > 0 || audioPlayer.playbackState === Audio.PlayingState ? (Format.formatDuration(audioPlayer.position/1000, Formatter.DurationShort)+" / ") : "") + Format.formatDuration(queryResultItem.audioData.duration || (audioPlayer.duration/1000), Formatter.DurationShort)
|
||||||
|
visible: (queryResultItem.audioData.duration || (audioPlayer.duration/1000)) > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: sizeLabel
|
||||||
|
anchors.right: parent.right
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: Theme.secondaryColor
|
||||||
|
text: Format.formatFileSize(file.expectedSize)
|
||||||
|
visible: file.expectedSize > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: sendButton
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.horizontalPageMargin
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
icon {
|
||||||
|
asynchronous: true
|
||||||
|
source: "image://theme/icon-m-send"
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
queryResultItem.sendInlineQueryResultMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
InlineQueryResultDefaultBase {
|
||||||
|
id: queryResultItem
|
||||||
|
property string namesSeparator: model.contact.first_name && model.contact.last_name ? " " : ""
|
||||||
|
|
||||||
|
title: Emoji.emojify(model.contact.first_name + namesSeparator + model.contact.last_name || "", titleLable.font.pixelSize)
|
||||||
|
description: Emoji.emojify(model.contact.phone_number || "", descriptionLabel.font.pixelSize)
|
||||||
|
|
||||||
|
extraText: model.url || ""
|
||||||
|
extraTextLabel.visible: !model.hide_url && extraText.length > 0
|
||||||
|
|
||||||
|
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
||||||
|
|
||||||
|
icon.source: "image://theme/icon-m-contact"
|
||||||
|
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
InlineQueryResult {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
property alias title: titleLabel.text
|
||||||
|
property alias titleLable: titleLabel
|
||||||
|
|
||||||
|
property alias description: descriptionLabel.text
|
||||||
|
property alias descriptionLabel: descriptionLabel
|
||||||
|
|
||||||
|
property alias extraText: extraTextLabel.text
|
||||||
|
property alias extraTextLabel: extraTextLabel
|
||||||
|
|
||||||
|
property alias thumbnailFileInformation: thumbnailFile.fileInformation
|
||||||
|
property alias thumbnail: thumbnail
|
||||||
|
|
||||||
|
property alias icon: icon
|
||||||
|
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: thumbnail
|
||||||
|
source: thumbnailFile.isDownloadingCompleted ? thumbnailFile.path : ""
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
asynchronous: true
|
||||||
|
width: visible ? Theme.itemSizeLarge : 0
|
||||||
|
height: width
|
||||||
|
opacity: status === Image.Ready ? 1.0 : 0.0
|
||||||
|
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: thumbnail }
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: thumbnailFile
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Icon {
|
||||||
|
id: icon
|
||||||
|
asynchronous: true
|
||||||
|
anchors.centerIn: thumbnail
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
left: thumbnail.right
|
||||||
|
leftMargin: thumbnail.visible ? Theme.paddingLarge : Theme.horizontalPageMargin
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: Theme.horizontalPageMargin
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: titleLabel
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: highlighted || !queryResultItem.enabled ? Theme.highlightColor : Theme.primaryColor
|
||||||
|
visible: text.length > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: descriptionLabel
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: highlighted || !queryResultItem.enabled ? Theme.secondaryColor : Theme.secondaryHighlightColor
|
||||||
|
visible: text.length > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: extraTextLabel
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
color: highlighted || !queryResultItem.enabled ? Theme.secondaryHighlightColor : Theme.secondaryColor
|
||||||
|
visible: text.length > 0
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
Component {
|
||||||
|
id: documentComponent
|
||||||
|
InlineQueryResultDefaultBase {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
title: Emoji.emojify(model.title || model.document.file_name || "", titleLable.font.pixelSize)
|
||||||
|
description: Emoji.emojify(model.description || model.document.file_name || "", descriptionLabel.font.pixelSize)
|
||||||
|
extraText: Format.formatFileSize(model.document.document.expected_size)
|
||||||
|
|
||||||
|
thumbnailFileInformation: model.thumbnail ? model.thumbnail.file : {}
|
||||||
|
|
||||||
|
icon.source: Theme.iconForMimeType(model.document.mime_type)
|
||||||
|
icon.visible: thumbnail.visible && thumbnail.opacity === 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: voiceNoteDocumentComponent
|
||||||
|
InlineQueryResultVoiceNote {
|
||||||
|
resultData: model.document
|
||||||
|
audioData: model.document.document
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceComponent: model.document.mime_type === "audio/ogg" ? voiceNoteDocumentComponent : documentComponent
|
||||||
|
}
|
53
qml/components/inlineQueryResults/InlineQueryResultGame.qml
Normal file
53
qml/components/inlineQueryResults/InlineQueryResultGame.qml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
InlineQueryResultDefaultBase {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
title: Emoji.emojify(model.game.title || "", titleLable.font.pixelSize)
|
||||||
|
description: Emoji.emojify(model.game.description || "", descriptionLabel.font.pixelSize)
|
||||||
|
descriptionLabel {
|
||||||
|
maximumLineCount: 3
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
icon.source: "image://theme/icon-m-game-controller"
|
||||||
|
icon.visible: thumbnail.opacity === 0
|
||||||
|
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (model.game.photo) {
|
||||||
|
// Check first which size fits best...
|
||||||
|
var photo
|
||||||
|
for (var i = 0; i < model.game.photo.sizes.length; i++) {
|
||||||
|
photo = model.game.photo.sizes[i].photo
|
||||||
|
if (model.game.photo.sizes[i].width >= queryResultItem.width) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (photo) {
|
||||||
|
thumbnailFileInformation = photo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
|
||||||
|
InlineQueryResultVenue {
|
||||||
|
resultData: model
|
||||||
|
}
|
68
qml/components/inlineQueryResults/InlineQueryResultPhoto.qml
Normal file
68
qml/components/inlineQueryResults/InlineQueryResultPhoto.qml
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import QtMultimedia 5.6
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
InlineQueryResult {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: file
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
autoLoad: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
asynchronous: true
|
||||||
|
active: file.isDownloadingCompleted
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: item && item.status === Image.Ready ? 1.0 : 0.0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
sourceComponent: Component {
|
||||||
|
Image {
|
||||||
|
id: image
|
||||||
|
source: file.path
|
||||||
|
asynchronous: true
|
||||||
|
clip: true
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
layer.enabled: queryResultItem.pressed
|
||||||
|
layer.effect: PressEffect { source: image }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (model.photo) {
|
||||||
|
// Check first which size fits best...
|
||||||
|
var photo
|
||||||
|
for (var i = 0; i < model.photo.sizes.length; i++) {
|
||||||
|
photo = model.photo.sizes[i].photo
|
||||||
|
if (model.photo.sizes[i].width >= queryResultItem.width) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (photo) {
|
||||||
|
file.fileInformation = photo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
qml/components/inlineQueryResults/InlineQueryResultSticker.qml
Normal file
106
qml/components/inlineQueryResults/InlineQueryResultSticker.qml
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import Nemo.Thumbnailer 1.0
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
InlineQueryResult {
|
||||||
|
id: queryResultItem
|
||||||
|
|
||||||
|
property bool animate
|
||||||
|
property bool animating: animate && model.sticker.is_animated
|
||||||
|
property url stickerId: "http://sticker/" + model.sticker.sticker.remote.id
|
||||||
|
onAnimatingChanged: {
|
||||||
|
if(animating) {
|
||||||
|
resultView.requestPlayback(stickerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: resultView
|
||||||
|
onRequestPlayback: {
|
||||||
|
if(queryResultItem.animating && queryResultItem.stickerId !== playbackSource) {
|
||||||
|
animate = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressAndHold: {
|
||||||
|
animate = !animate
|
||||||
|
}
|
||||||
|
|
||||||
|
TDLibFile {
|
||||||
|
id: file
|
||||||
|
tdlib: tdLibWrapper
|
||||||
|
fileInformation: model.sticker.sticker
|
||||||
|
autoLoad: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: animatedStickerLoader
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
active: queryResultItem.animating
|
||||||
|
sourceComponent: Component {
|
||||||
|
AnimatedImage {
|
||||||
|
id: animatedSticker
|
||||||
|
anchors.fill: parent
|
||||||
|
source: file.path
|
||||||
|
asynchronous: true
|
||||||
|
paused: !Qt.application.active
|
||||||
|
cache: false
|
||||||
|
layer.enabled: highlighted
|
||||||
|
layer.effect: PressEffect { source: animatedSticker }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: staticSticker
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Theme.paddingLarge
|
||||||
|
}
|
||||||
|
source: file.path
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
autoTransform: true
|
||||||
|
asynchronous: true
|
||||||
|
visible: !queryResultItem.animating && opacity > 0
|
||||||
|
opacity: status === Image.Ready ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
layer.enabled: queryResultItem.highlighted
|
||||||
|
layer.effect: PressEffect { source: staticSticker }
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon {
|
||||||
|
source: "image://theme/icon-m-video"
|
||||||
|
width: Theme.iconSizeExtraSmall
|
||||||
|
height: width
|
||||||
|
visible: model.sticker.is_animated
|
||||||
|
highlighted: queryResultItem.highlighted || queryResultItem.animating
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
qml/components/inlineQueryResults/InlineQueryResultVenue.qml
Normal file
51
qml/components/inlineQueryResults/InlineQueryResultVenue.qml
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../../js/twemoji.js" as Emoji
|
||||||
|
|
||||||
|
InlineQueryResultDefaultBase {
|
||||||
|
id: queryResultItem
|
||||||
|
property string locationId
|
||||||
|
property var resultData: model.venue
|
||||||
|
|
||||||
|
title: Emoji.emojify(queryResultItem.resultData.title || (queryResultItem.resultData.location.latitude + ":" + queryResultItem.resultData.location.longitude), titleLable.font.pixelSize)
|
||||||
|
description: Emoji.emojify(queryResultItem.resultData.address || "", descriptionLabel.font.pixelSize)
|
||||||
|
extraText: Emoji.emojify(queryResultItem.resultData.type || "", extraTextLabel.font.pixelSize)
|
||||||
|
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onFileUpdated: {
|
||||||
|
if(fileInformation["@extra"] === queryResultItem.locationId) {
|
||||||
|
thumbnailFileInformation = fileInformation
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var dimensions = [ Math.round(thumbnail.width), Math.round(thumbnail.height)];
|
||||||
|
|
||||||
|
locationId = "location:" + resultData.location.latitude + ":" + resultData.location.longitude + ":" + dimensions[0] + ":" + dimensions[1];
|
||||||
|
|
||||||
|
tdLibWrapper.getMapThumbnailFile(chatId, resultData.location.latitude, resultData.location.longitude, dimensions[0], dimensions[1], locationId);
|
||||||
|
}
|
||||||
|
}
|
25
qml/components/inlineQueryResults/InlineQueryResultVideo.qml
Normal file
25
qml/components/inlineQueryResults/InlineQueryResultVideo.qml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.6
|
||||||
|
|
||||||
|
InlineQueryResultAnimation {
|
||||||
|
isAnimation: false
|
||||||
|
animationKey: "video"
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.6
|
||||||
|
|
||||||
|
InlineQueryResultAudio {
|
||||||
|
|
||||||
|
}
|
|
@ -145,6 +145,10 @@ function getMessageText(message, simple, currentUserId, ignoreEntities) {
|
||||||
return myself ? qsTr("sent a self-destructing video that is expired", "myself") : qsTr("sent a self-destructing video that is expired");
|
return myself ? qsTr("sent a self-destructing video that is expired", "myself") : qsTr("sent a self-destructing video that is expired");
|
||||||
case 'messageScreenshotTaken':
|
case 'messageScreenshotTaken':
|
||||||
return myself ? qsTr("created a screenshot in this chat", "myself") : qsTr("created a screenshot in this chat");
|
return myself ? qsTr("created a screenshot in this chat", "myself") : qsTr("created a screenshot in this chat");
|
||||||
|
case 'messageGame':
|
||||||
|
return simple ? (myself ? qsTr("sent a game", "myself") : qsTr("sent a game")) : "";
|
||||||
|
case 'messageGameScore':
|
||||||
|
return myself ? qsTr("scored %Ln points", "myself", message.content.score) : qsTr("scored %Ln points", "myself", message.content.score);
|
||||||
case 'messageUnsupported':
|
case 'messageUnsupported':
|
||||||
return myself ? qsTr("sent an unsupported message", "myself") : qsTr("sent an unsupported message");
|
return myself ? qsTr("sent an unsupported message", "myself") : qsTr("sent an unsupported message");
|
||||||
default:
|
default:
|
||||||
|
@ -361,16 +365,16 @@ function handleLink(link) {
|
||||||
if (typeof userInformation.id === "undefined") {
|
if (typeof userInformation.id === "undefined") {
|
||||||
appNotification.show(qsTr("Unable to find user %1").arg(userName));
|
appNotification.show(qsTr("Unable to find user %1").arg(userName));
|
||||||
} else {
|
} else {
|
||||||
tdLibWrapper.createPrivateChat(userInformation.id);
|
tdLibWrapper.createPrivateChat(userInformation.id, "openDirectly");
|
||||||
}
|
}
|
||||||
} else if (link.indexOf("userId://") === 0) {
|
} else if (link.indexOf("userId://") === 0) {
|
||||||
tdLibWrapper.createPrivateChat(link.substring(9));
|
tdLibWrapper.createPrivateChat(link.substring(9), "openDirectly");
|
||||||
} else if (link.indexOf("tg://") === 0) {
|
} else if (link.indexOf("tg://") === 0) {
|
||||||
Debug.log("Special TG link: ", link);
|
Debug.log("Special TG link: ", link);
|
||||||
if (link.indexOf("tg://join?invite=") === 0) {
|
if (link.indexOf("tg://join?invite=") === 0) {
|
||||||
tdLibWrapper.joinChatByInviteLink(tMePrefix + "joinchat/" + link.substring(17));
|
tdLibWrapper.joinChatByInviteLink(tMePrefix + "joinchat/" + link.substring(17));
|
||||||
} else if (link.indexOf("tg://resolve?domain=") === 0) {
|
} else if (link.indexOf("tg://resolve?domain=") === 0) {
|
||||||
tdLibWrapper.searchPublicChat(link.substring(20));
|
tdLibWrapper.searchPublicChat(link.substring(20), true);
|
||||||
}
|
}
|
||||||
} else if (link.indexOf("botCommand://") === 0) { // this gets returned to send on ChatPage
|
} else if (link.indexOf("botCommand://") === 0) { // this gets returned to send on ChatPage
|
||||||
return link.substring(13);
|
return link.substring(13);
|
||||||
|
@ -383,7 +387,7 @@ function handleLink(link) {
|
||||||
// Fail with nice error message if it doesn't work
|
// Fail with nice error message if it doesn't work
|
||||||
} else {
|
} else {
|
||||||
Debug.log("Search public chat: ", link.substring(tMePrefix.length));
|
Debug.log("Search public chat: ", link.substring(tMePrefix.length));
|
||||||
tdLibWrapper.searchPublicChat(link.substring(tMePrefix.length));
|
tdLibWrapper.searchPublicChat(link.substring(tMePrefix.length), true);
|
||||||
// Check responses for updateBasicGroup or updateSupergroup
|
// Check responses for updateBasicGroup or updateSupergroup
|
||||||
// Fire createBasicGroupChat or createSupergroupChat
|
// Fire createBasicGroupChat or createSupergroupChat
|
||||||
// Do the necessary stuff to open the chat
|
// Do the necessary stuff to open the chat
|
||||||
|
@ -440,8 +444,10 @@ function getMessagesArrayText(messages) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleErrorMessage(code, message) {
|
function handleErrorMessage(code, message) {
|
||||||
if (code === 404) {
|
if (code === 404 || (code === 400 && message === "USERNAME_INVALID")) {
|
||||||
// Silently ignore 404 Not Found messages (occur sometimes, without clear context...)
|
// Silently ignore
|
||||||
|
// - 404 Not Found messages (occur sometimes, without clear context...)
|
||||||
|
// - searchPublicChat messages for "invalid" inline queries
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message === "USER_ALREADY_PARTICIPANT") {
|
if (message === "USER_ALREADY_PARTICIPANT") {
|
||||||
|
|
|
@ -38,6 +38,7 @@ Page {
|
||||||
property bool isBasicGroup: false
|
property bool isBasicGroup: false
|
||||||
property bool isSuperGroup: false
|
property bool isSuperGroup: false
|
||||||
property bool isChannel: false
|
property bool isChannel: false
|
||||||
|
readonly property bool canGetMembers: ("can_get_members" in groupFullInformation) && groupFullInformation.can_get_members
|
||||||
|
|
||||||
property string chatPartnerGroupId
|
property string chatPartnerGroupId
|
||||||
|
|
||||||
|
@ -69,8 +70,6 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: mainContentLoader
|
id: mainContentLoader
|
||||||
active: false
|
active: false
|
||||||
|
|
|
@ -45,6 +45,7 @@ Page {
|
||||||
property bool isSuperGroup: false;
|
property bool isSuperGroup: false;
|
||||||
property bool isChannel: false;
|
property bool isChannel: false;
|
||||||
property var chatPartnerInformation;
|
property var chatPartnerInformation;
|
||||||
|
property var botInformation;
|
||||||
property var chatGroupInformation;
|
property var chatGroupInformation;
|
||||||
property int chatOnlineMemberCount: 0;
|
property int chatOnlineMemberCount: 0;
|
||||||
property var emojiProposals;
|
property var emojiProposals;
|
||||||
|
@ -59,6 +60,8 @@ 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_messages")
|
||||||
|
property bool doSendBotStartMessage
|
||||||
|
property string sendBotStartMessageParameter
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
|
@ -154,6 +157,9 @@ Page {
|
||||||
if (isSecretChat) {
|
if (isSecretChat) {
|
||||||
tdLibWrapper.getSecretChat(chatInformation.type.secret_chat_id);
|
tdLibWrapper.getSecretChat(chatInformation.type.secret_chat_id);
|
||||||
}
|
}
|
||||||
|
if(chatPartnerInformation.type["@type"] === "userTypeBot") {
|
||||||
|
tdLibWrapper.getUserFullInfo(chatPartnerInformation.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (isBasicGroup) {
|
else if (isBasicGroup) {
|
||||||
chatGroupInformation = tdLibWrapper.getBasicGroup(chatInformation.type.basic_group_id);
|
chatGroupInformation = tdLibWrapper.getBasicGroup(chatInformation.type.basic_group_id);
|
||||||
|
@ -172,6 +178,7 @@ Page {
|
||||||
}
|
}
|
||||||
tdLibWrapper.getChatPinnedMessage(chatInformation.id);
|
tdLibWrapper.getChatPinnedMessage(chatInformation.id);
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false);
|
tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) {
|
function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) {
|
||||||
|
@ -207,14 +214,13 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAttachmentPreviewRow() {
|
function clearAttachmentPreviewRow() {
|
||||||
attachmentPreviewRow.visible = false;
|
|
||||||
attachmentPreviewRow.isPicture = false;
|
attachmentPreviewRow.isPicture = false;
|
||||||
attachmentPreviewRow.isVideo = false;
|
attachmentPreviewRow.isVideo = false;
|
||||||
attachmentPreviewRow.isDocument = false;
|
attachmentPreviewRow.isDocument = false;
|
||||||
attachmentPreviewRow.isVoiceNote = false;
|
attachmentPreviewRow.isVoiceNote = false;
|
||||||
attachmentPreviewRow.isLocation = false;
|
attachmentPreviewRow.isLocation = false;
|
||||||
attachmentPreviewRow.fileProperties = {};
|
attachmentPreviewRow.fileProperties = null;
|
||||||
attachmentPreviewRow.locationData = {};
|
attachmentPreviewRow.locationData = null;
|
||||||
attachmentPreviewRow.attachmentDescription = "";
|
attachmentPreviewRow.attachmentDescription = "";
|
||||||
fernschreiberUtils.stopGeoLocationUpdates();
|
fernschreiberUtils.stopGeoLocationUpdates();
|
||||||
}
|
}
|
||||||
|
@ -286,6 +292,10 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageTextReplacement(text, cursorPosition) {
|
function handleMessageTextReplacement(text, cursorPosition) {
|
||||||
|
if(!newMessageTextField.focus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var wordBoundaries = getWordBoundaries(text, cursorPosition);
|
var wordBoundaries = getWordBoundaries(text, cursorPosition);
|
||||||
|
|
||||||
var currentWord = text.substring(wordBoundaries.beginIndex, wordBoundaries.endIndex);
|
var currentWord = text.substring(wordBoundaries.beginIndex, wordBoundaries.endIndex);
|
||||||
|
@ -300,6 +310,7 @@ Page {
|
||||||
} else {
|
} else {
|
||||||
knownUsersRepeater.model = undefined;
|
knownUsersRepeater.model = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceMessageText(text, cursorPosition, newText) {
|
function replaceMessageText(text, cursorPosition, newText) {
|
||||||
|
@ -310,6 +321,19 @@ Page {
|
||||||
newMessageTextField.cursorPosition = newIndex;
|
newMessageTextField.cursorPosition = newIndex;
|
||||||
lostFocusTimer.start();
|
lostFocusTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMessageText(text, doSend) {
|
||||||
|
if(doSend) {
|
||||||
|
tdLibWrapper.sendTextMessage(chatInformation.id, text, "0");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newMessageTextField.text = text
|
||||||
|
newMessageTextField.cursorPosition = text.length
|
||||||
|
lostFocusTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function forwardMessages(fromChatId, messageIds) {
|
function forwardMessages(fromChatId, messageIds) {
|
||||||
forwardMessagesTimer.fromChatId = fromChatId;
|
forwardMessagesTimer.fromChatId = fromChatId;
|
||||||
forwardMessagesTimer.messageIds = messageIds;
|
forwardMessagesTimer.messageIds = messageIds;
|
||||||
|
@ -402,6 +426,17 @@ Page {
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case PageStatus.Activating:
|
case PageStatus.Activating:
|
||||||
tdLibWrapper.openChat(chatInformation.id);
|
tdLibWrapper.openChat(chatInformation.id);
|
||||||
|
if(!chatPage.isInitialized) {
|
||||||
|
if(chatInformation.draft_message) {
|
||||||
|
if(chatInformation.draft_message && chatInformation.draft_message.input_message_text) {
|
||||||
|
newMessageTextField.text = chatInformation.draft_message.input_message_text.text.text;
|
||||||
|
if(chatInformation.draft_message.reply_to_message_id) {
|
||||||
|
tdLibWrapper.getMessage(chatInformation.id, chatInformation.draft_message.reply_to_message_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PageStatus.Active:
|
case PageStatus.Active:
|
||||||
if (!chatPage.isInitialized) {
|
if (!chatPage.isInitialized) {
|
||||||
|
@ -410,13 +445,8 @@ Page {
|
||||||
pageStack.pushAttached(Qt.resolvedUrl("ChatInformationPage.qml"), { "chatInformation" : chatInformation, "privateChatUserInformation": chatPartnerInformation, "groupInformation": chatGroupInformation, "chatOnlineMemberCount": chatOnlineMemberCount});
|
pageStack.pushAttached(Qt.resolvedUrl("ChatInformationPage.qml"), { "chatInformation" : chatInformation, "privateChatUserInformation": chatPartnerInformation, "groupInformation": chatGroupInformation, "chatOnlineMemberCount": chatOnlineMemberCount});
|
||||||
chatPage.isInitialized = true;
|
chatPage.isInitialized = true;
|
||||||
|
|
||||||
if(chatInformation.draft_message) {
|
if(doSendBotStartMessage) {
|
||||||
if(chatInformation.draft_message && chatInformation.draft_message.input_message_text) {
|
tdLibWrapper.sendBotStartMessage(chatInformation.id, chatInformation.id, sendBotStartMessageParameter, "")
|
||||||
newMessageTextField.text = chatInformation.draft_message.input_message_text.text.text;
|
|
||||||
if(chatInformation.draft_message.reply_to_message_id) {
|
|
||||||
tdLibWrapper.getMessage(chatInformation.id, chatInformation.draft_message.reply_to_message_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -494,6 +524,25 @@ Page {
|
||||||
chatPage.isSecretChatReady = chatPage.secretChatDetails.state["@type"] === "secretChatStateReady";
|
chatPage.isSecretChatReady = chatPage.secretChatDetails.state["@type"] === "secretChatStateReady";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onCallbackQueryAnswer: {
|
||||||
|
if(text.length > 0) { // ignore bool "alert", just show as notification:
|
||||||
|
appNotification.show(Emoji.emojify(text, Theme.fontSizeSmall));
|
||||||
|
}
|
||||||
|
if(url.length > 0) {
|
||||||
|
Functions.handleLink(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onUserFullInfoReceived: {
|
||||||
|
if(userFullInfo["@extra"] === chatPartnerInformation.id.toString()) {
|
||||||
|
chatPage.botInformation = userFullInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onUserFullInfoUpdated: {
|
||||||
|
|
||||||
|
if(userId === chatPartnerInformation.id) {
|
||||||
|
chatPage.botInformation = userFullInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -895,7 +944,7 @@ Page {
|
||||||
id: chatView
|
id: chatView
|
||||||
|
|
||||||
visible: !blurred
|
visible: !blurred
|
||||||
property bool blurred: messageOverlayLoader.item || stickerPickerLoader.item || voiceNoteOverlayLoader.item
|
property bool blurred: messageOverlayLoader.item || stickerPickerLoader.item || voiceNoteOverlayLoader.item || inlineQuery.hasOverlay
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
opacity: chatPage.loading ? 0 : 1
|
opacity: chatPage.loading ? 0 : 1
|
||||||
|
@ -975,6 +1024,38 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
model: chatModel
|
model: chatModel
|
||||||
|
header: Component {
|
||||||
|
Loader {
|
||||||
|
active: !!chatPage.botInformation
|
||||||
|
&& !!chatPage.botInformation.bot_info && chatPage.botInformation.bot_info.description.length > 0
|
||||||
|
asynchronous: true
|
||||||
|
width: chatView.width
|
||||||
|
sourceComponent: Component {
|
||||||
|
Label {
|
||||||
|
id: botInfoLabel
|
||||||
|
topPadding: Theme.paddingLarge
|
||||||
|
bottomPadding: Theme.paddingLarge
|
||||||
|
leftPadding: Theme.horizontalPageMargin
|
||||||
|
rightPadding: Theme.horizontalPageMargin
|
||||||
|
text: Emoji.emojify(chatPage.botInformation.bot_info.description, font.pixelSize)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.highlightColor
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
textFormat: Text.StyledText
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
onLinkActivated: {
|
||||||
|
var chatCommand = Functions.handleLink(link);
|
||||||
|
if(chatCommand) {
|
||||||
|
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linkColor: Theme.primaryColor
|
||||||
|
visible: (text !== "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
readonly property var contentComponentNames: ({
|
readonly property var contentComponentNames: ({
|
||||||
messageSticker: "StickerPreview",
|
messageSticker: "StickerPreview",
|
||||||
messagePhoto: "ImagePreview",
|
messagePhoto: "ImagePreview",
|
||||||
|
@ -986,7 +1067,8 @@ Page {
|
||||||
messageDocument: "DocumentPreview",
|
messageDocument: "DocumentPreview",
|
||||||
messageLocation: "LocationPreview",
|
messageLocation: "LocationPreview",
|
||||||
messageVenue: "LocationPreview",
|
messageVenue: "LocationPreview",
|
||||||
messagePoll: "PollPreview"
|
messagePoll: "PollPreview",
|
||||||
|
messageGame: "GamePreview"
|
||||||
})
|
})
|
||||||
function getContentComponentHeight(componentName, content, parentWidth) {
|
function getContentComponentHeight(componentName, content, parentWidth) {
|
||||||
switch(componentName) {
|
switch(componentName) {
|
||||||
|
@ -1002,6 +1084,8 @@ Page {
|
||||||
return Theme.itemSizeSmall;
|
return Theme.itemSizeSmall;
|
||||||
case "PollPreview":
|
case "PollPreview":
|
||||||
return Theme.itemSizeSmall * (4 + content.poll.options);
|
return Theme.itemSizeSmall * (4 + content.poll.options);
|
||||||
|
case "GamePreview":
|
||||||
|
return parentWidth * 0.66666666 + Theme.itemSizeLarge; // 2 / 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,6 +1098,7 @@ Page {
|
||||||
"messageChatJoinByLink",
|
"messageChatJoinByLink",
|
||||||
"messageChatSetTtl",
|
"messageChatSetTtl",
|
||||||
"messageChatUpgradeFrom",
|
"messageChatUpgradeFrom",
|
||||||
|
"messageGameScore",
|
||||||
"messageChatUpgradeTo",
|
"messageChatUpgradeTo",
|
||||||
"messageCustomServiceAction",
|
"messageCustomServiceAction",
|
||||||
"messagePinMessage",
|
"messagePinMessage",
|
||||||
|
@ -1168,12 +1253,17 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InlineQuery {
|
||||||
|
id: inlineQuery
|
||||||
|
textField: newMessageTextField
|
||||||
|
chatId: chatInformation.id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: newMessageColumn
|
id: newMessageColumn
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
topPadding: Theme.paddingSmall
|
topPadding: Theme.paddingSmall + inlineQuery.buttonPadding
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: height > 0
|
visible: height > 0
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
|
@ -1212,7 +1302,7 @@ Page {
|
||||||
property bool isNeeded: false
|
property bool isNeeded: false
|
||||||
width: chatPage.width
|
width: chatPage.width
|
||||||
x: -Theme.horizontalPageMargin
|
x: -Theme.horizontalPageMargin
|
||||||
height: isNeeded ? attachmentOptionsRow.height : 0
|
height: isNeeded && !inlineQuery.userNameIsValid ? attachmentOptionsRow.height : 0
|
||||||
Behavior on height { SmoothedAnimation { duration: 200 } }
|
Behavior on height { SmoothedAnimation { duration: 200 } }
|
||||||
visible: height > 0
|
visible: height > 0
|
||||||
contentHeight: attachmentOptionsRow.height
|
contentHeight: attachmentOptionsRow.height
|
||||||
|
@ -1252,7 +1342,6 @@ Page {
|
||||||
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
attachmentPreviewRow.isPicture = true;
|
attachmentPreviewRow.isPicture = true;
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1269,7 +1358,6 @@ Page {
|
||||||
Debug.log("Selected video: ", picker.selectedContentProperties.filePath );
|
Debug.log("Selected video: ", picker.selectedContentProperties.filePath );
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
attachmentPreviewRow.isVideo = true;
|
attachmentPreviewRow.isVideo = true;
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1387,6 @@ Page {
|
||||||
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
attachmentPreviewRow.isDocument = true;
|
attachmentPreviewRow.isDocument = true;
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1337,7 +1424,6 @@ Page {
|
||||||
attachmentOptionsFlickable.isNeeded = false;
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
attachmentPreviewRow.isLocation = true;
|
attachmentPreviewRow.isLocation = true;
|
||||||
attachmentPreviewRow.attachmentDescription = qsTr("Location: Obtaining position...");
|
attachmentPreviewRow.attachmentDescription = qsTr("Location: Obtaining position...");
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1348,7 +1434,7 @@ Page {
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: attachmentPreviewRow
|
id: attachmentPreviewRow
|
||||||
visible: false
|
visible: (!!locationData || !!fileProperties) && !inlineQuery.userNameIsValid
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
width: parent.width
|
width: parent.width
|
||||||
layoutDirection: Qt.RightToLeft
|
layoutDirection: Qt.RightToLeft
|
||||||
|
@ -1359,8 +1445,8 @@ Page {
|
||||||
property bool isDocument: false;
|
property bool isDocument: false;
|
||||||
property bool isVoiceNote: false;
|
property bool isVoiceNote: false;
|
||||||
property bool isLocation: false;
|
property bool isLocation: false;
|
||||||
property var locationData: ({});
|
property var locationData: null;
|
||||||
property var fileProperties:({});
|
property var fileProperties: null;
|
||||||
property string attachmentDescription: "";
|
property string attachmentDescription: "";
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -1390,15 +1476,15 @@ Page {
|
||||||
sourceSize.height: height
|
sourceSize.height: height
|
||||||
|
|
||||||
fillMode: Thumbnail.PreserveAspectCrop
|
fillMode: Thumbnail.PreserveAspectCrop
|
||||||
mimeType: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.mimeType || "" : ""
|
mimeType: !!attachmentPreviewRow.fileProperties ? attachmentPreviewRow.fileProperties.mimeType || "" : ""
|
||||||
source: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.url || "" : ""
|
source: !!attachmentPreviewRow.fileProperties ? attachmentPreviewRow.fileProperties.url || "" : ""
|
||||||
visible: attachmentPreviewRow.isPicture || attachmentPreviewRow.isVideo
|
visible: attachmentPreviewRow.isPicture || attachmentPreviewRow.isVideo
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: attachmentPreviewText
|
id: attachmentPreviewText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
text: ( attachmentPreviewRow.isVoiceNote || attachmentPreviewRow.isLocation ) ? attachmentPreviewRow.attachmentDescription : ( typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.fileName || "" : "" );
|
text: ( attachmentPreviewRow.isVoiceNote || attachmentPreviewRow.isLocation ) ? attachmentPreviewRow.attachmentDescription : ( !!attachmentPreviewRow.fileProperties ? attachmentPreviewRow.fileProperties.fileName || "" : "" );
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
|
@ -1491,9 +1577,11 @@ Page {
|
||||||
id: atMentionColumn
|
id: atMentionColumn
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: knownUsersRepeater.count > 0 ? true : false
|
visible: opacity > 0
|
||||||
opacity: knownUsersRepeater.count > 0 ? 1 : 0
|
opacity: knownUsersRepeater.count > 0 ? 1 : 0
|
||||||
Behavior on opacity { NumberAnimation {} }
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
height: knownUsersRepeater.count > 0 ? childrenRect.height : 0
|
||||||
|
Behavior on height { SmoothedAnimation { duration: 200 } }
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
|
@ -1598,7 +1686,7 @@ Page {
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
id: newMessageTextField
|
id: newMessageTextField
|
||||||
width: parent.width - attachmentIconButton.width - (newMessageSendButton.visible ? newMessageSendButton.width : 0)
|
width: parent.width - (attachmentIconButton.visible ? attachmentIconButton.width : 0) - (newMessageSendButton.visible ? newMessageSendButton.width : 0) - (cancelInlineQueryButton.visible ? cancelInlineQueryButton.width : 0)
|
||||||
height: Math.min(chatContainer.height / 3, implicitHeight)
|
height: Math.min(chatContainer.height / 3, implicitHeight)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
@ -1617,7 +1705,7 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterKey.enabled: !appSettings.sendByEnter || text.length
|
EnterKey.enabled: !inlineQuery.userNameIsValid && (!appSettings.sendByEnter || text.length)
|
||||||
EnterKey.iconSource: appSettings.sendByEnter ? "image://theme/icon-m-chat" : "image://theme/icon-m-enter"
|
EnterKey.iconSource: appSettings.sendByEnter ? "image://theme/icon-m-chat" : "image://theme/icon-m-enter"
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
|
@ -1632,6 +1720,7 @@ Page {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Theme.paddingSmall
|
anchors.bottomMargin: Theme.paddingSmall
|
||||||
enabled: !attachmentPreviewRow.visible
|
enabled: !attachmentPreviewRow.visible
|
||||||
|
visible: !inlineQuery.userNameIsValid
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (attachmentOptionsFlickable.isNeeded) {
|
if (attachmentOptionsFlickable.isNeeded) {
|
||||||
attachmentOptionsFlickable.isNeeded = false;
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
@ -1648,7 +1737,7 @@ Page {
|
||||||
icon.source: "image://theme/icon-m-chat"
|
icon.source: "image://theme/icon-m-chat"
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Theme.paddingSmall
|
anchors.bottomMargin: Theme.paddingSmall
|
||||||
visible: !appSettings.sendByEnter || attachmentPreviewRow.visible
|
visible: !inlineQuery.userNameIsValid && (!appSettings.sendByEnter || attachmentPreviewRow.visible)
|
||||||
enabled: false
|
enabled: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendMessage();
|
sendMessage();
|
||||||
|
@ -1658,6 +1747,42 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: cancelInlineQueryButton.width
|
||||||
|
height: cancelInlineQueryButton.height
|
||||||
|
visible: inlineQuery.userNameIsValid
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: Theme.paddingSmall
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: cancelInlineQueryButton
|
||||||
|
icon.source: "image://theme/icon-m-cancel"
|
||||||
|
visible: parent.visible
|
||||||
|
opacity: inlineQuery.isLoading ? 0.2 : 1
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
onClicked: {
|
||||||
|
if(inlineQuery.query !== "") {
|
||||||
|
newMessageTextField.text = "@" + inlineQuery.userName + " "
|
||||||
|
newMessageTextField.cursorPosition = newMessageTextField.text.length
|
||||||
|
lostFocusTimer.start();
|
||||||
|
} else {
|
||||||
|
newMessageTextField.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPressAndHold: {
|
||||||
|
newMessageTextField.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
size: BusyIndicatorSize.Small
|
||||||
|
anchors.centerIn: parent
|
||||||
|
running: inlineQuery.isLoading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ Dialog {
|
||||||
case "forwardMessages":
|
case "forwardMessages":
|
||||||
acceptDestinationInstance.forwardMessages(payload.fromChatId, payload.messageIds)
|
acceptDestinationInstance.forwardMessages(payload.fromChatId, payload.messageIds)
|
||||||
break;
|
break;
|
||||||
|
case "fillTextArea": // ReplyMarkupButtons: inlineKeyboardButtonTypeSwitchInline
|
||||||
|
acceptDestinationInstance.setMessageText(payload.text)
|
||||||
|
break;
|
||||||
// future uses of chat selection can be processed here
|
// future uses of chat selection can be processed here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +78,7 @@ Dialog {
|
||||||
QtObject {
|
QtObject {
|
||||||
property bool visible: false
|
property bool visible: false
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if(chatSelectionPage.state === "forwardMessages") {
|
if(chatSelectionPage.state === "forwardMessages" || chatSelectionPage.state === "fillTextArea" ) {
|
||||||
var chatType = display.type['@type']
|
var chatType = display.type['@type']
|
||||||
var chatGroupInformation
|
var chatGroupInformation
|
||||||
if(chatType === "chatTypePrivate" || chatType === "chatTypeSecret") {
|
if(chatType === "chatTypePrivate" || chatType === "chatTypeSecret") {
|
||||||
|
@ -126,6 +129,7 @@ Dialog {
|
||||||
var chat = tdLibWrapper.getChat(display.id);
|
var chat = tdLibWrapper.getChat(display.id);
|
||||||
switch(chatSelectionPage.state) {
|
switch(chatSelectionPage.state) {
|
||||||
case "forwardMessages":
|
case "forwardMessages":
|
||||||
|
case "fillTextArea":
|
||||||
chatSelectionPage.acceptDestinationProperties = { "chatInformation" : chat};
|
chatSelectionPage.acceptDestinationProperties = { "chatInformation" : chat};
|
||||||
chatSelectionPage.acceptDestination = Qt.resolvedUrl("../pages/ChatPage.qml");
|
chatSelectionPage.acceptDestination = Qt.resolvedUrl("../pages/ChatPage.qml");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,6 +18,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 "../components"
|
import "../components"
|
||||||
import "../js/functions.js" as Functions
|
import "../js/functions.js" as Functions
|
||||||
import "../js/debug.js" as Debug
|
import "../js/debug.js" as Debug
|
||||||
|
@ -28,9 +29,7 @@ Page {
|
||||||
backNavigation: !imageOnly
|
backNavigation: !imageOnly
|
||||||
|
|
||||||
property var photoData;
|
property var photoData;
|
||||||
property var pictureFileInformation;
|
|
||||||
|
|
||||||
property string imageUrl;
|
|
||||||
property int imageWidth;
|
property int imageWidth;
|
||||||
property int imageHeight;
|
property int imageHeight;
|
||||||
|
|
||||||
|
@ -47,40 +46,31 @@ Page {
|
||||||
property bool imageOnly
|
property bool imageOnly
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
updatePicture();
|
if (photoData) {
|
||||||
}
|
|
||||||
|
|
||||||
function updatePicture() {
|
|
||||||
if (typeof photoData === "object") {
|
|
||||||
// Check first which size fits best...
|
// Check first which size fits best...
|
||||||
|
var photo
|
||||||
for (var i = 0; i < photoData.sizes.length; i++) {
|
for (var i = 0; i < photoData.sizes.length; i++) {
|
||||||
imagePage.imageWidth = photoData.sizes[i].width;
|
imagePage.imageWidth = photoData.sizes[i].width;
|
||||||
imagePage.imageHeight = photoData.sizes[i].height;
|
imagePage.imageHeight = photoData.sizes[i].height;
|
||||||
imagePage.pictureFileInformation = photoData.sizes[i].photo;
|
photo = photoData.sizes[i].photo
|
||||||
if (photoData.sizes[i].width >= imagePage.width) {
|
if (photoData.sizes[i].width >= imagePage.width) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (photo) {
|
||||||
|
imageFile.fileInformation = photo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (imagePage.pictureFileInformation.local.is_downloading_completed) {
|
TDLibFile {
|
||||||
imagePage.imageUrl = imagePage.pictureFileInformation.local.path;
|
id: imageFile
|
||||||
} else {
|
tdlib: tdLibWrapper
|
||||||
tdLibWrapper.downloadFile(imagePage.pictureFileInformation.id);
|
autoLoad: true
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onFileUpdated: {
|
|
||||||
if (fileId === imagePage.pictureFileInformation.id) {
|
|
||||||
Debug.log("File updated, completed? ", fileInformation.local.is_downloading_completed);
|
|
||||||
if (fileInformation.local.is_downloading_completed) {
|
|
||||||
imagePage.pictureFileInformation = fileInformation;
|
|
||||||
imagePage.imageUrl = fileInformation.local.path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onCopyToDownloadsSuccessful: {
|
onCopyToDownloadsSuccessful: {
|
||||||
appNotification.show(qsTr("Download of %1 successful.").arg(fileName), filePath);
|
appNotification.show(qsTr("Download of %1 successful.").arg(fileName), filePath);
|
||||||
}
|
}
|
||||||
|
@ -96,11 +86,11 @@ Page {
|
||||||
interactive: !imageOnly
|
interactive: !imageOnly
|
||||||
|
|
||||||
PullDownMenu {
|
PullDownMenu {
|
||||||
visible: !imageOnly && imageUrl
|
visible: !imageOnly && imageFile.isDownloadingCompleted && imageFile.path
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Download Picture")
|
text: qsTr("Download Picture")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.copyFileToDownloads(imagePage.imageUrl);
|
tdLibWrapper.copyFileToDownloads(imageFile.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +124,7 @@ Page {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: singleImage
|
id: singleImage
|
||||||
source: imageUrl
|
source: imageFile.isDownloadingCompleted ? imageFile.path : ""
|
||||||
width: imagePage.imageWidth * imagePage.sizingFactor
|
width: imagePage.imageWidth * imagePage.sizingFactor
|
||||||
height: imagePage.imageHeight * imagePage.sizingFactor
|
height: imagePage.imageHeight * imagePage.sizingFactor
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
|
@ -220,7 +220,7 @@ Page {
|
||||||
icon.source: "image://theme/icon-m-chat"
|
icon.source: "image://theme/icon-m-chat"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(display.id);
|
tdLibWrapper.createPrivateChat(display.id, "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ Page {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createPrivateChat(display.id);
|
tdLibWrapper.createPrivateChat(display.id, "openDirectly");
|
||||||
}
|
}
|
||||||
onPressed: {
|
onPressed: {
|
||||||
privateChatHighlightBackground.visible = true;
|
privateChatHighlightBackground.visible = true;
|
||||||
|
@ -295,7 +295,7 @@ Page {
|
||||||
icon.source: "image://theme/icon-m-device-lock"
|
icon.source: "image://theme/icon-m-device-lock"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createNewSecretChat(display.id);
|
tdLibWrapper.createNewSecretChat(display.id, "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ Page {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.createNewSecretChat(display.id);
|
tdLibWrapper.createNewSecretChat(display.id, "openDirectly");
|
||||||
}
|
}
|
||||||
onPressed: {
|
onPressed: {
|
||||||
secretChatHighlightBackground.visible = true;
|
secretChatHighlightBackground.visible = true;
|
||||||
|
|
|
@ -228,10 +228,17 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onChatReceived: {
|
onChatReceived: {
|
||||||
if(chat["@extra"] === "openDirectly") {
|
var openAndSendStartToBot = chat["@extra"].indexOf("openAndSendStartToBot:") === 0
|
||||||
|
if(chat["@extra"] === "openDirectly" || openAndSendStartToBot && chat.type["@type"] === "chatTypePrivate") {
|
||||||
pageStack.pop(overviewPage, PageStackAction.Immediate)
|
pageStack.pop(overviewPage, PageStackAction.Immediate)
|
||||||
// if we get a new chat (no messages?), we can not use the provided data
|
// if we get a new chat (no messages?), we can not use the provided data
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/ChatPage.qml"), { "chatInformation" : tdLibWrapper.getChat(chat.id) });
|
var chatinfo = tdLibWrapper.getChat(chat.id);
|
||||||
|
var options = { "chatInformation" : chatinfo }
|
||||||
|
if(openAndSendStartToBot) {
|
||||||
|
options.doSendBotStartMessage = true;
|
||||||
|
options.sendBotStartMessageParameter = chat["@extra"].substring(22);
|
||||||
|
}
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/ChatPage.qml"), options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onErrorReceived: {
|
onErrorReceived: {
|
||||||
|
|
|
@ -159,6 +159,20 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SectionHeader {
|
||||||
|
text: qsTr("Privacy")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSwitch {
|
||||||
|
checked: appSettings.allowInlineBotLocationAccess
|
||||||
|
text: qsTr("Allow sending Location to inline bots")
|
||||||
|
description: qsTr("Some inline bots request location data when using them")
|
||||||
|
automaticCheck: false
|
||||||
|
onClicked: {
|
||||||
|
appSettings.allowInlineBotLocationAccess = !checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SectionHeader {
|
SectionHeader {
|
||||||
text: qsTr("Storage")
|
text: qsTr("Storage")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace {
|
||||||
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
||||||
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
||||||
const QString KEY_STORAGE_OPTIMIZER("storageOptimizer");
|
const QString KEY_STORAGE_OPTIMIZER("storageOptimizer");
|
||||||
|
const QString KEY_INLINEBOT_LOCATION_ACCESS("allowInlineBotLocationAccess");
|
||||||
const QString KEY_REMAINING_INTERACTION_HINTS("remainingInteractionHints");
|
const QString KEY_REMAINING_INTERACTION_HINTS("remainingInteractionHints");
|
||||||
const QString KEY_ONLINE_ONLY_MODE("onlineOnlyMode");
|
const QString KEY_ONLINE_ONLY_MODE("onlineOnlyMode");
|
||||||
}
|
}
|
||||||
|
@ -149,6 +150,21 @@ void AppSettings::setStorageOptimizer(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppSettings::allowInlineBotLocationAccess() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_INLINEBOT_LOCATION_ACCESS, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setAllowInlineBotLocationAccess(bool enable)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (allowInlineBotLocationAccess() != enable) {
|
||||||
|
LOG(KEY_INLINEBOT_LOCATION_ACCESS << enable);
|
||||||
|
settings.setValue(KEY_INLINEBOT_LOCATION_ACCESS, enable);
|
||||||
|
emit allowInlineBotLocationAccessChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int AppSettings::remainingInteractionHints() const
|
int AppSettings::remainingInteractionHints() const
|
||||||
{
|
{
|
||||||
return settings.value(KEY_REMAINING_INTERACTION_HINTS, 3).toInt();
|
return settings.value(KEY_REMAINING_INTERACTION_HINTS, 3).toInt();
|
||||||
|
|
|
@ -31,6 +31,7 @@ class AppSettings : public QObject {
|
||||||
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
||||||
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
||||||
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(int remainingInteractionHints READ remainingInteractionHints WRITE setRemainingInteractionHints NOTIFY remainingInteractionHintsChanged)
|
Q_PROPERTY(int remainingInteractionHints READ remainingInteractionHints WRITE setRemainingInteractionHints NOTIFY remainingInteractionHintsChanged)
|
||||||
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
|
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
|
||||||
|
|
||||||
|
@ -69,6 +70,9 @@ public:
|
||||||
bool storageOptimizer() const;
|
bool storageOptimizer() const;
|
||||||
void setStorageOptimizer(bool enable);
|
void setStorageOptimizer(bool enable);
|
||||||
|
|
||||||
|
bool allowInlineBotLocationAccess() const;
|
||||||
|
void setAllowInlineBotLocationAccess(bool enable);
|
||||||
|
|
||||||
int remainingInteractionHints() const;
|
int remainingInteractionHints() const;
|
||||||
void setRemainingInteractionHints(int remainingHints);
|
void setRemainingInteractionHints(int remainingHints);
|
||||||
|
|
||||||
|
@ -84,6 +88,7 @@ signals:
|
||||||
void notificationTurnsDisplayOnChanged();
|
void notificationTurnsDisplayOnChanged();
|
||||||
void notificationFeedbackChanged();
|
void notificationFeedbackChanged();
|
||||||
void storageOptimizerChanged();
|
void storageOptimizerChanged();
|
||||||
|
void allowInlineBotLocationAccessChanged();
|
||||||
void remainingInteractionHintsChanged();
|
void remainingInteractionHintsChanged();
|
||||||
void onlineOnlyModeChanged();
|
void onlineOnlyModeChanged();
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,13 @@ QString FernschreiberUtils::getMessageShortText(TDLibWrapper *tdLibWrapper, cons
|
||||||
if (contentType == "messageScreenshotTaken") {
|
if (contentType == "messageScreenshotTaken") {
|
||||||
return myself ? tr("created a screenshot in this chat", "myself") : tr("created a screenshot in this chat");
|
return myself ? tr("created a screenshot in this chat", "myself") : tr("created a screenshot in this chat");
|
||||||
}
|
}
|
||||||
|
if (contentType == "messageGameScore") {
|
||||||
|
qint32 score = messageContent.value("score").toInt();
|
||||||
|
return myself ? tr("scored %Ln points", "myself", score) : tr("scored %Ln points", "", score);
|
||||||
|
}
|
||||||
|
if (contentType == "messageGame") {
|
||||||
|
return myself ? tr("sent a game", "myself") : tr("sent a game");
|
||||||
|
}
|
||||||
if (contentType == "messageUnsupported") {
|
if (contentType == "messageUnsupported") {
|
||||||
return myself ? tr("sent an unsupported message", "myself") : tr("sent an unsupported message");
|
return myself ? tr("sent an unsupported message", "myself") : tr("sent an unsupported message");
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,8 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("updateMessageEdited", &TDLibReceiver::processUpdateMessageEdited);
|
handlers.insert("updateMessageEdited", &TDLibReceiver::processUpdateMessageEdited);
|
||||||
handlers.insert("updateChatIsMarkedAsUnread", &TDLibReceiver::processUpdateChatIsMarkedAsUnread);
|
handlers.insert("updateChatIsMarkedAsUnread", &TDLibReceiver::processUpdateChatIsMarkedAsUnread);
|
||||||
handlers.insert("updateChatDraftMessage", &TDLibReceiver::processUpdateChatDraftMessage);
|
handlers.insert("updateChatDraftMessage", &TDLibReceiver::processUpdateChatDraftMessage);
|
||||||
|
handlers.insert("inlineQueryResults", &TDLibReceiver::processInlineQueryResults);
|
||||||
|
handlers.insert("callbackQueryAnswer", &TDLibReceiver::processCallbackQueryAnswer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::setActive(bool active)
|
void TDLibReceiver::setActive(bool active)
|
||||||
|
@ -596,3 +598,16 @@ void TDLibReceiver::processUpdateChatDraftMessage(const QVariantMap &receivedInf
|
||||||
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(), receivedInformation.value("draft_message").toMap(), findChatPositionOrder(receivedInformation.value(POSITIONS).toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processInlineQueryResults(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
LOG("Inline Query results");
|
||||||
|
emit inlineQueryResults(receivedInformation.value("inline_query_id").toString(), receivedInformation.value("next_offset").toString(), receivedInformation.value("results").toList(), receivedInformation.value("switch_pm_text").toString(), receivedInformation.value("switch_pm_parameter").toString(), receivedInformation.value(EXTRA).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processCallbackQueryAnswer(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG("Callback Query answer");
|
||||||
|
emit callbackQueryAnswer(receivedInformation.value(TEXT).toString(), receivedInformation.value("alert").toBool(), receivedInformation.value("url").toString());
|
||||||
|
}
|
||||||
|
|
|
@ -93,6 +93,8 @@ signals:
|
||||||
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
||||||
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
||||||
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
||||||
|
void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra);
|
||||||
|
void callbackQueryAnswer(const QString &text, bool alert, const QString &url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
||||||
|
@ -160,6 +162,8 @@ private:
|
||||||
void processImportedContacts(const QVariantMap &receivedInformation);
|
void processImportedContacts(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatIsMarkedAsUnread(const QVariantMap &receivedInformation);
|
void processUpdateChatIsMarkedAsUnread(const QVariantMap &receivedInformation);
|
||||||
void processUpdateChatDraftMessage(const QVariantMap &receivedInformation);
|
void processUpdateChatDraftMessage(const QVariantMap &receivedInformation);
|
||||||
|
void processInlineQueryResults(const QVariantMap &receivedInformation);
|
||||||
|
void processCallbackQueryAnswer(const QVariantMap &receivedInformation);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TDLIBRECEIVER_H
|
#endif // TDLIBRECEIVER_H
|
||||||
|
|
|
@ -156,6 +156,9 @@ void TDLibWrapper::initializeTDLibReciever() {
|
||||||
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)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)));
|
connect(this->tdLibReceiver, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
connect(this->tdLibReceiver, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString)), this, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(callbackQueryAnswer(QString, bool, QString)), this, SIGNAL(callbackQueryAnswer(QString, bool, QString)));
|
||||||
|
|
||||||
this->tdLibReceiver->start();
|
this->tdLibReceiver->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,13 +706,12 @@ void TDLibWrapper::deleteMessages(const QString &chatId, const QVariantList mess
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height)
|
void TDLibWrapper::getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height, const QString &extra)
|
||||||
{
|
{
|
||||||
LOG("Getting Map Thumbnail File" << chatId);
|
LOG("Getting Map Thumbnail File" << chatId);
|
||||||
QVariantMap location;
|
QVariantMap location;
|
||||||
location.insert("latitude", latitude);
|
location.insert("latitude", latitude);
|
||||||
location.insert("longitude", longitude);
|
location.insert("longitude", longitude);
|
||||||
|
|
||||||
// ensure dimensions are in bounds (16 - 1024)
|
// ensure dimensions are in bounds (16 - 1024)
|
||||||
int boundsWidth = std::min(std::max(width, 16), 1024);
|
int boundsWidth = std::min(std::max(width, 16), 1024);
|
||||||
int boundsHeight = std::min(std::max(height, 16), 1024);
|
int boundsHeight = std::min(std::max(height, 16), 1024);
|
||||||
|
@ -722,6 +724,7 @@ void TDLibWrapper::getMapThumbnailFile(const QString &chatId, double latitude, d
|
||||||
requestObject.insert("height", boundsHeight);
|
requestObject.insert("height", boundsHeight);
|
||||||
requestObject.insert("scale", 1); // 1-3
|
requestObject.insert("scale", 1); // 1-3
|
||||||
requestObject.insert(CHAT_ID, chatId);
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
requestObject.insert(_EXTRA, extra);
|
||||||
|
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
@ -787,43 +790,43 @@ void TDLibWrapper::getUserFullInfo(const QString &userId)
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::createPrivateChat(const QString &userId)
|
void TDLibWrapper::createPrivateChat(const QString &userId, const QString &extra)
|
||||||
{
|
{
|
||||||
LOG("Creating Private Chat");
|
LOG("Creating Private Chat");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "createPrivateChat");
|
requestObject.insert(_TYPE, "createPrivateChat");
|
||||||
requestObject.insert("user_id", userId);
|
requestObject.insert("user_id", userId);
|
||||||
requestObject.insert(_EXTRA, "openDirectly"); //gets matched in qml
|
requestObject.insert(_EXTRA, extra); //"openDirectly"/"openAndSendStartToBot:[optional parameter]" gets matched in qml
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::createNewSecretChat(const QString &userId)
|
void TDLibWrapper::createNewSecretChat(const QString &userId, const QString &extra)
|
||||||
{
|
{
|
||||||
LOG("Creating new secret chat");
|
LOG("Creating new secret chat");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "createNewSecretChat");
|
requestObject.insert(_TYPE, "createNewSecretChat");
|
||||||
requestObject.insert("user_id", userId);
|
requestObject.insert("user_id", userId);
|
||||||
requestObject.insert(_EXTRA, "openDirectly"); //gets matched in qml
|
requestObject.insert(_EXTRA, extra); //"openDirectly" gets matched in qml
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::createSupergroupChat(const QString &supergroupId)
|
void TDLibWrapper::createSupergroupChat(const QString &supergroupId, const QString &extra)
|
||||||
{
|
{
|
||||||
LOG("Creating Supergroup Chat");
|
LOG("Creating Supergroup Chat");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "createSupergroupChat");
|
requestObject.insert(_TYPE, "createSupergroupChat");
|
||||||
requestObject.insert("supergroup_id", supergroupId);
|
requestObject.insert("supergroup_id", supergroupId);
|
||||||
requestObject.insert(_EXTRA, "openDirectly"); //gets matched in qml
|
requestObject.insert(_EXTRA, extra); //"openDirectly" gets matched in qml
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::createBasicGroupChat(const QString &basicGroupId)
|
void TDLibWrapper::createBasicGroupChat(const QString &basicGroupId, const QString &extra)
|
||||||
{
|
{
|
||||||
LOG("Creating Basic Group Chat");
|
LOG("Creating Basic Group Chat");
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "createBasicGroupChat");
|
requestObject.insert(_TYPE, "createBasicGroupChat");
|
||||||
requestObject.insert("basic_group_id", basicGroupId);
|
requestObject.insert("basic_group_id", basicGroupId);
|
||||||
requestObject.insert(_EXTRA, "openDirectly"); //gets matched in qml
|
requestObject.insert(_EXTRA, extra); //"openDirectly"/"openAndSend:*" gets matched in qml
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,12 +950,15 @@ void TDLibWrapper::getPollVoters(const QString &chatId, qlonglong messageId, int
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibWrapper::searchPublicChat(const QString &userName)
|
void TDLibWrapper::searchPublicChat(const QString &userName, bool doOpenOnFound)
|
||||||
{
|
{
|
||||||
LOG("Search public chat" << userName);
|
LOG("Search public chat" << userName);
|
||||||
|
if(doOpenOnFound) {
|
||||||
this->activeChatSearchName = userName;
|
this->activeChatSearchName = userName;
|
||||||
|
}
|
||||||
QVariantMap requestObject;
|
QVariantMap requestObject;
|
||||||
requestObject.insert(_TYPE, "searchPublicChat");
|
requestObject.insert(_TYPE, "searchPublicChat");
|
||||||
|
requestObject.insert(_EXTRA, "searchPublicChat:"+userName);
|
||||||
requestObject.insert(USERNAME, userName);
|
requestObject.insert(USERNAME, userName);
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
@ -1093,6 +1099,53 @@ void TDLibWrapper::setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlo
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::getInlineQueryResults(qlonglong botUserId, qlonglong chatId, const QVariantMap &userLocation, const QString &query, const QString &offset, const QString &extra)
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG("Get Inline Query Results" << chatId << query);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "getInlineQueryResults");
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
requestObject.insert("bot_user_id", botUserId);
|
||||||
|
if(!userLocation.isEmpty()) {
|
||||||
|
requestObject.insert("user_location", userLocation);
|
||||||
|
}
|
||||||
|
requestObject.insert("query", query);
|
||||||
|
requestObject.insert("offset", offset);
|
||||||
|
requestObject.insert(_EXTRA, extra);
|
||||||
|
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::sendInlineQueryResultMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &queryId, const QString &resultId)
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG("Send Inline Query Result Message" << chatId);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "sendInlineQueryResultMessage");
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
requestObject.insert("message_thread_id", threadId);
|
||||||
|
requestObject.insert("reply_to_message_id", replyToMessageId);
|
||||||
|
requestObject.insert("query_id", queryId);
|
||||||
|
requestObject.insert("result_id", resultId);
|
||||||
|
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::sendBotStartMessage(qlonglong botUserId, qlonglong chatId, const QString ¶meter, const QString &extra)
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG("Send Bot Start Message" << botUserId << chatId << parameter << extra);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "sendBotStartMessage");
|
||||||
|
requestObject.insert("bot_user_id", botUserId);
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
requestObject.insert("parameter", parameter);
|
||||||
|
requestObject.insert(_EXTRA, extra);
|
||||||
|
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::searchEmoji(const QString &queryString)
|
void TDLibWrapper::searchEmoji(const QString &queryString)
|
||||||
{
|
{
|
||||||
LOG("Searching emoji" << queryString);
|
LOG("Searching emoji" << queryString);
|
||||||
|
@ -1389,12 +1442,12 @@ void TDLibWrapper::handleChatReceived(const QVariantMap &chatInformation)
|
||||||
if (receivedChatType == ChatTypeBasicGroup) {
|
if (receivedChatType == ChatTypeBasicGroup) {
|
||||||
LOG("Found basic group for active search" << this->activeChatSearchName);
|
LOG("Found basic group for active search" << this->activeChatSearchName);
|
||||||
this->activeChatSearchName.clear();
|
this->activeChatSearchName.clear();
|
||||||
this->createBasicGroupChat(chatType.value("basic_group_id").toString());
|
this->createBasicGroupChat(chatType.value("basic_group_id").toString(), "openDirectly");
|
||||||
}
|
}
|
||||||
if (receivedChatType == ChatTypeSupergroup) {
|
if (receivedChatType == ChatTypeSupergroup) {
|
||||||
LOG("Found supergroup for active search" << this->activeChatSearchName);
|
LOG("Found supergroup for active search" << this->activeChatSearchName);
|
||||||
this->activeChatSearchName.clear();
|
this->activeChatSearchName.clear();
|
||||||
this->createSupergroupChat(chatType.value("supergroup_id").toString());
|
this->createSupergroupChat(chatType.value("supergroup_id").toString(), "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1421,7 +1474,7 @@ void TDLibWrapper::handleBasicGroupUpdated(qlonglong groupId, const QVariantMap
|
||||||
if (!this->activeChatSearchName.isEmpty() && this->activeChatSearchName == groupInformation.value(USERNAME).toString()) {
|
if (!this->activeChatSearchName.isEmpty() && this->activeChatSearchName == groupInformation.value(USERNAME).toString()) {
|
||||||
LOG("Found basic group for active search" << this->activeChatSearchName);
|
LOG("Found basic group for active search" << this->activeChatSearchName);
|
||||||
this->activeChatSearchName.clear();
|
this->activeChatSearchName.clear();
|
||||||
this->createBasicGroupChat(groupInformation.value(ID).toString());
|
this->createBasicGroupChat(groupInformation.value(ID).toString(), "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,7 +1484,7 @@ void TDLibWrapper::handleSuperGroupUpdated(qlonglong groupId, const QVariantMap
|
||||||
if (!this->activeChatSearchName.isEmpty() && this->activeChatSearchName == groupInformation.value(USERNAME).toString()) {
|
if (!this->activeChatSearchName.isEmpty() && this->activeChatSearchName == groupInformation.value(USERNAME).toString()) {
|
||||||
LOG("Found supergroup for active search" << this->activeChatSearchName);
|
LOG("Found supergroup for active search" << this->activeChatSearchName);
|
||||||
this->activeChatSearchName.clear();
|
this->activeChatSearchName.clear();
|
||||||
this->createSupergroupChat(groupInformation.value(ID).toString());
|
this->createSupergroupChat(groupInformation.value(ID).toString(), "openDirectly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,17 +155,17 @@ public:
|
||||||
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap ¬ificationSettings);
|
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap ¬ificationSettings);
|
||||||
Q_INVOKABLE void editMessageText(const QString &chatId, const QString &messageId, const QString &message);
|
Q_INVOKABLE void editMessageText(const QString &chatId, const QString &messageId, const QString &message);
|
||||||
Q_INVOKABLE void deleteMessages(const QString &chatId, const QVariantList messageIds);
|
Q_INVOKABLE void deleteMessages(const QString &chatId, const QVariantList messageIds);
|
||||||
Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height);
|
Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height, const QString &extra);
|
||||||
Q_INVOKABLE void getRecentStickers();
|
Q_INVOKABLE void getRecentStickers();
|
||||||
Q_INVOKABLE void getInstalledStickerSets();
|
Q_INVOKABLE void getInstalledStickerSets();
|
||||||
Q_INVOKABLE void getStickerSet(const QString &setId);
|
Q_INVOKABLE void getStickerSet(const QString &setId);
|
||||||
Q_INVOKABLE void getSupergroupMembers(const QString &groupId, int limit, int offset);
|
Q_INVOKABLE void getSupergroupMembers(const QString &groupId, int limit, int offset);
|
||||||
Q_INVOKABLE void getGroupFullInfo(const QString &groupId, bool isSuperGroup);
|
Q_INVOKABLE void getGroupFullInfo(const QString &groupId, bool isSuperGroup);
|
||||||
Q_INVOKABLE void getUserFullInfo(const QString &userId);
|
Q_INVOKABLE void getUserFullInfo(const QString &userId);
|
||||||
Q_INVOKABLE void createPrivateChat(const QString &userId);
|
Q_INVOKABLE void createPrivateChat(const QString &userId, const QString &extra);
|
||||||
Q_INVOKABLE void createNewSecretChat(const QString &userId);
|
Q_INVOKABLE void createNewSecretChat(const QString &userId, const QString &extra);
|
||||||
Q_INVOKABLE void createSupergroupChat(const QString &supergroupId);
|
Q_INVOKABLE void createSupergroupChat(const QString &supergroupId, const QString &extra);
|
||||||
Q_INVOKABLE void createBasicGroupChat(const QString &basicGroupId);
|
Q_INVOKABLE void createBasicGroupChat(const QString &basicGroupId, const QString &extra);
|
||||||
Q_INVOKABLE void getGroupsInCommon(const QString &userId, int limit, int offset);
|
Q_INVOKABLE void getGroupsInCommon(const QString &userId, int limit, int offset);
|
||||||
Q_INVOKABLE void getUserProfilePhotos(const QString &userId, int limit, int offset);
|
Q_INVOKABLE void getUserProfilePhotos(const QString &userId, int limit, int offset);
|
||||||
Q_INVOKABLE void setChatPermissions(const QString &chatId, const QVariantMap &chatPermissions);
|
Q_INVOKABLE void setChatPermissions(const QString &chatId, const QVariantMap &chatPermissions);
|
||||||
|
@ -177,7 +177,7 @@ public:
|
||||||
Q_INVOKABLE void setPollAnswer(const QString &chatId, qlonglong messageId, QVariantList optionIds);
|
Q_INVOKABLE void setPollAnswer(const QString &chatId, qlonglong messageId, QVariantList optionIds);
|
||||||
Q_INVOKABLE void stopPoll(const QString &chatId, qlonglong messageId);
|
Q_INVOKABLE void stopPoll(const QString &chatId, qlonglong messageId);
|
||||||
Q_INVOKABLE void getPollVoters(const QString &chatId, qlonglong messageId, int optionId, int limit, int offset, const QString &extra);
|
Q_INVOKABLE void getPollVoters(const QString &chatId, qlonglong messageId, int optionId, int limit, int offset, const QString &extra);
|
||||||
Q_INVOKABLE void searchPublicChat(const QString &userName);
|
Q_INVOKABLE void searchPublicChat(const QString &userName, bool doOpenOnFound);
|
||||||
Q_INVOKABLE void joinChatByInviteLink(const QString &inviteLink);
|
Q_INVOKABLE void joinChatByInviteLink(const QString &inviteLink);
|
||||||
Q_INVOKABLE void getDeepLinkInfo(const QString &link);
|
Q_INVOKABLE void getDeepLinkInfo(const QString &link);
|
||||||
Q_INVOKABLE void getContacts();
|
Q_INVOKABLE void getContacts();
|
||||||
|
@ -190,6 +190,9 @@ public:
|
||||||
Q_INVOKABLE void toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread);
|
Q_INVOKABLE void toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread);
|
||||||
Q_INVOKABLE void toggleChatIsPinned(qlonglong chatId, bool isPinned);
|
Q_INVOKABLE void toggleChatIsPinned(qlonglong chatId, bool isPinned);
|
||||||
Q_INVOKABLE void setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft);
|
Q_INVOKABLE void setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft);
|
||||||
|
Q_INVOKABLE void getInlineQueryResults(qlonglong botUserId, qlonglong chatId, const QVariantMap &userLocation, const QString &query, const QString &offset, const QString &extra);
|
||||||
|
Q_INVOKABLE void sendInlineQueryResultMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &queryId, const QString &resultId);
|
||||||
|
Q_INVOKABLE void sendBotStartMessage(qlonglong botUserId, qlonglong chatId, const QString ¶meter, const QString &extra);
|
||||||
|
|
||||||
// Others (candidates for extraction ;))
|
// Others (candidates for extraction ;))
|
||||||
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
||||||
|
@ -262,6 +265,8 @@ signals:
|
||||||
void messageNotFound(qlonglong chatId, qlonglong messageId);
|
void messageNotFound(qlonglong chatId, qlonglong messageId);
|
||||||
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
||||||
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
||||||
|
void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra);
|
||||||
|
void callbackQueryAnswer(const QString &text, bool alert, const QString &url);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleVersionDetected(const QString &version);
|
void handleVersionDetected(const QString &version);
|
||||||
|
|
|
@ -831,6 +831,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>haben %1 vom Chat entfernt</translation>
|
<translation>haben %1 vom Chat entfernt</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>
|
||||||
|
<numerusform>haben %Ln Punkt erziehlt</numerusform>
|
||||||
|
<numerusform>haben %Ln Punkte erziehlt</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform>hat %Ln Punkt erziehlt</numerusform>
|
||||||
|
<numerusform>hat %Ln Punkte erziehlt</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>haben ein Spiel gesendet</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation>hat ein Spiel gesendet</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -981,6 +1005,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Sie</translation>
|
<translation>Sie</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform>haben %Ln Punkt bei %2 erziehlt</numerusform>
|
||||||
|
<numerusform>haben %Ln Punkte bei %2 erziehlt</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform>hat %Ln Punkt bei %2 erziehlt</numerusform>
|
||||||
|
<numerusform>hat %Ln Punkte bei %2 erziehlt</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -993,6 +1032,14 @@
|
||||||
<translation>Diese Nachricht wurde weitergeleitet. Ursprünglicher Autor: %1</translation>
|
<translation>Diese Nachricht wurde weitergeleitet. Ursprünglicher Autor: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished">via %1</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1457,6 +1504,18 @@
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
<translation>Schaltet das Offline-Caching aus. Bestimmte Features können in diesem Modus eingeschränkt sein oder fehlen. Änderungen erfordern einen Neustart von Fernschreiber, um in Kraft zu treten.</translation>
|
<translation>Schaltet das Offline-Caching aus. Bestimmte Features können in diesem Modus eingeschränkt sein oder fehlen. Änderungen erfordern einen Neustart von Fernschreiber, um in Kraft zu treten.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation>Privatsphäre</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation>Erlaubt Standortsendung an Inline-Bots</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
|
<translation>Einige Inline-Bots fragen bei Nutzung Standortdaten an</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1924,5 +1983,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>haben %1 vom Chat entfernt</translation>
|
<translation>haben %1 vom Chat entfernt</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform>haben %Ln Punkt erziehlt</numerusform>
|
||||||
|
<numerusform>haben %Ln Punkte erziehlt</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>haben ein Spiel gesendet</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation>hat ein Spiel gesendet</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -831,6 +831,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>have removed %1 from the chat</translation>
|
<translation>have removed %1 from the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>
|
||||||
|
<numerusform>scored %Ln point</numerusform>
|
||||||
|
<numerusform>scored %Ln points</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>scored %Ln point</numerusform>
|
||||||
|
<numerusform>scored %Ln points</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>sent a game</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation>sent a game</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -981,6 +1005,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>You</translation>
|
<translation>You</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>
|
||||||
|
<numerusform>scored %Ln point in %2</numerusform>
|
||||||
|
<numerusform>scored %Ln points in %2</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>scored %Ln point in %2</numerusform>
|
||||||
|
<numerusform>scored %Ln points in %2</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -993,6 +1032,14 @@
|
||||||
<translation>This message was forwarded. Original author: %1</translation>
|
<translation>This message was forwarded. Original author: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished">via %1</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1457,6 +1504,18 @@
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
<translation>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</translation>
|
<translation>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation>Privacy</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation>Allow sending Location to inline bots</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
|
<translation>Some inline bots request location data when using them</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1924,5 +1983,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>have removed %1 from the chat</translation>
|
<translation>have removed %1 from the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>
|
||||||
|
<numerusform>scored %Ln point</numerusform>
|
||||||
|
<numerusform>scored %Ln points</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation>sent a game</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation>sent a game</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -275,11 +275,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin chat</source>
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Desanclar charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Pin chat</source>
|
<source>Pin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Anclar charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unmute chat</source>
|
<source>Unmute chat</source>
|
||||||
|
@ -492,7 +492,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Copy Document to Downloads</source>
|
<source>Copy Document to Downloads</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Copiar documento a Downloads</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -821,6 +821,28 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>ha quitado %1 de charla</translation>
|
<translation>ha quitado %1 de charla</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -904,7 +926,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Use the international format, e.g. %1</source>
|
<source>Use the international format, e.g. %1</source>
|
||||||
<translation>Usa el formato internacional %1</translation>
|
<translation>%1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>About Fernschreiber</source>
|
<source>About Fernschreiber</source>
|
||||||
|
@ -971,6 +993,19 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Usted</translation>
|
<translation>Usted</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -983,6 +1018,14 @@
|
||||||
<translation>Este mensaje fue reenviado. Autor original: %1</translation>
|
<translation>Este mensaje fue reenviado. Autor original: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1430,10 +1473,22 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enable online-only mode</source>
|
<source>Enable online-only mode</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Modo solo en línea</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation>Deshabilita el almacenamiento en caché sin conexión. Algunas funciones pueden estar limitadas o ausentes en este modo. Se requiere reiniciar Fernschreiber para su efecto.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1647,7 +1702,7 @@
|
||||||
<message>
|
<message>
|
||||||
<source>were added to this chat</source>
|
<source>were added to this chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>me añadí a esta charla</translation>
|
<translation>se agregó a esta charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>left this chat</source>
|
<source>left this chat</source>
|
||||||
|
@ -1903,5 +1958,21 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>ha añadido %1 de la charla</translation>
|
<translation>ha añadido %1 de la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -832,6 +832,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -982,6 +1006,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Sinä</translation>
|
<translation>Sinä</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -994,6 +1033,14 @@
|
||||||
<translation>Välitetty viesti. Alkuperäinen lähettäjä: %1</translation>
|
<translation>Välitetty viesti. Alkuperäinen lähettäjä: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1456,6 +1503,18 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1925,5 +1984,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -821,6 +821,28 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -971,6 +993,19 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation type="unfinished">Te</translation>
|
<translation type="unfinished">Te</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -983,6 +1018,14 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1434,6 +1477,18 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1903,5 +1958,21 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -831,6 +831,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>hai rimosso %1 dalla chat</translation>
|
<translation>hai rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -981,6 +1005,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Tu</translation>
|
<translation>Tu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -993,6 +1032,14 @@
|
||||||
<translation>Questo è un messaggio inoltrato. Autore originale: %1</translation>
|
<translation>Questo è un messaggio inoltrato. Autore originale: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1457,6 +1504,18 @@
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1924,5 +1983,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>hai rimosso %1 dalla chat</translation>
|
<translation>hai rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -841,6 +841,32 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>usunąłem %1 z czatu</translation>
|
<translation>usunąłem %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -991,6 +1017,23 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Ty</translation>
|
<translation>Ty</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -1003,6 +1046,14 @@
|
||||||
<translation>Ta wiadomość została przekazana. Oryginalny autor: %1</translation>
|
<translation>Ta wiadomość została przekazana. Oryginalny autor: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1478,6 +1529,18 @@
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1945,5 +2008,23 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>usunąłem %1 z czatu</translation>
|
<translation>usunąłem %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Open Telegram Database Library on GitHub</source>
|
<source>Open Telegram Database Library on GitHub</source>
|
||||||
<translation>Открыть Telegram Database Library на GitHub</translation>
|
<translation>Открыть TDLib на GitHub</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>About Telegram</source>
|
<source>About Telegram</source>
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>This product uses the Telegram API but is not endorsed or certified by Telegram.</source>
|
<source>This product uses the Telegram API but is not endorsed or certified by Telegram.</source>
|
||||||
<translation>Этот продукт использует Telegram API, но не одобрен или сертифицирован Telegram.</translation>
|
<translation>Этот продукт использует Telegram API, но не одобрен или сертифицирован Telegram FZ-LLC</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>TDLib version %1</source>
|
<source>TDLib version %1</source>
|
||||||
|
@ -281,11 +281,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin chat</source>
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Открепить чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Pin chat</source>
|
<source>Pin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Закрепить чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unmute chat</source>
|
<source>Unmute chat</source>
|
||||||
|
@ -512,7 +512,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Copy Document to Downloads</source>
|
<source>Copy Document to Downloads</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Сохранить в Загрузках</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -841,6 +841,32 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished">%1 удалены из чата</translation>
|
<translation type="unfinished">%1 удалены из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -928,7 +954,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>About Fernschreiber</source>
|
<source>About Fernschreiber</source>
|
||||||
<translation>О Фэрншрайбе</translation>
|
<translation>О программе</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -991,6 +1017,23 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Вы</translation>
|
<translation>Вы</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -1003,6 +1046,14 @@
|
||||||
<translation>Это сообщение было переадресовано. Первоначальный автор: %1</translation>
|
<translation>Это сообщение было переадресовано. Первоначальный автор: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1039,7 +1090,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Synchronize Contacts with Telegram</source>
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
<translation>Сихронизация контактов с Телеграм</translation>
|
<translation>Синхронизировать с Телеграм</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Could not synchronize your contacts with Telegram.</source>
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
@ -1065,7 +1116,7 @@
|
||||||
<name>OverviewPage</name>
|
<name>OverviewPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>About Fernschreiber</source>
|
<source>About Fernschreiber</source>
|
||||||
<translation>О программе «Fernschreiber»</translation>
|
<translation>О программе</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Fernschreiber</source>
|
<source>Fernschreiber</source>
|
||||||
|
@ -1472,10 +1523,22 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enable online-only mode</source>
|
<source>Enable online-only mode</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Включить режим "только в онлайне"</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished">При нём не будет использоваться автономное кэширование и некоторые функции могут быть ограничены или отсутствовать. Изменения вступят в силу после перезапуска Fernschreiber.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1541,7 +1604,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Ready</source>
|
<source>Ready</source>
|
||||||
<translation>Готов</translation>
|
<translation>Ожидание</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1945,5 +2008,23 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished">%1 удалены из чата</translation>
|
<translation type="unfinished">%1 удалены из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -831,6 +831,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>har tagit bort %1 från chatten</translation>
|
<translation>har tagit bort %1 från chatten</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -981,6 +1005,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Du</translation>
|
<translation>Du</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -993,6 +1032,14 @@
|
||||||
<translation>Detta meddelande är vidarebefordrat. Ursprunglig avsändare: %1</translation>
|
<translation>Detta meddelande är vidarebefordrat. Ursprunglig avsändare: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1455,6 +1502,18 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1924,5 +1983,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>har tagit bort %1 från chatten</translation>
|
<translation>har tagit bort %1 från chatten</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -275,11 +275,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin chat</source>
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>取消置顶对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Pin chat</source>
|
<source>Pin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>置顶对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unmute chat</source>
|
<source>Unmute chat</source>
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation>正在搜索对话内容…</translation>
|
<translation>搜索对话内容…</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Location: Obtaining position...</source>
|
<source>Location: Obtaining position...</source>
|
||||||
|
@ -441,8 +441,7 @@
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>unread message</source>
|
<source>unread message</source>
|
||||||
<translation>未读
|
<translation>未读消息</translation>
|
||||||
消息</translation>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>unread messages</source>
|
<source>unread messages</source>
|
||||||
|
@ -493,7 +492,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Copy Document to Downloads</source>
|
<source>Copy Document to Downloads</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>复制文档到下载</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -822,6 +821,28 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>已从此对话移除 %1</translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -972,6 +993,19 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>你</translation>
|
<translation>你</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -984,6 +1018,14 @@
|
||||||
<translation>此消息为转发消息,原作者: %1</translation>
|
<translation>此消息为转发消息,原作者: %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1419,7 +1461,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>启用储存加速器</translation>
|
<translation>开启储存加速器</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Focus text input area after send</source>
|
<source>Focus text input area after send</source>
|
||||||
|
@ -1431,10 +1473,22 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enable online-only mode</source>
|
<source>Enable online-only mode</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>开启仅在线模式</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation>禁用离线缓存。某些特定功能会在此模式中受限或消失。切换模式需要重启 fernschreiber 才能生效。</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1904,5 +1958,21 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation>已从此对话移除 %1</translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -831,6 +831,30 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ImagePage</name>
|
<name>ImagePage</name>
|
||||||
|
@ -981,6 +1005,21 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>You</translation>
|
<translation>You</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points in %2</source>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MessageOverlayFlickable</name>
|
<name>MessageOverlayFlickable</name>
|
||||||
|
@ -993,6 +1032,14 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MessageViaLabel</name>
|
||||||
|
<message>
|
||||||
|
<source>via %1</source>
|
||||||
|
<comment>message posted via bot user</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NewChatPage</name>
|
<name>NewChatPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1455,6 +1502,18 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Privacy</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Allow sending Location to inline bots</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Some inline bots request location data when using them</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -1924,5 +1983,22 @@
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>scored %Ln points</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished">
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<comment>myself</comment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>sent a game</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
Loading…
Reference in a new issue