telegram.me links supported in-app and in Windows

This commit is contained in:
John Preston 2014-12-03 16:10:32 +03:00
parent 03c8de6195
commit 27de201bda
25 changed files with 3626 additions and 3093 deletions

View File

@ -265,11 +265,12 @@ namespace App {
return lang(lng_status_lastseen).replace(qsl("{when}"), when);
}
void feedUsers(const MTPVector<MTPUser> &users) {
UserData *feedUsers(const MTPVector<MTPUser> &users) {
UserData *data;
const QVector<MTPUser> &v(users.c_vector().v);
for (QVector<MTPUser>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
const MTPuser &user(*i);
UserData *data = 0;
data = 0;
bool wasContact = false;
const MTPUserStatus *status = 0;
@ -389,6 +390,8 @@ namespace App {
if (App::main()) App::main()->peerUpdated(data);
}
return data;
}
void feedChats(const MTPVector<MTPChat> &chats) {
@ -903,6 +906,15 @@ namespace App {
return ::self;
}
UserData *userByName(const QString &username) {
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
if (!i.value()->chat && !i.value()->asUser()->username.compare(username.trimmed(), Qt::CaseInsensitive)) {
return i.value()->asUser();
}
}
return 0;
}
ChatData *chat(const PeerId &peer) {
PeerData *d = App::peer(peer);
return d->asChat();
@ -2062,4 +2074,16 @@ namespace App {
}
}
void openUserByName(const QString &username) {
if (App::main()) {
App::main()->openUserByName(username);
}
}
void openLocalUrl(const QString &url) {
if (App::main()) {
App::main()->openLocalUrl(url);
}
}
}

View File

@ -67,7 +67,7 @@ namespace App {
int32 onlineWillChangeIn(int32 onlineOnServer, int32 nowOnServer);
QString onlineText(UserData *user, int32 nowOnServer, bool precise = false);
void feedUsers(const MTPVector<MTPUser> &users);
UserData *feedUsers(const MTPVector<MTPUser> &users); // returnes last user
void feedChats(const MTPVector<MTPChat> &chats);
void feedParticipants(const MTPChatParticipants &p);
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
@ -99,6 +99,7 @@ namespace App {
UserData *user(const PeerId &peer);
UserData *user(int32 user);
UserData *self();
UserData *userByName(const QString &username);
ChatData *chat(const PeerId &peer);
ChatData *chat(int32 chat);
QString peerName(const PeerData *peer, bool forDialogs = false);
@ -187,5 +188,7 @@ namespace App {
void setProxySettings(QTcpSocket &socket);
void searchByHashtag(const QString &tag);
void openUserByName(const QString &username);
void openLocalUrl(const QString &url);
};

View File

@ -566,6 +566,9 @@ void Application::socketConnected() {
for (QStringList::const_iterator i = lst.cbegin(), e = lst.cend(); i != e; ++i) {
commands += qsl("SEND:") + _escapeTo7bit(*i) + ';';
}
if (!cStartUrl().isEmpty()) {
commands += qsl("OPEN:") + _escapeTo7bit(cStartUrl()) + ';';
}
commands += qsl("CMD:show;");
DEBUG_LOG(("Application Info: writing commands %1").arg(commands));
socket.write(commands.toLocal8Bit());
@ -674,6 +677,9 @@ void Application::startApp() {
}
QNetworkProxyFactory::setUseSystemConfiguration(true);
if (Local::oldMapVersion() < AppVersion) {
psRegisterCustomScheme();
}
}
void Application::socketDisconnected() {
@ -693,6 +699,7 @@ void Application::newInstanceConnected() {
}
void Application::readClients() {
QString startUrl;
QStringList toSend;
for (ClientSockets::iterator i = clients.begin(), e = clients.end(); i != e; ++i) {
i->second.append(i->first->readAll());
@ -709,6 +716,10 @@ void Application::readClients() {
if (cSendPaths().isEmpty()) {
toSend.append(_escapeFrom7bit(cmds.mid(from + 5, to - from - 5)));
}
} else if (cmd.startsWith(qsl("OPEN:"))) {
if (cStartUrl().isEmpty()) {
startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5));
}
} else {
LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
}
@ -729,6 +740,13 @@ void Application::readClients() {
App::wnd()->sendPaths();
}
}
if (!startUrl.isEmpty()) {
cSetStartUrl(startUrl);
}
if (!cStartUrl().isEmpty() && App::main() && App::self()) {
App::main()->openLocalUrl(cStartUrl());
cSetStartUrl(QString());
}
}
void Application::removeClients() {

View File

@ -260,7 +260,7 @@ bool AddContactBox::onSaveSelfFail(const RPCError &error) {
QString err(error.type());
QString firstName = textOneLine(_firstInput.text()), lastName = textOneLine(_lastInput.text());
if (err == "NAME_NOT_MODIFIED") {
App::self()->setName(firstName, lastName, firstName + ' ' + lastName, textOneLine(App::self()->username));
App::self()->setName(firstName, lastName, QString(), textOneLine(App::self()->username));
emit closed();
return true;
} else if (err == "FIRSTNAME_INVALID") {

View File

@ -812,6 +812,20 @@ namespace {
}
void TextLink::onClick(Qt::MouseButton button) const {
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
QString url = TextLink::encoded();
QRegularExpressionMatch telegramMe = QRegularExpression(qsl("^https?://telegram\\.me/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url);
if (telegramMe.hasMatch()) {
App::openUserByName(telegramMe.captured(1));
} else if (QRegularExpression(qsl("^tg://[a-zA-Z0-9]+"), QRegularExpression::CaseInsensitiveOption).match(url).hasMatch()) {
App::openLocalUrl(url);
} else {
QDesktopServices::openUrl(TextLink::encoded());
}
}
}
void HashtagLink::onClick(Qt::MouseButton button) const {
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
App::searchByHashtag(_tag);
@ -2935,6 +2949,7 @@ namespace {
regOneProtocol(qsl("http"));
regOneProtocol(qsl("https"));
regOneProtocol(qsl("ftp"));
regOneProtocol(qsl("tg")); // local urls
regOneTopDomain(qsl("ac"));
regOneTopDomain(qsl("ad"));

View File

@ -244,11 +244,7 @@ public:
return _url;
}
void onClick(Qt::MouseButton button) const {
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
QDesktopServices::openUrl(TextLink::encoded());
}
}
void onClick(Qt::MouseButton button) const;
const QString &readable() const {
return _readable;

View File

@ -451,7 +451,7 @@ namespace {
int32 _storageFilesSize = 0;
bool _mapChanged = false;
int32 _oldMapVersion = 0;
Local::ReadMapState _readMap(const QByteArray &pass) {
uint64 ms = getms();
QByteArray dataNameUtf8 = cDataFile().toUtf8();
@ -546,12 +546,15 @@ namespace {
return Local::ReadMapFailed;
}
}
_draftsMap = draftsMap;
_draftsPositionsMap = draftsPositionsMap;
_draftsNotReadMap = draftsNotReadMap;
_storageMap = storageMap;
_storageFilesSize = storageFilesSize;
_mapChanged = false;
_oldMapVersion = mapData.version;
LOG(("Map read time: %1").arg(getms() - ms));
return Local::ReadMapDone;
}
@ -693,6 +696,10 @@ namespace Local {
return result;
}
int32 oldMapVersion() {
return _oldMapVersion;
}
void writeDraft(const PeerId &peer, const QString &text) {
if (!_working()) return;

View File

@ -86,6 +86,7 @@ namespace Local {
ReadMapPassNeeded = 2,
};
ReadMapState readMap(const QByteArray &pass);
int32 oldMapVersion();
void writeDraft(const PeerId &peer, const QString &text);
QString readDraft(const PeerId &peer);

View File

@ -211,6 +211,7 @@ void logsInit() {
cForceWorkingDir(rightDir);
}
cForceWorkingDir(QDir(cWorkingDir()).absolutePath() + '/');
#ifdef Q_OS_WIN
if (cWorkingDir() == psAppDataPath()) { // fix old "Telegram Win (Unofficial)" version
moveOldDataFiles(psAppDataPathOld());

View File

@ -289,6 +289,7 @@ updPts(0), updDate(0), updQts(-1), updSeq(0), updInited(false), onlineRequest(0)
connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
connect(&history, SIGNAL(peerShown(PeerData*)), this, SLOT(onPeerShown(PeerData*)));
connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings()));
connect(this, SIGNAL(showPeerAsync(quint64,qint32,bool,bool)), this, SLOT(showPeer(quint64,qint32,bool,bool)), Qt::QueuedConnection);
if (audioVoice()) {
connect(audioVoice(), SIGNAL(updated(AudioData*)), this, SLOT(audioPlayProgress(AudioData*)));
connect(audioVoice(), SIGNAL(stopped(AudioData*)), this, SLOT(audioPlayProgress(AudioData*)));
@ -1049,7 +1050,7 @@ void MainWidget::createDialogAtTop(History *history, int32 unreadCount) {
dialogs.createDialogAtTop(history, unreadCount);
}
void MainWidget::showPeer(const PeerId &peerId, MsgId msgId, bool back, bool force) {
void MainWidget::showPeer(quint64 peerId, qint32 msgId, bool back, bool force) {
if (!back && _stack.size() == 1 && _stack[0]->type() == HistoryStackItem && _stack[0]->peer->id == peerId) {
back = true;
}
@ -1835,6 +1836,30 @@ void MainWidget::start(const MTPUser &user) {
App::app()->startUpdateCheck();
MTP::send(MTPupdates_GetState(), rpcDone(&MainWidget::gotState));
update();
if (!cStartUrl().isEmpty()) {
openLocalUrl(cStartUrl());
cSetStartUrl(QString());
}
}
void MainWidget::openLocalUrl(const QString &url) {
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/\\?domain=([a-zA-Z0-9\\.\\_]+)$"), QRegularExpression::CaseInsensitiveOption).match(url.trimmed());
if (m.hasMatch()) {
openUserByName(m.captured(1));
}
}
void MainWidget::openUserByName(const QString &username) {
UserData *user = App::userByName(username);
if (user) {
emit showPeerAsync(user->id, 0, false, true);
} else {
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone));
}
}
void MainWidget::usernameResolveDone(const MTPUser &user) {
showPeer(App::feedUsers(MTP_vector<MTPUser>(1, user))->id, 0, false, true);
}
void MainWidget::startFull(const MTPVector<MTPUser> &users) {
@ -2326,12 +2351,34 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
App::feedUserLink(d.vuser_id, d.vmy_link, d.vforeign_link);
} break;
case mtpc_updateNotifySettings: {
const MTPDupdateNotifySettings &d(update.c_updateNotifySettings());
applyNotifySetting(d.vpeer, d.vnotify_settings);
} break;
case mtpc_updateDcOptions: {
const MTPDupdateDcOptions &d(update.c_updateDcOptions());
MTP::updateDcOptions(d.vdc_options.c_vector().v);
} break;
case mtpc_updateUserPhone: {
const MTPDupdateUserPhone &d(update.c_updateUserPhone());
UserData *user = App::userLoaded(d.vuser_id.v);
if (user) {
user->setPhone(qs(d.vphone));
user->setName(user->firstName, user->lastName, (user->contact || isServiceUser(user->id) || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), user->username);
if (App::main()) App::main()->peerUpdated(user);
}
} break;
case mtpc_updateActivation: {
const MTPDupdateActivation &d(update.c_updateActivation());
} break;
case mtpc_updateNewAuthorization: {
const MTPDupdateNewAuthorization &d(update.c_updateNewAuthorization());
case mtpc_updateNewGeoChatMessage: {
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
// PeerId peer = App::histories().addToBack(d.vmessage);
// history.peerMessagesUpdated(peer);
} break;
case mtpc_updateNewEncryptedMessage: {
@ -2351,30 +2398,20 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
const MTPDupdateEncryptedMessagesRead &d(update.c_updateEncryptedMessagesRead());
} break;
case mtpc_updateNewGeoChatMessage: {
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
// PeerId peer = App::histories().addToBack(d.vmessage);
// history.peerMessagesUpdated(peer);
} break;
case mtpc_updateUserBlocked: {
const MTPDupdateUserBlocked &d(update.c_updateUserBlocked());
//
} break;
case mtpc_updateNotifySettings: {
const MTPDupdateNotifySettings &d(update.c_updateNotifySettings());
applyNotifySetting(d.vpeer, d.vnotify_settings);
} break;
case mtpc_updateDcOptions: {
const MTPDupdateDcOptions &d(update.c_updateDcOptions());
MTP::updateDcOptions(d.vdc_options.c_vector().v);
case mtpc_updateNewAuthorization: {
const MTPDupdateNewAuthorization &d(update.c_updateNewAuthorization());
} break;
case mtpc_updateServiceNotification: {
const MTPDupdateServiceNotification &d(update.c_updateServiceNotification());
//
} break;
case mtpc_updatePrivacy: {
const MTPDupdatePrivacy &d(update.c_updatePrivacy());
} break;
}
}

View File

@ -174,6 +174,8 @@ public:
bool animStep(float64 ms);
void start(const MTPUser &user);
void openLocalUrl(const QString &str);
void openUserByName(const QString &name);
void startFull(const MTPVector<MTPUser> &users);
void applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *history = 0);
void gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
@ -298,6 +300,7 @@ signals:
void dialogRowReplaced(DialogRow *oldRow, DialogRow *newRow);
void dialogToTop(const History::DialogLinks &links);
void dialogsUpdated();
void showPeerAsync(quint64 peer, qint32 msgId, bool back, bool force);
public slots:
@ -323,7 +326,7 @@ public slots:
void mainStateChanged(Qt::WindowState state);
void updateOnlineDisplay();
void showPeer(const PeerId &peer, MsgId msgId = 0, bool back = false, bool force = false);
void showPeer(quint64 peer, qint32 msgId = 0, bool back = false, bool force = false); // PeerId, MsgId
void onTopBarClick();
void onPeerShown(PeerData *peer);
@ -357,6 +360,8 @@ private:
void handleUpdates(const MTPUpdates &updates);
bool updateFail(const RPCError &e);
void usernameResolveDone(const MTPUser &user);
void hideAll();
void showAll();

View File

@ -367,7 +367,7 @@ static const mtpTypeId mtpLayers[] = {
mtpc_invokeWithLayer17,
mtpc_invokeWithLayer18,
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
static const mtpPrime mtpCurrentLayer = 19;
static const mtpPrime mtpCurrentLayer = 20;
template <typename bareT>
class MTPBoxed : public bareT {

File diff suppressed because it is too large Load Diff

View File

@ -349,6 +349,8 @@ enum {
mtpc_privacyValueDisallowUsers = 0xc7f49b7,
mtpc_account_privacyRules = 0x554abb6f,
mtpc_accountDaysTTL = 0xb8d0afdf,
mtpc_account_sentChangePhoneCode = 0xa4f58c4c,
mtpc_updateUserPhone = 0x12b9417b,
mtpc_invokeAfterMsg = 0xcb9f372d,
mtpc_invokeAfterMsgs = 0x3dc4b4f0,
mtpc_auth_checkPhone = 0x6fe51dfb,
@ -451,7 +453,10 @@ enum {
mtpc_account_setPrivacy = 0xc9f81ce8,
mtpc_account_deleteAccount = 0x418d4e0b,
mtpc_account_getAccountTTL = 0x8fc711d,
mtpc_account_setAccountTTL = 0x2442485e
mtpc_account_setAccountTTL = 0x2442485e,
mtpc_contacts_resolveUsername = 0xbf0131c,
mtpc_account_sendChangePhoneCode = 0xa407a8f4,
mtpc_account_changePhone = 0x70c32edb
};
// Type forward declarations
@ -805,6 +810,7 @@ class MTPDupdateUserBlocked;
class MTPDupdateNotifySettings;
class MTPDupdateServiceNotification;
class MTPDupdatePrivacy;
class MTPDupdateUserPhone;
class MTPupdates_state;
class MTPDupdates_state;
@ -940,6 +946,9 @@ class MTPDaccount_privacyRules;
class MTPaccountDaysTTL;
class MTPDaccountDaysTTL;
class MTPaccount_sentChangePhoneCode;
class MTPDaccount_sentChangePhoneCode;
// Boxed types definitions
typedef MTPBoxed<MTPresPQ> MTPResPQ;
@ -1068,6 +1077,7 @@ typedef MTPBoxed<MTPinputPrivacyRule> MTPInputPrivacyRule;
typedef MTPBoxed<MTPprivacyRule> MTPPrivacyRule;
typedef MTPBoxed<MTPaccount_privacyRules> MTPaccount_PrivacyRules;
typedef MTPBoxed<MTPaccountDaysTTL> MTPAccountDaysTTL;
typedef MTPBoxed<MTPaccount_sentChangePhoneCode> MTPaccount_SentChangePhoneCode;
// Type classes definitions
@ -5301,6 +5311,18 @@ public:
return *(const MTPDupdatePrivacy*)data;
}
MTPDupdateUserPhone &_updateUserPhone() {
if (!data) throw mtpErrorUninitialized();
if (_type != mtpc_updateUserPhone) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhone);
split();
return *(MTPDupdateUserPhone*)data;
}
const MTPDupdateUserPhone &c_updateUserPhone() const {
if (!data) throw mtpErrorUninitialized();
if (_type != mtpc_updateUserPhone) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhone);
return *(const MTPDupdateUserPhone*)data;
}
uint32 innerLength() const;
mtpTypeId type() const;
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
@ -5337,6 +5359,7 @@ private:
explicit MTPupdate(MTPDupdateNotifySettings *_data);
explicit MTPupdate(MTPDupdateServiceNotification *_data);
explicit MTPupdate(MTPDupdatePrivacy *_data);
explicit MTPupdate(MTPDupdateUserPhone *_data);
friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts);
friend MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id);
@ -5365,6 +5388,7 @@ private:
friend MTPupdate MTP_updateNotifySettings(const MTPNotifyPeer &_peer, const MTPPeerNotifySettings &_notify_settings);
friend MTPupdate MTP_updateServiceNotification(const MTPstring &_type, const MTPstring &_message, const MTPMessageMedia &_media, MTPBool _popup);
friend MTPupdate MTP_updatePrivacy(const MTPPrivacyKey &_key, const MTPVector<MTPPrivacyRule> &_rules);
friend MTPupdate MTP_updateUserPhone(MTPint _user_id, const MTPstring &_phone);
mtpTypeId _type;
};
@ -6983,6 +7007,37 @@ private:
};
typedef MTPBoxed<MTPaccountDaysTTL> MTPAccountDaysTTL;
class MTPaccount_sentChangePhoneCode : private mtpDataOwner {
public:
MTPaccount_sentChangePhoneCode();
MTPaccount_sentChangePhoneCode(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sentChangePhoneCode) : mtpDataOwner(0) {
read(from, end, cons);
}
MTPDaccount_sentChangePhoneCode &_account_sentChangePhoneCode() {
if (!data) throw mtpErrorUninitialized();
split();
return *(MTPDaccount_sentChangePhoneCode*)data;
}
const MTPDaccount_sentChangePhoneCode &c_account_sentChangePhoneCode() const {
if (!data) throw mtpErrorUninitialized();
return *(const MTPDaccount_sentChangePhoneCode*)data;
}
uint32 innerLength() const;
mtpTypeId type() const;
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sentChangePhoneCode);
void write(mtpBuffer &to) const;
typedef void ResponseType;
private:
explicit MTPaccount_sentChangePhoneCode(MTPDaccount_sentChangePhoneCode *_data);
friend MTPaccount_sentChangePhoneCode MTP_account_sentChangePhoneCode(const MTPstring &_phone_code_hash, MTPint _send_call_timeout);
};
typedef MTPBoxed<MTPaccount_sentChangePhoneCode> MTPaccount_SentChangePhoneCode;
// Type constructors with data
class MTPDresPQ : public mtpDataImpl<MTPDresPQ> {
@ -9069,6 +9124,17 @@ public:
MTPVector<MTPPrivacyRule> vrules;
};
class MTPDupdateUserPhone : public mtpDataImpl<MTPDupdateUserPhone> {
public:
MTPDupdateUserPhone() {
}
MTPDupdateUserPhone(MTPint _user_id, const MTPstring &_phone) : vuser_id(_user_id), vphone(_phone) {
}
MTPint vuser_id;
MTPstring vphone;
};
class MTPDupdates_state : public mtpDataImpl<MTPDupdates_state> {
public:
MTPDupdates_state() {
@ -9783,6 +9849,17 @@ public:
MTPint vdays;
};
class MTPDaccount_sentChangePhoneCode : public mtpDataImpl<MTPDaccount_sentChangePhoneCode> {
public:
MTPDaccount_sentChangePhoneCode() {
}
MTPDaccount_sentChangePhoneCode(const MTPstring &_phone_code_hash, MTPint _send_call_timeout) : vphone_code_hash(_phone_code_hash), vsend_call_timeout(_send_call_timeout) {
}
MTPstring vphone_code_hash;
MTPint vsend_call_timeout;
};
// RPC methods
class MTPreq_pq { // RPC method 'req_pq'
@ -14479,6 +14556,129 @@ public:
}
};
class MTPcontacts_resolveUsername { // RPC method 'contacts.resolveUsername'
public:
MTPstring vusername;
MTPcontacts_resolveUsername() {
}
MTPcontacts_resolveUsername(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_contacts_resolveUsername) {
read(from, end, cons);
}
MTPcontacts_resolveUsername(const MTPstring &_username) : vusername(_username) {
}
uint32 innerLength() const {
return vusername.innerLength();
}
mtpTypeId type() const {
return mtpc_contacts_resolveUsername;
}
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_contacts_resolveUsername) {
vusername.read(from, end);
}
void write(mtpBuffer &to) const {
vusername.write(to);
}
typedef MTPUser ResponseType;
};
class MTPcontacts_ResolveUsername : public MTPBoxed<MTPcontacts_resolveUsername> {
public:
MTPcontacts_ResolveUsername() {
}
MTPcontacts_ResolveUsername(const MTPcontacts_resolveUsername &v) : MTPBoxed<MTPcontacts_resolveUsername>(v) {
}
MTPcontacts_ResolveUsername(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPcontacts_resolveUsername>(from, end, cons) {
}
MTPcontacts_ResolveUsername(const MTPstring &_username) : MTPBoxed<MTPcontacts_resolveUsername>(MTPcontacts_resolveUsername(_username)) {
}
};
class MTPaccount_sendChangePhoneCode { // RPC method 'account.sendChangePhoneCode'
public:
MTPstring vphone_number;
MTPaccount_sendChangePhoneCode() {
}
MTPaccount_sendChangePhoneCode(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sendChangePhoneCode) {
read(from, end, cons);
}
MTPaccount_sendChangePhoneCode(const MTPstring &_phone_number) : vphone_number(_phone_number) {
}
uint32 innerLength() const {
return vphone_number.innerLength();
}
mtpTypeId type() const {
return mtpc_account_sendChangePhoneCode;
}
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sendChangePhoneCode) {
vphone_number.read(from, end);
}
void write(mtpBuffer &to) const {
vphone_number.write(to);
}
typedef MTPaccount_SentChangePhoneCode ResponseType;
};
class MTPaccount_SendChangePhoneCode : public MTPBoxed<MTPaccount_sendChangePhoneCode> {
public:
MTPaccount_SendChangePhoneCode() {
}
MTPaccount_SendChangePhoneCode(const MTPaccount_sendChangePhoneCode &v) : MTPBoxed<MTPaccount_sendChangePhoneCode>(v) {
}
MTPaccount_SendChangePhoneCode(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_sendChangePhoneCode>(from, end, cons) {
}
MTPaccount_SendChangePhoneCode(const MTPstring &_phone_number) : MTPBoxed<MTPaccount_sendChangePhoneCode>(MTPaccount_sendChangePhoneCode(_phone_number)) {
}
};
class MTPaccount_changePhone { // RPC method 'account.changePhone'
public:
MTPstring vphone_number;
MTPstring vphone_code_hash;
MTPstring vphone_code;
MTPaccount_changePhone() {
}
MTPaccount_changePhone(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_changePhone) {
read(from, end, cons);
}
MTPaccount_changePhone(const MTPstring &_phone_number, const MTPstring &_phone_code_hash, const MTPstring &_phone_code) : vphone_number(_phone_number), vphone_code_hash(_phone_code_hash), vphone_code(_phone_code) {
}
uint32 innerLength() const {
return vphone_number.innerLength() + vphone_code_hash.innerLength() + vphone_code.innerLength();
}
mtpTypeId type() const {
return mtpc_account_changePhone;
}
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_changePhone) {
vphone_number.read(from, end);
vphone_code_hash.read(from, end);
vphone_code.read(from, end);
}
void write(mtpBuffer &to) const {
vphone_number.write(to);
vphone_code_hash.write(to);
vphone_code.write(to);
}
typedef MTPUser ResponseType;
};
class MTPaccount_ChangePhone : public MTPBoxed<MTPaccount_changePhone> {
public:
MTPaccount_ChangePhone() {
}
MTPaccount_ChangePhone(const MTPaccount_changePhone &v) : MTPBoxed<MTPaccount_changePhone>(v) {
}
MTPaccount_ChangePhone(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_changePhone>(from, end, cons) {
}
MTPaccount_ChangePhone(const MTPstring &_phone_number, const MTPstring &_phone_code_hash, const MTPstring &_phone_code) : MTPBoxed<MTPaccount_changePhone>(MTPaccount_changePhone(_phone_number, _phone_code_hash, _phone_code)) {
}
};
// Inline methods definition
inline MTPresPQ::MTPresPQ() : mtpDataOwner(new MTPDresPQ()) {
@ -19781,6 +19981,10 @@ inline uint32 MTPupdate::innerLength() const {
const MTPDupdatePrivacy &v(c_updatePrivacy());
return v.vkey.innerLength() + v.vrules.innerLength();
}
case mtpc_updateUserPhone: {
const MTPDupdateUserPhone &v(c_updateUserPhone());
return v.vuser_id.innerLength() + v.vphone.innerLength();
}
}
return 0;
}
@ -19962,6 +20166,12 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
v.vkey.read(from, end);
v.vrules.read(from, end);
} break;
case mtpc_updateUserPhone: _type = cons; {
if (!data) setData(new MTPDupdateUserPhone());
MTPDupdateUserPhone &v(_updateUserPhone());
v.vuser_id.read(from, end);
v.vphone.read(from, end);
} break;
default: throw mtpErrorUnexpected(cons, "MTPupdate");
}
}
@ -20111,6 +20321,11 @@ inline void MTPupdate::write(mtpBuffer &to) const {
v.vkey.write(to);
v.vrules.write(to);
} break;
case mtpc_updateUserPhone: {
const MTPDupdateUserPhone &v(c_updateUserPhone());
v.vuser_id.write(to);
v.vphone.write(to);
} break;
}
}
inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
@ -20142,6 +20357,7 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
case mtpc_updateNotifySettings: setData(new MTPDupdateNotifySettings()); break;
case mtpc_updateServiceNotification: setData(new MTPDupdateServiceNotification()); break;
case mtpc_updatePrivacy: setData(new MTPDupdatePrivacy()); break;
case mtpc_updateUserPhone: setData(new MTPDupdateUserPhone()); break;
default: throw mtpErrorBadTypeId(type, "MTPupdate");
}
}
@ -20199,6 +20415,8 @@ inline MTPupdate::MTPupdate(MTPDupdateServiceNotification *_data) : mtpDataOwner
}
inline MTPupdate::MTPupdate(MTPDupdatePrivacy *_data) : mtpDataOwner(_data), _type(mtpc_updatePrivacy) {
}
inline MTPupdate::MTPupdate(MTPDupdateUserPhone *_data) : mtpDataOwner(_data), _type(mtpc_updateUserPhone) {
}
inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts) {
return MTPupdate(new MTPDupdateNewMessage(_message, _pts));
}
@ -20280,6 +20498,9 @@ inline MTPupdate MTP_updateServiceNotification(const MTPstring &_type, const MTP
inline MTPupdate MTP_updatePrivacy(const MTPPrivacyKey &_key, const MTPVector<MTPPrivacyRule> &_rules) {
return MTPupdate(new MTPDupdatePrivacy(_key, _rules));
}
inline MTPupdate MTP_updateUserPhone(MTPint _user_id, const MTPstring &_phone) {
return MTPupdate(new MTPDupdateUserPhone(_user_id, _phone));
}
inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) {
}
@ -22439,6 +22660,35 @@ inline MTPaccountDaysTTL MTP_accountDaysTTL(MTPint _days) {
return MTPaccountDaysTTL(new MTPDaccountDaysTTL(_days));
}
inline MTPaccount_sentChangePhoneCode::MTPaccount_sentChangePhoneCode() : mtpDataOwner(new MTPDaccount_sentChangePhoneCode()) {
}
inline uint32 MTPaccount_sentChangePhoneCode::innerLength() const {
const MTPDaccount_sentChangePhoneCode &v(c_account_sentChangePhoneCode());
return v.vphone_code_hash.innerLength() + v.vsend_call_timeout.innerLength();
}
inline mtpTypeId MTPaccount_sentChangePhoneCode::type() const {
return mtpc_account_sentChangePhoneCode;
}
inline void MTPaccount_sentChangePhoneCode::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
if (cons != mtpc_account_sentChangePhoneCode) throw mtpErrorUnexpected(cons, "MTPaccount_sentChangePhoneCode");
if (!data) setData(new MTPDaccount_sentChangePhoneCode());
MTPDaccount_sentChangePhoneCode &v(_account_sentChangePhoneCode());
v.vphone_code_hash.read(from, end);
v.vsend_call_timeout.read(from, end);
}
inline void MTPaccount_sentChangePhoneCode::write(mtpBuffer &to) const {
const MTPDaccount_sentChangePhoneCode &v(c_account_sentChangePhoneCode());
v.vphone_code_hash.write(to);
v.vsend_call_timeout.write(to);
}
inline MTPaccount_sentChangePhoneCode::MTPaccount_sentChangePhoneCode(MTPDaccount_sentChangePhoneCode *_data) : mtpDataOwner(_data) {
}
inline MTPaccount_sentChangePhoneCode MTP_account_sentChangePhoneCode(const MTPstring &_phone_code_hash, MTPint _send_call_timeout) {
return MTPaccount_sentChangePhoneCode(new MTPDaccount_sentChangePhoneCode(_phone_code_hash, _send_call_timeout));
}
// Human-readable text serialization
#if (defined _DEBUG || defined _WITH_DEBUG)

