Merge branch 'master' into smarter-extra-options

This commit is contained in:
Sebastian Wolf 2021-12-05 22:09:18 +01:00 committed by GitHub
commit 489c410b14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 5242 additions and 550 deletions

View file

@ -108,6 +108,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/messageContent/MessageVideoNote.qml \
qml/components/messageContent/MessageVideo.qml \
qml/components/messageContent/MessageVoiceNote.qml \
qml/components/messageContent/SponsoredMessage.qml \
qml/components/messageContent/WebPagePreview.qml \
qml/components/settingsPage/Accordion.qml \
qml/components/settingsPage/AccordionItem.qml \

View file

@ -141,7 +141,7 @@ ListItem {
text: qsTr("Reply to Message")
}
MenuItem {
visible: myMessage.can_be_edited
visible: typeof myMessage.can_be_edited !== "undefined" && myMessage.can_be_edited
onClicked: editMessage()
text: qsTr("Edit Message")
}
@ -187,16 +187,16 @@ ListItem {
Connections {
target: chatModel
onMessagesReceived: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onMessagesIncrementalUpdate: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onNewMessageReceived: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onUnreadCountUpdated: {
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex();
messageBackground.isUnread = index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage";
}
onLastReadSentMessageUpdated: {
Debug.log("[ChatModel] Messages in this chat were read, new last read: ", lastReadSentIndex, ", updating description for index ", index, ", status: ", (index <= lastReadSentIndex));
@ -305,7 +305,7 @@ ListItem {
}
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
width: precalculatedValues.backgroundWidth
property bool isUnread: index > chatModel.getLastReadMessageIndex()
property bool isUnread: index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage"
color: Theme.colorScheme === Theme.LightOnDark ? (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor) : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor)
radius: parent.width / 50
opacity: isUnread ? 0.5 : 0.2
@ -327,7 +327,7 @@ ListItem {
id: userText
width: parent.width
text: messageListItem.isOwnMessage ? qsTr("You") : Emoji.emojify(messageListItem.isAnonymous ? page.chatInformation.title : Functions.getUserName(messageListItem.userInformation), font.pixelSize)
text: messageListItem.isOwnMessage ? qsTr("You") : Emoji.emojify( myMessage['@type'] === "sponsoredMessage" ? tdLibWrapper.getChat(myMessage.sponsor_chat_id).title : ( messageListItem.isAnonymous ? page.chatInformation.title : Functions.getUserName(messageListItem.userInformation) ), font.pixelSize)
font.pixelSize: Theme.fontSizeExtraSmall
font.weight: Font.ExtraBold
color: messageListItem.textColor
@ -335,7 +335,7 @@ ListItem {
truncationMode: TruncationMode.Fade
textFormat: Text.StyledText
horizontalAlignment: messageListItem.textAlign
visible: precalculatedValues.showUserInfo
visible: precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage"
MouseArea {
anchors.fill: parent
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
@ -351,7 +351,7 @@ ListItem {
Loader {
id: messageInReplyToLoader
active: myMessage.reply_to_message_id !== 0
active: typeof myMessage.reply_to_message_id !== "undefined" && myMessage.reply_to_message_id !== 0
width: parent.width
// text height ~= 1,28*font.pixelSize
height: active ? precalculatedValues.messageInReplyToHeight : 0
@ -458,6 +458,21 @@ ListItem {
visible: (text !== "")
}
Loader {
id: sponsoredMessageButtonLoader
active: myMessage['@type'] === "sponsoredMessage"
asynchronous: true
width: parent.width
height: (status === Loader.Ready) ? item.implicitHeight : myMessage['@type'] === "sponsoredMessage" ? Theme.itemSizeMedium : 0
sourceComponent: Component {
SponsoredMessage {
sponsoredMessageData: myMessage
width: parent.width
}
}
}
Loader {
id: webPagePreviewLoader
active: false

View file

@ -0,0 +1,59 @@
/*
Copyright (C) 2021 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
Fernschreiber is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Fernschreiber is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
import "../"
import "../../js/functions.js" as Functions
Column {
id: sponsoredMessageColumn
property var sponsoredMessageData;
Component.onCompleted: {
if (sponsoredMessageData) {
if (typeof sponsoredMessageData.link === "undefined") {
sponsoredMessageButton.text = qsTr("Go to Channel");
sponsoredMessageButton.advertisesChannel = true;
} else if (sponsoredMessageData.link['@type'] === "internalLinkTypeMessage") {
sponsoredMessageButton.text = qsTr("Go to Message");
sponsoredMessageButton.enabled = false;
} else {
sponsoredMessageButton.text = qsTr("Start Bot");
sponsoredMessageButton.enabled = false;
}
}
}
Button {
id: sponsoredMessageButton
property bool advertisesChannel: false;
anchors {
horizontalCenter: parent.horizontalCenter
}
onClicked: {
if (advertisesChannel) {
tdLibWrapper.createSupergroupChat(sponsoredMessageData.sponsor_chat_id, "openDirectly");
}
}
}
}

View file

@ -78,7 +78,6 @@ Item {
}
horizontalAlignment: Text.AlignRight
truncationMode: TruncationMode.Fade
font.pixelSize: Theme.fontSizeSmall
color: button.highlighted ? Theme.highlightColor : Theme.primaryColor
textFormat: Text.PlainText
}

View file

@ -34,7 +34,10 @@ function getUserName(userInformation) {
function getMessageText(message, simple, currentUserId, ignoreEntities) {
var myself = ( message.sender['@type'] === "messageSenderUser" && message.sender.user_id.toString() === currentUserId.toString() );
var myself = false;
if ( message['@type'] !== "sponsoredMessage" ) {
myself = ( message.sender['@type'] === "messageSenderUser" && message.sender.user_id.toString() === currentUserId.toString() );
}
switch(message.content['@type']) {
case 'messageText':

View file

@ -44,6 +44,7 @@ Page {
property bool isBasicGroup: false;
property bool isSuperGroup: false;
property bool isChannel: false;
property bool containsSponsoredMessages: false;
property var chatPartnerInformation;
property var botInformation;
property var chatGroupInformation;
@ -188,6 +189,10 @@ Page {
return "";
}
if (message['@type'] === "sponsoredMessage") {
return qsTr("Sponsored Message");
}
if (message.edit_date > 0) {
messageStatusSuffix += " - " + qsTr("edited");
}
@ -552,11 +557,13 @@ Page {
}
}
onUserFullInfoUpdated: {
if(userId === chatPartnerInformation.id) {
chatPage.botInformation = userFullInfo;
}
}
onSponsoredMessagesReceived: {
chatPage.containsSponsoredMessages = true;
}
}
Connections {
@ -684,8 +691,10 @@ Page {
}
onTriggered: {
if(chatInformation.unread_count > 0 && lastQueuedIndex > -1) {
var messageToRead = chatModel.getMessage(lastQueuedIndex);
if (messageToRead['@type'] === "sponsoredMessage") {
tdLibWrapper.viewSponsoredMessage(chatInformation.id, messageToRead.id);
} else if (chatInformation.unread_count > 0 && lastQueuedIndex > -1) {
if (messageToRead && messageToRead.id) {
tdLibWrapper.viewMessage(chatInformation.id, messageToRead.id, false);
}
@ -1085,6 +1094,9 @@ Page {
Debug.log("Page is initialized!");
chatPage.isInitialized = true;
chatView.handleScrollPositionChanged();
if (chatPage.isChannel) {
tdLibWrapper.getChatSponsoredMessages(chatInformation.id);
}
}
}
}
@ -1135,7 +1147,8 @@ Page {
function handleScrollPositionChanged() {
Debug.log("Current position: ", chatView.contentY);
if (chatOverviewItem.visible && chatInformation.unread_count > 0) {
Debug.log("Contains sponsored messages?", chatPage.containsSponsoredMessages);
if (chatOverviewItem.visible && ( chatInformation.unread_count > 0 || chatPage.containsSponsoredMessages ) ) {
var bottomIndex = chatView.indexAt(chatView.contentX, ( chatView.contentY + chatView.height - Theme.horizontalPageMargin ));
if (bottomIndex > -1) {
viewMessageTimer.queueViewMessage(bottomIndex)

View file

@ -221,6 +221,17 @@ QVector<int> ChatModel::MessageData::setInteractionInfo(const QVariantMap &info)
bool ChatModel::MessageData::lessThan(const MessageData *message1, const MessageData *message2)
{
bool message1Sponsored = message1->messageData.value("@type") == "sponsoredMessage";
bool message2Sponsored = message2->messageData.value("@type") == "sponsoredMessage";
if (message1Sponsored && message2Sponsored) {
return message1->messageId < message2->messageId;
}
if (message1Sponsored && !message2Sponsored) {
return false;
}
if (!message1Sponsored && message2Sponsored) {
return true;
}
return message1->messageId < message2->messageId;
}
@ -232,6 +243,7 @@ ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
{
this->tdLibWrapper = tdLibWrapper;
connect(this->tdLibWrapper, SIGNAL(messagesReceived(QVariantList, int)), this, SLOT(handleMessagesReceived(QVariantList, int)));
connect(this->tdLibWrapper, SIGNAL(sponsoredMessagesReceived(QVariantList)), this, SLOT(handleSponsoredMessagesReceived(QVariantList)));
connect(this->tdLibWrapper, SIGNAL(newMessageReceived(qlonglong, QVariantMap)), this, SLOT(handleNewMessageReceived(qlonglong, QVariantMap)));
connect(this->tdLibWrapper, SIGNAL(receivedMessage(qlonglong, qlonglong, QVariantMap)), this, SLOT(handleMessageReceived(qlonglong, qlonglong, QVariantMap)));
connect(this->tdLibWrapper, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SLOT(handleChatReadInboxUpdated(QString, QString, int)));
@ -462,6 +474,23 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
}
void ChatModel::handleSponsoredMessagesReceived(const QVariantList &sponsoredMessages)
{
LOG("Handling sponsored messages:" <<sponsoredMessages.size());
if (sponsoredMessages.size() > 0) {
QList<MessageData*> messagesToBeAdded;
for (QVariant sponsoredMessage: sponsoredMessages) {
QVariantMap sponsoredMessageData = sponsoredMessage.toMap();
const qlonglong messageId = sponsoredMessageData.value(ID).toLongLong();
if (messageId && !messageIndexMap.contains(messageId)) {
LOG("New sponsored message will be added:" << messageId);
messagesToBeAdded.append(new MessageData(sponsoredMessageData, messageId));
}
}
appendMessages(messagesToBeAdded);
}
}
void ChatModel::handleNewMessageReceived(qlonglong chatId, const QVariantMap &message)
{
const qlonglong messageId = message.value(ID).toLongLong();
@ -662,7 +691,14 @@ void ChatModel::insertMessages(const QList<MessageData*> newMessages)
appendMessages(newMessages);
} else if (!newMessages.isEmpty()) {
// There is only an append or a prepend, tertium non datur! (probably ;))
const qlonglong lastKnownId = messages.last()->messageId;
qlonglong lastKnownId = -1;
for (int i = (messages.size() - 1); i >=0; i-- ) {
if (messages.at(i)->messageData.value("@type").toString() == "sponsoredMessage") {
continue;
} else {
lastKnownId = messages.at(i)->messageId;
}
}
const qlonglong firstNewId = newMessages.first()->messageId;
LOG("Inserting messages, last known ID:" << lastKnownId << ", first new ID:" << firstNewId);
if (lastKnownId < firstNewId) {

View file

@ -63,6 +63,7 @@ signals:
private slots:
void handleMessagesReceived(const QVariantList &messages, int totalCount);
void handleSponsoredMessagesReceived(const QVariantList &sponsoredMessages);
void handleNewMessageReceived(qlonglong chatId, const QVariantMap &message);
void handleMessageReceived(qlonglong chatId, qlonglong messageId, const QVariantMap &message);
void handleChatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);

View file

@ -101,6 +101,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("updateSupergroup", &TDLibReceiver::processUpdateSuperGroup);
handlers.insert("updateChatOnlineMemberCount", &TDLibReceiver::processChatOnlineMemberCountUpdated);
handlers.insert("messages", &TDLibReceiver::processMessages);
handlers.insert("sponsoredMessages", &TDLibReceiver::processSponsoredMessages);
handlers.insert("updateNewMessage", &TDLibReceiver::processUpdateNewMessage);
handlers.insert("message", &TDLibReceiver::processMessage);
handlers.insert("updateMessageSendSucceeded", &TDLibReceiver::processMessageSendSucceeded);
@ -356,6 +357,12 @@ void TDLibReceiver::processMessages(const QVariantMap &receivedInformation)
emit messagesReceived(receivedInformation.value(MESSAGES).toList(), receivedInformation.value(TOTAL_COUNT).toInt());
}
void TDLibReceiver::processSponsoredMessages(const QVariantMap &receivedInformation)
{
LOG("Received sponsored messages");
emit sponsoredMessagesReceived(receivedInformation.value("messages").toList());
}
void TDLibReceiver::processUpdateNewMessage(const QVariantMap &receivedInformation)
{
const QVariantMap message = receivedInformation.value(MESSAGE).toMap();

View file

@ -56,6 +56,7 @@ signals:
void superGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
void messagesReceived(const QVariantList &messages, int totalCount);
void sponsoredMessagesReceived(const QVariantList &sponsoredMessages);
void newMessageReceived(qlonglong chatId, const QVariantMap &message);
void messageInformation(qlonglong chatId, qlonglong messageId, const QVariantMap &message);
void messageSendSucceeded(qlonglong messageId, qlonglong oldMessageId, const QVariantMap &message);
@ -130,6 +131,7 @@ private:
void processUpdateSuperGroup(const QVariantMap &receivedInformation);
void processChatOnlineMemberCountUpdated(const QVariantMap &receivedInformation);
void processMessages(const QVariantMap &receivedInformation);
void processSponsoredMessages(const QVariantMap &receivedInformation);
void processUpdateNewMessage(const QVariantMap &receivedInformation);
void processMessage(const QVariantMap &receivedInformation);
void processMessageSendSucceeded(const QVariantMap &receivedInformation);

View file

@ -118,6 +118,7 @@ void TDLibWrapper::initializeTDLibReciever() {
connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleSuperGroupUpdated(qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SIGNAL(chatOnlineMemberCountUpdated(QString, int)));
connect(this->tdLibReceiver, SIGNAL(messagesReceived(QVariantList, int)), this, SIGNAL(messagesReceived(QVariantList, int)));
connect(this->tdLibReceiver, SIGNAL(sponsoredMessagesReceived(QVariantList)), this, SIGNAL(sponsoredMessagesReceived(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(newMessageReceived(qlonglong, QVariantMap)), this, SIGNAL(newMessageReceived(qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(messageInformation(qlonglong, qlonglong, QVariantMap)), this, SLOT(handleMessageInformation(qlonglong, qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(messageSendSucceeded(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageSendSucceeded(qlonglong, qlonglong, QVariantMap)));
@ -335,6 +336,17 @@ void TDLibWrapper::viewMessage(const QString &chatId, const QString &messageId,
this->sendRequest(requestObject);
}
void TDLibWrapper::viewSponsoredMessage(qlonglong chatId, qlonglong messageId)
{
LOG("Mark sponsored message as viewed" << chatId << messageId);
QVariantMap requestObject;
requestObject.insert(_TYPE, "viewSponsoredMessage");
requestObject.insert(CHAT_ID, chatId);
requestObject.insert("sponsored_message_id", messageId);
requestObject.insert(_EXTRA, "viewSponsoredMessage");
this->sendRequest(requestObject);
}
void TDLibWrapper::pinMessage(const QString &chatId, const QString &messageId, bool disableNotification)
{
LOG("Pin message to chat" << chatId << messageId << disableNotification);
@ -655,6 +667,16 @@ void TDLibWrapper::getChatPinnedMessage(qlonglong chatId)
this->sendRequest(requestObject);
}
void TDLibWrapper::getChatSponsoredMessages(qlonglong chatId)
{
LOG("Retrieving sponsored messages" << chatId);
QVariantMap requestObject;
requestObject.insert(_TYPE, "getChatSponsoredMessages");
requestObject.insert(CHAT_ID, chatId);
requestObject.insert(_EXTRA, "getChatSponsoredMessages:" + QString::number(chatId));
this->sendRequest(requestObject);
}
void TDLibWrapper::setOptionInteger(const QString &optionName, int optionValue)
{
LOG("Setting integer option" << optionName << optionValue);

View file

@ -158,6 +158,7 @@ public:
Q_INVOKABLE void leaveChat(const QString &chatId);
Q_INVOKABLE void getChatHistory(qlonglong chatId, qlonglong fromMessageId = 0, int offset = -1, int limit = 50, bool onlyLocal = false);
Q_INVOKABLE void viewMessage(const QString &chatId, const QString &messageId, bool force);
Q_INVOKABLE void viewSponsoredMessage(qlonglong chatId, qlonglong messageId);
Q_INVOKABLE void pinMessage(const QString &chatId, const QString &messageId, bool disableNotification = false);
Q_INVOKABLE void unpinMessage(const QString &chatId, const QString &messageId);
Q_INVOKABLE void sendTextMessage(const QString &chatId, const QString &message, const QString &replyToMessageId = "0");
@ -172,6 +173,7 @@ public:
Q_INVOKABLE void getMessage(qlonglong chatId, qlonglong messageId);
Q_INVOKABLE void getCallbackQueryAnswer(const QString &chatId, const QString &messageId, const QVariantMap &payload);
Q_INVOKABLE void getChatPinnedMessage(qlonglong chatId);
Q_INVOKABLE void getChatSponsoredMessages(qlonglong chatId);
Q_INVOKABLE void setOptionInteger(const QString &optionName, int optionValue);
Q_INVOKABLE void setOptionBoolean(const QString &optionName, bool optionValue);
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap &notificationSettings);
@ -260,6 +262,7 @@ signals:
void superGroupUpdated(qlonglong groupId);
void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
void messagesReceived(const QVariantList &messages, int totalCount);
void sponsoredMessagesReceived(const QVariantList &sponsoredMessages);
void newMessageReceived(qlonglong chatId, const QVariantMap &message);
void copyToDownloadsSuccessful(const QString &fileName, const QString &filePath);
void copyToDownloadsError(const QString &fileName, const QString &filePath);

View file

@ -1,5 +1,5 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -119,12 +119,12 @@ class Client final {
/**
* Move constructor.
*/
Client(Client &&other);
Client(Client &&other) noexcept;
/**
* Move assignment operator.
*/
Client &operator=(Client &&other);
Client &operator=(Client &&other) noexcept;
private:
class Impl;
@ -238,6 +238,27 @@ class ClientManager final {
*/
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> &&request);
/**
* A type of callback function that will be called when a message is added to the internal TDLib log.
*
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
* If 0, then TDLib will crash as soon as the callback returns.
* None of the TDLib methods can be called from the callback.
* \param message Null-terminated string with the message added to the log.
*/
using LogMessageCallbackPtr = void (*)(int verbosity_level, const char *message);
/**
* Sets the callback that will be called when a message is added to the internal TDLib log.
* None of the TDLib methods can be called from the callback.
* By default the callback is not set.
*
* \param[in] max_verbosity_level The maximum verbosity level of messages for which the callback will be called.
* \param[in] callback Callback that will be called when a message is added to the internal TDLib log.
* Pass nullptr to remove the callback.
*/
static void set_log_message_callback(int max_verbosity_level, LogMessageCallbackPtr callback);
/**
* Destroys the client manager and all TDLib client instances managed by it.
*/
@ -246,12 +267,12 @@ class ClientManager final {
/**
* Move constructor.
*/
ClientManager(ClientManager &&other);
ClientManager(ClientManager &&other) noexcept;
/**
* Move assignment operator.
*/
ClientManager &operator=(ClientManager &&other);
ClientManager &operator=(ClientManager &&other) noexcept;
/**
* Returns a pointer to a singleton ClientManager instance.

View file

@ -1,5 +1,5 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -21,7 +21,7 @@ namespace td {
* Interface for managing the internal logging of TDLib.
* By default TDLib writes logs to stderr or an OS specific log and uses a verbosity level of 5.
* These functions are deprecated since TDLib 1.4.0 in favor of the td::td_api::setLogVerbosityLevel,
* td::td_api::setLogStream and other synchronous requests for managing the intrenal TDLib logging.
* td::td_api::setLogStream and other synchronous requests for managing the internal TDLib logging.
*/
class Log {
public:
@ -76,6 +76,7 @@ class Log {
* The TDLib will crash as soon as callback returns.
* By default the callback is not set.
*
* \deprecated Use ClientManager::set_log_message_callback instead.
* \param[in] callback Callback that will be called when a fatal error happens.
* Pass nullptr to remove the callback.
*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -94,8 +94,11 @@ TDJSON_EXPORT const char *td_json_client_execute(void *client, const char *reque
*/
TDJSON_EXPORT void td_json_client_destroy(void *client);
/*
* New TDLib JSON interface.
/**
* \file
* Alternatively, you can use new TDLib JSON interface, which will replace the current JSON interface in TDLib 2.0.0.
*
* Objects and functions serialization to JSON is the same for both JSON interfaces.
*
* The main TDLib interface is asynchronous. To match requests with a corresponding response, the field "@extra" can
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
@ -109,6 +112,7 @@ TDJSON_EXPORT void td_json_client_destroy(void *client);
* Also note that all updates and responses to requests must be applied in the order they were received for consistency.
* Some TDLib requests can be executed synchronously from any thread using td_execute.
* TDLib client instances are destroyed automatically after they are closed.
* All TDLib client instances must be closed before application termination to ensure data consistency.
*
* General pattern of usage:
* \code
@ -156,6 +160,27 @@ TDJSON_EXPORT const char *td_receive(double timeout);
*/
TDJSON_EXPORT const char *td_execute(const char *request);
/**
* A type of callback function that will be called when a message is added to the internal TDLib log.
*
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
* If 0, then TDLib will crash as soon as the callback returns.
* None of the TDLib methods can be called from the callback.
* \param message Null-terminated string with the logged message.
*/
typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char *message);
/**
* Sets the callback that will be called when a message is added to the internal TDLib log.
* None of the TDLib methods can be called from the callback.
* By default the callback is not set.
*
* \param[in] max_verbosity_level The maximum verbosity level of messages for which the callback will be called.
* \param[in] callback Callback that will be called when a message is added to the internal TDLib log.
* Pass nullptr to remove the callback.
*/
TDJSON_EXPORT void td_set_log_message_callback(int max_verbosity_level, td_log_message_callback_ptr callback);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1,5 +1,5 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -11,7 +11,7 @@
* C interface for managing the internal logging of TDLib.
* By default TDLib writes logs to stderr or an OS specific log and uses a verbosity level of 5.
* These functions are deprecated since TDLib 1.4.0 in favor of the setLogVerbosityLevel, setLogStream and
* other synchronous requests for managing the intrenal TDLib logging.
* other synchronous requests for managing the internal TDLib logging.
*/
#include "td/telegram/tdjson_export.h"
@ -71,10 +71,11 @@ typedef void (*td_log_fatal_error_callback_ptr)(const char *error_message);
* The TDLib will crash as soon as callback returns.
* By default the callback is not set.
*
* \deprecated Use td_set_log_message_callback instead.
* \param[in] callback Callback that will be called when a fatal error happens.
* Pass NULL to remove the callback.
*/
TDJSON_EXPORT void td_set_log_fatal_error_callback(td_log_fatal_error_callback_ptr callback);
TDJSON_DEPRECATED_EXPORT void td_set_log_fatal_error_callback(td_log_fatal_error_callback_ptr callback);
#ifdef __cplusplus
} // extern "C"

View file

@ -1,5 +1,5 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation>Genauigkeit: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation>Gesponsorte Nachricht</translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1761,6 +1765,21 @@
<translation>Lade hoch...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation>Zum Kanal gehen</translation>
</message>
<message>
<source>Go to Message</source>
<translation>Zur Nachricht gehen</translation>
</message>
<message>
<source>Start Bot</source>
<translation>Bot starten</translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation>Accuracy: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation>Sponsored Message</translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1763,6 +1767,21 @@ messages</numerusform>
<translation>Uploading...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation>Go to Channel</translation>
</message>
<message>
<source>Go to Message</source>
<translation>Go to Message</translation>
</message>
<message>
<source>Start Bot</source>
<translation>Start Bot</translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -17,7 +17,7 @@
</message>
<message>
<source>Licensed under GNU GPLv3</source>
<translation>Usa la licencia GPLv3</translation>
<translation>Licenciado por: GPLv3</translation>
</message>
<message>
<source>Sources on GitHub</source>
@ -97,11 +97,11 @@
</message>
<message>
<source>This project uses OpenStreetMap Nominatim for reverse geocoding of location attachments. Thanks for making it available as web service!</source>
<translation type="unfinished"></translation>
<translation>Este proyecto usa la librería OpenStreetMap Nominatim para la codificación geográfica inversa de archivos adjuntos de ubicación. ¡Gracias por estar disponible como servicio web!</translation>
</message>
<message>
<source>Open OSM Nominatim Wiki</source>
<translation type="unfinished"></translation>
<translation>Librería OSM Nominatim</translation>
</message>
</context>
<context>
@ -516,10 +516,14 @@
</message>
<message>
<source>Unknown address</source>
<translation type="unfinished"></translation>
<translation>Dirección desconocida</translation>
</message>
<message>
<source>Accuracy: %1m</source>
<translation>Exactitud: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -737,7 +741,7 @@
<message>
<source>sent a voice note</source>
<comment>myself</comment>
<translation>envie una nota de voz</translation>
<translation>envié una nota de voz</translation>
</message>
<message>
<source>sent a venue</source>
@ -936,7 +940,7 @@
</message>
<message>
<source>Animated Emoji: %1</source>
<translation type="unfinished"></translation>
<translation>Emoji animado: %1</translation>
</message>
</context>
<context>
@ -1181,7 +1185,7 @@
</message>
<message>
<source>Transport-encrypted, uses Telegram Cloud, sharable across devices</source>
<translation>Transporte-encriptado, usa la nube de Telegram, se puede compartir entre dispositivos</translation>
<translation>Transporte-encriptado, usa la nube de Telegram, compartible entre dispositivos</translation>
</message>
<message>
<source>Search a contact...</source>
@ -1512,11 +1516,11 @@
</message>
<message>
<source>Show stickers as emojis</source>
<translation type="unfinished"></translation>
<translation>Mostrar pegatinas como emojis</translation>
</message>
<message>
<source>Only display emojis instead of the actual stickers</source>
<translation></translation>
<translation>Solo muestra emojis en lugar de las pegatinas reales</translation>
</message>
<message>
<source>Show stickers as images</source>
@ -1547,11 +1551,11 @@
</message>
<message>
<source>Focus text input on chat open</source>
<translation type="unfinished"></translation>
<translation>Enfocar la entrada de texto en la conversación abierta</translation>
</message>
<message>
<source>Focus the text input area when entering a chat</source>
<translation type="unfinished"></translation>
<translation>Enfocar el área de entrada de texto al ingresar a una conversación</translation>
</message>
<message>
<source>Focus text input area after send</source>
@ -1742,7 +1746,7 @@
</message>
<message>
<source>Profile Pictures</source>
<translation>Perfil de imagen</translation>
<translation>Imagen de perfil</translation>
</message>
<message>
<source>Add Picture</source>
@ -1761,6 +1765,21 @@
<translation>Subiendo...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>
@ -1799,7 +1818,7 @@
</message>
<message>
<source>Copy video to gallery</source>
<translation>Copiar video a la galería </translation>
<translation>Copiar video a la galería</translation>
</message>
</context>
<context>
@ -2261,7 +2280,7 @@
</message>
<message>
<source>Animated Emoji: %1</source>
<translation type="unfinished"></translation>
<translation>Emoji animado: %1</translation>
</message>
</context>
</TS>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1762,6 +1766,21 @@
<translation>Lähetetään...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation>Précision : %1 m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1761,6 +1765,21 @@
<translation>Téléverse</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -512,6 +512,10 @@
<source>Accuracy: %1m</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1734,6 +1738,21 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1761,6 +1765,21 @@
<translation>Carica...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -532,6 +532,10 @@
<source>Accuracy: %1m</source>
<translation>Dokładność: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1788,6 +1792,21 @@
<translation>Przesyłanie...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -532,6 +532,10 @@
<source>Accuracy: %1m</source>
<translation>Точность: %1м</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1791,6 +1795,21 @@
<translation>Отправка...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -532,6 +532,10 @@
<source>Accuracy: %1m</source>
<translation>Presnosť: %1 m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1788,6 +1792,21 @@
<translation>Zapisovanie...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation>Noggrannhet: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1761,6 +1765,21 @@
<translation>Ladda upp...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -512,6 +512,10 @@
<source>Accuracy: %1m</source>
<translation>: %1m</translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1735,6 +1739,21 @@
<translation></translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>

View file

@ -522,6 +522,10 @@
<source>Accuracy: %1m</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sponsored Message</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatSelectionPage</name>
@ -1761,6 +1765,21 @@
<translation type="unfinished">Uploading...</translation>
</message>
</context>
<context>
<name>SponsoredMessage</name>
<message>
<source>Go to Channel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Go to Message</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Start Bot</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>
<message>