Synchronize contacts with Telegram
This commit is contained in:
parent
7ab58d3730
commit
deacb7f0ea
20 changed files with 270 additions and 9 deletions
|
@ -28,17 +28,38 @@ Page {
|
||||||
|
|
||||||
property bool isLoading: true;
|
property bool isLoading: true;
|
||||||
|
|
||||||
onStatusChanged: {
|
function resetFocus() {
|
||||||
if (status === PageStatus.Active) {
|
contactsSearchField.focus = false;
|
||||||
|
newChatPage.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadContacts() {
|
||||||
contactsModel.hydrateContacts();
|
contactsModel.hydrateContacts();
|
||||||
contactsListView.model = contactsModel;
|
contactsListView.model = contactsModel;
|
||||||
newChatPage.isLoading = false;
|
newChatPage.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === PageStatus.Active) {
|
||||||
|
reloadContacts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetFocus() {
|
Connections {
|
||||||
contactsSearchField.focus = false;
|
target: contactsModel
|
||||||
newChatPage.focus = true;
|
onErrorSynchronizingContacts: {
|
||||||
|
reloadContacts();
|
||||||
|
appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onContactsImported: {
|
||||||
|
reloadContacts();
|
||||||
|
appNotification.show(qsTr("Contacts successfully synchronized with Telegram."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaFlickable {
|
SilicaFlickable {
|
||||||
|
@ -46,6 +67,17 @@ Page {
|
||||||
contentHeight: newChatPage.height
|
contentHeight: newChatPage.height
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
PullDownMenu {
|
||||||
|
visible: contactsModel.canSynchronizeContacts()
|
||||||
|
MenuItem {
|
||||||
|
onClicked: {
|
||||||
|
newChatPage.isLoading = true;
|
||||||
|
contactsModel.synchronizeContacts();
|
||||||
|
}
|
||||||
|
text: qsTr("Synchronize Contacts with Telegram")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: newChatPageColumn
|
id: newChatPageColumn
|
||||||
width: newChatPage.width
|
width: newChatPage.width
|
||||||
|
|
|
@ -325,6 +325,7 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false
|
||||||
connect(tdLibWrapper, SIGNAL(basicGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong)));
|
connect(tdLibWrapper, SIGNAL(basicGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong)));
|
||||||
connect(tdLibWrapper, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
|
connect(tdLibWrapper, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
|
||||||
connect(tdLibWrapper, SIGNAL(secretChatReceived(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
|
connect(tdLibWrapper, SIGNAL(secretChatReceived(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
|
||||||
|
connect(tdLibWrapper, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
|
||||||
|
|
||||||
// Don't start the timer until we have at least one chat
|
// Don't start the timer until we have at least one chat
|
||||||
relativeTimeRefreshTimer = new QTimer(this);
|
relativeTimeRefreshTimer = new QTimer(this);
|
||||||
|
@ -779,6 +780,27 @@ void ChatListModel::handleSecretChatUpdated(const QString &secretChatId, const Q
|
||||||
updateSecretChatVisibility(secretChat);
|
updateSecretChatVisibility(secretChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatListModel::handleChatTitleUpdated(const QString &chatId, const QString &title)
|
||||||
|
{
|
||||||
|
qlonglong chatIdLongLong = chatId.toLongLong();
|
||||||
|
if (chatIndexMap.contains(chatIdLongLong)) {
|
||||||
|
LOG("Updating title for" << chatId);
|
||||||
|
const int chatIndex = chatIndexMap.value(chatIdLongLong);
|
||||||
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
|
chat->chatData.insert(TITLE, title);
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
changedRoles.append(ChatData::RoleTitle);
|
||||||
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
|
} else {
|
||||||
|
ChatData *chat = hiddenChats.value(chatId.toLongLong());
|
||||||
|
if (chat) {
|
||||||
|
LOG("Updating title for hidden chat" << chatId);
|
||||||
|
chat->chatData.insert(TITLE, title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatListModel::handleRelativeTimeRefreshTimer()
|
void ChatListModel::handleRelativeTimeRefreshTimer()
|
||||||
{
|
{
|
||||||
LOG("Refreshing timestamps");
|
LOG("Refreshing timestamps");
|
||||||
|
|
|
@ -55,6 +55,7 @@ private slots:
|
||||||
void handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings);
|
void handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings);
|
||||||
void handleGroupUpdated(qlonglong groupId);
|
void handleGroupUpdated(qlonglong groupId);
|
||||||
void handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
|
void handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
|
||||||
|
void handleChatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
void handleRelativeTimeRefreshTimer();
|
void handleRelativeTimeRefreshTimer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -38,8 +38,17 @@ ContactsModel::ContactsModel(TDLibWrapper *tdLibWrapper, QObject *parent)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
this->tdLibWrapper = tdLibWrapper;
|
this->tdLibWrapper = tdLibWrapper;
|
||||||
|
|
||||||
connect(this->tdLibWrapper, SIGNAL(usersReceived(QString, QVariantList, int)), this, SLOT(handleUsersReceived(QString, QVariantList, int)));
|
connect(this->tdLibWrapper, SIGNAL(usersReceived(QString, QVariantList, int)), this, SLOT(handleUsersReceived(QString, QVariantList, int)));
|
||||||
|
|
||||||
|
this->deviceContactsDatabase = QSqlDatabase::addDatabase("QSQLITE", "contacts");
|
||||||
|
this->deviceContactsDatabase.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.local/share/system/Contacts/qtcontacts-sqlite/contacts.db");
|
||||||
|
if (this->deviceContactsDatabase.open()) {
|
||||||
|
LOG("Device's contacts database successfully opened :)");
|
||||||
|
this->canUseDeviceContacts = true;
|
||||||
|
} else {
|
||||||
|
LOG("Error opening device's contacts database :(");
|
||||||
|
this->canUseDeviceContacts = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ContactsModel::rowCount(const QModelIndex &) const
|
int ContactsModel::rowCount(const QModelIndex &) const
|
||||||
|
@ -143,3 +152,36 @@ void ContactsModel::applyFilter(const QString &filter)
|
||||||
}
|
}
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContactsModel::synchronizeContacts()
|
||||||
|
{
|
||||||
|
LOG("Synchronizing device contacts");
|
||||||
|
QVariantList deviceContacts;
|
||||||
|
QSqlQuery databaseQuery(this->deviceContactsDatabase);
|
||||||
|
databaseQuery.prepare("select distinct c.contactId, c.firstName, c.lastName, n.phoneNumber from Contacts as c inner join PhoneNumbers as n on c.contactId = n.contactId where n.phoneNumber is not null and ( c.firstName is not null or c.lastName is not null );");
|
||||||
|
if (databaseQuery.exec()) {
|
||||||
|
LOG("Device contacts successfully selected from database!");
|
||||||
|
while (databaseQuery.next()) {
|
||||||
|
QVariantMap singleContact;
|
||||||
|
singleContact.insert("first_name", databaseQuery.value(1).toString());
|
||||||
|
singleContact.insert("last_name", databaseQuery.value(2).toString());
|
||||||
|
singleContact.insert("phone_number", databaseQuery.value(3).toString());
|
||||||
|
deviceContacts.append(singleContact);
|
||||||
|
LOG("Found contact" << singleContact.value("first_name").toString() << singleContact.value("last_name").toString() << singleContact.value("phone_number").toString());
|
||||||
|
}
|
||||||
|
if (!deviceContacts.isEmpty()) {
|
||||||
|
LOG("Importing found contacts" << deviceContacts.size());
|
||||||
|
this->tdLibWrapper->importContacts(deviceContacts);
|
||||||
|
}
|
||||||
|
emit contactsSynchronized();
|
||||||
|
} else {
|
||||||
|
LOG("Error selecting contacts from database!");
|
||||||
|
emit errorSynchronizingContacts();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContactsModel::canSynchronizeContacts()
|
||||||
|
{
|
||||||
|
return this->canUseDeviceContacts;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QVariantList>
|
#include <QVariantList>
|
||||||
|
#include <QSqlDatabase>
|
||||||
|
#include <QSqlQuery>
|
||||||
|
|
||||||
#include "tdlibwrapper.h"
|
#include "tdlibwrapper.h"
|
||||||
|
|
||||||
|
@ -36,6 +38,12 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void hydrateContacts();
|
Q_INVOKABLE void hydrateContacts();
|
||||||
Q_INVOKABLE void applyFilter(const QString &filter);
|
Q_INVOKABLE void applyFilter(const QString &filter);
|
||||||
|
Q_INVOKABLE void synchronizeContacts();
|
||||||
|
Q_INVOKABLE bool canSynchronizeContacts();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void contactsSynchronized();
|
||||||
|
void errorSynchronizingContacts();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
void handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||||
|
@ -46,6 +54,8 @@ private:
|
||||||
QVariantList filteredContacts;
|
QVariantList filteredContacts;
|
||||||
QList<QString> contactIds;
|
QList<QString> contactIds;
|
||||||
QString filter;
|
QString filter;
|
||||||
|
QSqlDatabase deviceContactsDatabase;
|
||||||
|
bool canUseDeviceContacts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTACTSMODEL_H
|
#endif // CONTACTSMODEL_H
|
||||||
|
|
|
@ -129,6 +129,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("ok", &TDLibReceiver::nop);
|
handlers.insert("ok", &TDLibReceiver::nop);
|
||||||
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
||||||
handlers.insert("updateSecretChat", &TDLibReceiver::processUpdateSecretChat);
|
handlers.insert("updateSecretChat", &TDLibReceiver::processUpdateSecretChat);
|
||||||
|
handlers.insert("importedContacts", &TDLibReceiver::processImportedContacts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::setActive(bool active)
|
void TDLibReceiver::setActive(bool active)
|
||||||
|
@ -539,3 +540,9 @@ void TDLibReceiver::processUpdateSecretChat(const QVariantMap &receivedInformati
|
||||||
QVariantMap updatedSecretChat = receivedInformation.value(SECRET_CHAT).toMap();
|
QVariantMap updatedSecretChat = receivedInformation.value(SECRET_CHAT).toMap();
|
||||||
emit secretChatUpdated(updatedSecretChat.value(ID).toString(), updatedSecretChat);
|
emit secretChatUpdated(updatedSecretChat.value(ID).toString(), updatedSecretChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processImportedContacts(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
LOG("Contacts were imported");
|
||||||
|
emit contactsImported(receivedInformation.value("importer_count").toList(), receivedInformation.value("user_ids").toList());
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,8 @@ signals:
|
||||||
void errorReceived(const int code, const QString &message);
|
void errorReceived(const int code, const QString &message);
|
||||||
void secretChat(const QString &secretChatId, const QVariantMap &secretChat);
|
void secretChat(const QString &secretChatId, const QVariantMap &secretChat);
|
||||||
void secretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
|
void secretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
|
||||||
|
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
|
||||||
|
|
||||||
|
@ -148,6 +150,7 @@ private:
|
||||||
void nop(const QVariantMap &receivedInformation);
|
void nop(const QVariantMap &receivedInformation);
|
||||||
void processSecretChat(const QVariantMap &receivedInformation);
|
void processSecretChat(const QVariantMap &receivedInformation);
|
||||||
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
||||||
|
void processImportedContacts(const QVariantMap &receivedInformation);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TDLIBRECEIVER_H
|
#endif // TDLIBRECEIVER_H
|
||||||
|
|
|
@ -116,6 +116,7 @@ TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface,
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString)), this, SIGNAL(errorReceived(int, QString)));
|
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString)), this, SIGNAL(errorReceived(int, QString)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
|
||||||
|
|
||||||
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
|
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
|
||||||
|
|
||||||
|
@ -842,6 +843,15 @@ void TDLibWrapper::closeSecretChat(const QString &secretChatId)
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::importContacts(const QVariantList &contacts)
|
||||||
|
{
|
||||||
|
LOG("Importing contacts");
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "importContacts");
|
||||||
|
requestObject.insert("contacts", contacts);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::searchEmoji(const QString &queryString)
|
void TDLibWrapper::searchEmoji(const QString &queryString)
|
||||||
{
|
{
|
||||||
LOG("Searching emoji" << queryString);
|
LOG("Searching emoji" << queryString);
|
||||||
|
|
|
@ -176,6 +176,7 @@ public:
|
||||||
Q_INVOKABLE void getContacts();
|
Q_INVOKABLE void getContacts();
|
||||||
Q_INVOKABLE void getSecretChat(const QString &secretChatId);
|
Q_INVOKABLE void getSecretChat(const QString &secretChatId);
|
||||||
Q_INVOKABLE void closeSecretChat(const QString &secretChatId);
|
Q_INVOKABLE void closeSecretChat(const QString &secretChatId);
|
||||||
|
Q_INVOKABLE void importContacts(const QVariantList &contacts);
|
||||||
|
|
||||||
// Others (candidates for extraction ;))
|
// Others (candidates for extraction ;))
|
||||||
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
Q_INVOKABLE void searchEmoji(const QString &queryString);
|
||||||
|
@ -242,6 +243,7 @@ signals:
|
||||||
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
void chatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
||||||
void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||||
void errorReceived(const int code, const QString &message);
|
void errorReceived(const int code, const QString &message);
|
||||||
|
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleVersionDetected(const QString &version);
|
void handleVersionDetected(const QString &version);
|
||||||
|
|
|
@ -944,6 +944,18 @@
|
||||||
<source>Loading contacts...</source>
|
<source>Loading contacts...</source>
|
||||||
<translation>Lade Kontakte...</translation>
|
<translation>Lade Kontakte...</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation>Kontakte mit Telegram synchronisieren</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation>Konnte Ihre Kontakte nicht mit Telegram synchronisieren.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation>Die Kontakte wurden erfolgreich mit Telegram synchronisiert.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -944,6 +944,18 @@
|
||||||
<source>Transport-encrypted, uses Telegram Cloud, sharable across devices</source>
|
<source>Transport-encrypted, uses Telegram Cloud, sharable across devices</source>
|
||||||
<translation>Transport-encrypted, uses Telegram Cloud, sharable across devices</translation>
|
<translation>Transport-encrypted, uses Telegram Cloud, sharable across devices</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation>Synchronize Contacts with Telegram</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation>Could not synchronize your contacts with Telegram.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation>Contacts successfully synchronized with Telegram.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -934,6 +934,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -945,6 +945,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -934,6 +934,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -944,6 +944,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -954,6 +954,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -954,6 +954,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -944,6 +944,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -934,6 +934,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
|
@ -944,6 +944,18 @@
|
||||||
<source>Search a contact...</source>
|
<source>Search a contact...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Synchronize Contacts with Telegram</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not synchronize your contacts with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Contacts successfully synchronized with Telegram.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>NotificationManager</name>
|
<name>NotificationManager</name>
|
||||||
|
|
Loading…
Reference in a new issue