View File

@ -538,6 +538,10 @@ account.privacyRules#554abb6f rules:Vector<PrivacyRule> users:Vector<User> = acc
accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
account.sentChangePhoneCode#a4f58c4c phone_code_hash:string send_call_timeout:int = account.SentChangePhoneCode;
updateUserPhone#12b9417b user_id:int phone:string = Update;
---functions---
invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
@ -665,3 +669,8 @@ account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> =
account.deleteAccount#418d4e0b reason:string = Bool;
account.getAccountTTL#8fc711d = AccountDaysTTL;
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
contacts.resolveUsername#bf0131c username:string = User;
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;

View File

@ -982,6 +982,9 @@ void psStart() {
void psFinish() {
}
void psRegisterCustomScheme() {
}
bool _execUpdater(bool update = true) {
static const int MaxLen = 65536, MaxArgsCount = 128;

View File

@ -188,6 +188,8 @@ void psShowInFolder(const QString &name);
void psStart();
void psFinish();
void psRegisterCustomScheme();
void psUpdateOverlayed(QWidget *widget);
inline QString psConvertFileUrl(const QString &url) {
return url;

View File

@ -1108,6 +1108,10 @@ void psFinish() {
objc_finish();
}
void psRegisterCustomScheme() {
objc_registerCustomScheme();
}
void psExecUpdater() {
if (!objc_execUpdater()) {
QString readyPath = cWorkingDir() + qsl("tupdates/ready");

View File

@ -221,6 +221,8 @@ void psShowInFolder(const QString &name);
void psStart();
void psFinish();
void psRegisterCustomScheme();
void psUpdateOverlayed(QWidget *widget);
QString psConvertFileUrl(const QString &url);

View File

@ -66,6 +66,8 @@ void objc_finish();
bool objc_execUpdater();
void objc_execTelegram();
void objc_registerCustomScheme();
void objc_activateProgram();
bool objc_moveFile(const QString &from, const QString &to);
void objc_deleteDir(const QString &dir);

View File

@ -637,6 +637,9 @@ void objc_finish() {
}
}
void objc_registerCustomScheme() {
}
BOOL _execUpdater(BOOL update = YES) {
NSString *path = @"", *args = @"";
@try {

View File

@ -2168,6 +2168,77 @@ void psStart() {
void psFinish() {
}
namespace {
void _psLogError(const char *str, LSTATUS code) {
WCHAR errMsg[2048];
LPTSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, 0);
if (!errorText) {
errorText = errorTextDefault;
}
LOG((str).arg(code).arg(QString::fromStdWString(errorText)));
if (errorText != errorTextDefault) {
LocalFree(errorText);
}
}
bool _psOpenRegKey(LPCWSTR key, PHKEY rkey) {
DEBUG_LOG(("App Info: opening reg key %1..").arg(QString::fromStdWString(key)));
LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_QUERY_VALUE | KEY_WRITE, rkey);
if (status != ERROR_SUCCESS) {
if (status == ERROR_FILE_NOT_FOUND) {
status = RegCreateKeyEx(HKEY_CURRENT_USER, key, 0, 0, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_WRITE, 0, rkey, 0);
if (status != ERROR_SUCCESS) {
QString msg = qsl("App Error: could not create '%1' registry key, error %2").arg(QString::fromStdWString(key)).arg(qsl("%1: %2"));
_psLogError(msg.toUtf8().constData(), status);
return false;
}
} else {
QString msg = qsl("App Error: could not open '%1' registry key, error %2").arg(QString::fromStdWString(key)).arg(qsl("%1: %2"));
_psLogError(msg.toUtf8().constData(), status);
return false;
}
}
return true;
}
bool _psSetKeyValue(HKEY rkey, LPCWSTR value, QString v) {
static const int bufSize = 4096;
DWORD defaultType, defaultSize = bufSize * 2;
WCHAR defaultStr[bufSize] = { 0 };
if (RegQueryValueEx(rkey, value, 0, &defaultType, (BYTE*)defaultStr, &defaultSize) != ERROR_SUCCESS || defaultType != REG_SZ || defaultSize != (v.size() + 1) * 2 || QString::fromStdWString(defaultStr) != v) {
WCHAR tmp[bufSize] = { 0 };
if (!v.isEmpty()) wsprintf(tmp, v.replace(QChar('%'), qsl("%%")).toStdWString().c_str());
LSTATUS status = RegSetValueEx(rkey, 0, 0, REG_SZ, (BYTE*)tmp, (wcslen(tmp) + 1) * sizeof(WCHAR));
if (status != ERROR_SUCCESS) {
QString msg = qsl("App Error: could not set %1, error %2").arg(value ? ('\'' + QString::fromStdWString(value) + '\'') : qsl("(Default)")).arg("%1: %2");
_psLogError(msg.toUtf8().constData(), status);
return false;
}
}
return true;
}
}
void psRegisterCustomScheme() {
DEBUG_LOG(("App Info: Checking custom scheme 'tg'.."));
HKEY rkey;
QString exe = QDir::toNativeSeparators(QDir(cExeDir()).absolutePath() + '/' + QString::fromWCharArray(AppFile) + qsl(".exe"));
if (!_psOpenRegKey(L"Software\\Classes\\tg", &rkey)) return;
if (!_psSetKeyValue(rkey, L"URL Protocol", QString())) return;
if (!_psSetKeyValue(rkey, 0, qsl("URL:Telegram Link"))) return;
if (!_psOpenRegKey(L"Software\\Classes\\tg\\DefaultIcon", &rkey)) return;
if (!_psSetKeyValue(rkey, 0, '"' + exe + qsl(",1\""))) return;
if (!_psOpenRegKey(L"Software\\Classes\\tg\\shell", &rkey)) return;
if (!_psOpenRegKey(L"Software\\Classes\\tg\\shell\\open", &rkey)) return;
if (!_psOpenRegKey(L"Software\\Classes\\tg\\shell\\open\\command", &rkey)) return;
if (!_psSetKeyValue(rkey, 0, '"' + exe + qsl("\" -workdir \"") + cWorkingDir() + qsl("\" -- \"%1\""))) return;
}
void psExecUpdater() {
QString targs = qsl("-update");
if (cFromAutoStart()) targs += qsl(" -autostart");

View File

@ -199,6 +199,8 @@ void psShowInFolder(const QString &name);
void psStart();
void psFinish();
void psRegisterCustomScheme();
void psUpdateOverlayed(TWidget *widget);
inline QString psConvertFileUrl(const QString &url) {
return url;

View File

@ -26,6 +26,7 @@ QString gKeyFile;
QString gWorkingDir, gExeDir, gExeName;
QStringList gSendPaths;
QString gStartUrl;
QString gDialogLastPath, gDialogHelperPath; // optimize QFileDialog
@ -128,6 +129,13 @@ void settingsParseArgs(int argc, char *argv[]) {
for (++i; i < argc; ++i) {
gSendPaths.push_back(QString::fromLocal8Bit(argv[i]));
}
} else if (string("-workdir") == argv[i] && i + 1 < argc) {
QString dir = QString::fromLocal8Bit(argv[++i]);
if (QDir().exists(dir)) {
gWorkingDir = dir;
}
} else if (string("--") == argv[i] && i + 1 < argc) {
gStartUrl = QString::fromLocal8Bit(argv[++i]);
}
}
}

View File

@ -147,6 +147,7 @@ const RecentEmojiPack &cGetRecentEmojis();
DeclareReadSetting(QString, LangFile);
DeclareSetting(QStringList, SendPaths);
DeclareSetting(QString, StartUrl);
DeclareSetting(bool, Retina);
DeclareSetting(float64, RetinaFactor);