mirror of https://github.com/procxx/kepka.git
version 0.8.47.dev - search in conversation, clear history, delete conversation, saving cleared conversations locally, removed contacts from left column
This commit is contained in:
parent
61729119c5
commit
5dd8eab606
|
@ -1,11 +1,11 @@
|
||||||
@echo OFF
|
@echo OFF
|
||||||
|
|
||||||
set "AppVersionStrMajor=0.8"
|
set "AppVersionStrMajor=0.8"
|
||||||
set "AppVersion=8046"
|
set "AppVersion=8047"
|
||||||
set "AppVersionStrSmall=0.8.46"
|
set "AppVersionStrSmall=0.8.47"
|
||||||
set "AppVersionStr=0.8.46"
|
set "AppVersionStr=0.8.47"
|
||||||
set "AppVersionStrFull=0.8.46.0"
|
set "AppVersionStrFull=0.8.47.0"
|
||||||
set "DevChannel=0"
|
set "DevChannel=1"
|
||||||
|
|
||||||
if %DevChannel% neq 0 goto preparedev
|
if %DevChannel% neq 0 goto preparedev
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_dlg_new_group_name" = "Group name";
|
"lng_dlg_new_group_name" = "Group name";
|
||||||
"lng_dlg_create_group" = "Create";
|
"lng_dlg_create_group" = "Create";
|
||||||
"lng_no_contacts" = "You have no contacts";
|
"lng_no_contacts" = "You have no contacts";
|
||||||
|
"lng_no_chats" = "Your chats will be here";
|
||||||
"lng_contacts_loading" = "Loading..";
|
"lng_contacts_loading" = "Loading..";
|
||||||
"lng_contacts_not_found" = "No contacts found";
|
"lng_contacts_not_found" = "No contacts found";
|
||||||
"lng_dlg_search_chat" = "Search in this chat";
|
"lng_dlg_search_chat" = "Search in this chat";
|
||||||
|
@ -385,6 +386,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_title" = "New Group";
|
"lng_create_group_title" = "New Group";
|
||||||
|
|
||||||
"lng_failed_add_participant" = "Could not add user. Try again later.";
|
"lng_failed_add_participant" = "Could not add user. Try again later.";
|
||||||
|
"lng_failed_add_not_mutual" = "Sorry, if a person left a group, only a\nmutual contact can bring them back\n(they need to have your phone\nnumber, and you need theirs).";
|
||||||
|
|
||||||
"lng_sure_delete_contact" = "Are you sure, you want to delete {contact} from your contact list?";
|
"lng_sure_delete_contact" = "Are you sure, you want to delete {contact} from your contact list?";
|
||||||
"lng_sure_delete_history" = "Are you sure, you want to delete all message history with {contact}?\n\nThis action cannot be undone.";
|
"lng_sure_delete_history" = "Are you sure, you want to delete all message history with {contact}?\n\nThis action cannot be undone.";
|
||||||
|
@ -469,7 +471,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_message_ph" = "Write a message..";
|
"lng_message_ph" = "Write a message..";
|
||||||
"lng_record_cancel" = "Release outside this field to cancel";
|
"lng_record_cancel" = "Release outside this field to cancel";
|
||||||
"lng_empty_history" = "";
|
"lng_empty_history" = "";
|
||||||
"lng_willbe_history" = "Please select chat to start messaging";
|
"lng_willbe_history" = "Please select a chat to start messaging";
|
||||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||||
"lng_from_you" = "You";
|
"lng_from_you" = "You";
|
||||||
"lng_bot_description" = "What can this bot do?";
|
"lng_bot_description" = "What can this bot do?";
|
||||||
|
@ -627,7 +629,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||||
"lng_new_version_text" = "— Improved in-app media playback\n— Bug fixes and other minor improvements";
|
"lng_new_version_text" = "— Search for messages in conversation\n— Clear messages history in groups\n— Contacts without messages are hidden from the conversations list";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||||
|
|
||||||
|
|
|
@ -225,6 +225,23 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
||||||
_peerRequests.insert(peer, req);
|
_peerRequests.insert(peer, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::requestPeers(const QList<PeerData*> &peers) {
|
||||||
|
QVector<MTPint> chats;
|
||||||
|
QVector<MTPInputUser> users;
|
||||||
|
chats.reserve(peers.size());
|
||||||
|
users.reserve(peers.size());
|
||||||
|
for (QList<PeerData*>::const_iterator i = peers.cbegin(), e = peers.cend(); i != e; ++i) {
|
||||||
|
if (!*i || _fullPeerRequests.contains(*i) || _peerRequests.contains(*i)) continue;
|
||||||
|
if ((*i)->chat) {
|
||||||
|
chats.push_back(MTP_int(App::chatFromPeer((*i)->id)));
|
||||||
|
} else {
|
||||||
|
users.push_back((*i)->asUser()->inputUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!chats.isEmpty()) MTP::send(MTPmessages_GetChats(MTP_vector<MTPint>(chats)), rpcDone(&ApiWrap::gotChats));
|
||||||
|
if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers));
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||||
_peerRequests.remove(peer);
|
_peerRequests.remove(peer);
|
||||||
|
|
||||||
|
@ -249,6 +266,14 @@ void ApiWrap::gotUser(PeerData *peer, const MTPVector<MTPUser> &result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::gotChats(const MTPmessages_Chats &result) {
|
||||||
|
App::feedChats(result.c_messages_chats().vchats);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::gotUsers(const MTPVector<MTPUser> &result) {
|
||||||
|
App::feedUsers(result);
|
||||||
|
}
|
||||||
|
|
||||||
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
||||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
|
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(PeerData *peer);
|
||||||
void requestPeer(PeerData *peer);
|
void requestPeer(PeerData *peer);
|
||||||
|
void requestPeers(const QList<PeerData*> &peers);
|
||||||
|
|
||||||
void requestWebPageDelayed(WebPageData *page);
|
void requestWebPageDelayed(WebPageData *page);
|
||||||
void clearWebPageRequest(WebPageData *page);
|
void clearWebPageRequest(WebPageData *page);
|
||||||
|
@ -72,6 +73,8 @@ private:
|
||||||
|
|
||||||
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
|
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
|
||||||
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
|
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
|
||||||
|
void gotChats(const MTPmessages_Chats &result);
|
||||||
|
void gotUsers(const MTPVector<MTPUser> &result);
|
||||||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||||
PeerRequests _peerRequests;
|
PeerRequests _peerRequests;
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,8 @@ namespace App {
|
||||||
bool showPhone = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self | MTPDuser_flag_contact | MTPDuser_flag_mutual_contact));
|
bool showPhone = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self | MTPDuser_flag_contact | MTPDuser_flag_mutual_contact));
|
||||||
bool showPhoneChanged = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self)) && ((showPhone && data->contact) || (!showPhone && !data->contact));
|
bool showPhoneChanged = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self)) && ((showPhone && data->contact) || (!showPhone && !data->contact));
|
||||||
|
|
||||||
|
// see also Local::readPeer
|
||||||
|
|
||||||
QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : data->nameOrPhone;
|
QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : data->nameOrPhone;
|
||||||
|
|
||||||
data->setName(fname, lname, pname, uname);
|
data->setName(fname, lname, pname, uname);
|
||||||
|
@ -500,7 +502,6 @@ namespace App {
|
||||||
data->count = d.vparticipants_count.v;
|
data->count = d.vparticipants_count.v;
|
||||||
data->left = d.vleft.v;
|
data->left = d.vleft.v;
|
||||||
data->forbidden = false;
|
data->forbidden = false;
|
||||||
data->access = 0;
|
|
||||||
if (data->version < d.vversion.v) {
|
if (data->version < d.vversion.v) {
|
||||||
data->version = d.vversion.v;
|
data->version = d.vversion.v;
|
||||||
data->participants = ChatData::Participants();
|
data->participants = ChatData::Participants();
|
||||||
|
@ -519,7 +520,6 @@ namespace App {
|
||||||
data->count = -1;
|
data->count = -1;
|
||||||
data->left = false;
|
data->left = false;
|
||||||
data->forbidden = true;
|
data->forbidden = true;
|
||||||
data->access = 0;
|
|
||||||
} break;
|
} break;
|
||||||
case mtpc_geoChat: {
|
case mtpc_geoChat: {
|
||||||
const MTPDgeoChat &d(chat.c_geoChat());
|
const MTPDgeoChat &d(chat.c_geoChat());
|
||||||
|
@ -760,27 +760,23 @@ namespace App {
|
||||||
return ImagePtr();
|
return ImagePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc) {
|
||||||
|
if (loc.type() == mtpc_fileLocation) {
|
||||||
|
const MTPDfileLocation &l(loc.c_fileLocation());
|
||||||
|
return StorageImageLocation(w, h, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
||||||
|
}
|
||||||
|
return StorageImageLocation(w, h, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
StorageImageLocation imageLocation(const MTPPhotoSize &size) {
|
StorageImageLocation imageLocation(const MTPPhotoSize &size) {
|
||||||
switch (size.type()) {
|
switch (size.type()) {
|
||||||
case mtpc_photoSize: {
|
case mtpc_photoSize: {
|
||||||
const MTPDphotoSize &d(size.c_photoSize());
|
const MTPDphotoSize &d(size.c_photoSize());
|
||||||
if (d.vlocation.type() == mtpc_fileLocation) {
|
return imageLocation(d.vw.v, d.vh.v, d.vlocation);
|
||||||
const MTPDfileLocation &l(d.vlocation.c_fileLocation());
|
|
||||||
return StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case mtpc_photoCachedSize: {
|
case mtpc_photoCachedSize: {
|
||||||
const MTPDphotoCachedSize &d(size.c_photoCachedSize());
|
const MTPDphotoCachedSize &d(size.c_photoCachedSize());
|
||||||
if (d.vlocation.type() == mtpc_fileLocation) {
|
return imageLocation(d.vw.v, d.vh.v, d.vlocation);
|
||||||
const MTPDfileLocation &l(d.vlocation.c_fileLocation());
|
|
||||||
const string &s(d.vbytes.c_string().v);
|
|
||||||
QByteArray bytes(s.data(), s.size());
|
|
||||||
return StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
|
||||||
} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
|
|
||||||
const string &s(d.vbytes.c_string().v);
|
|
||||||
QByteArray bytes(s.data(), s.size());
|
|
||||||
return StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return StorageImageLocation();
|
return StorageImageLocation();
|
||||||
|
@ -1697,6 +1693,8 @@ namespace App {
|
||||||
randomData.clear();
|
randomData.clear();
|
||||||
mutedPeers.clear();
|
mutedPeers.clear();
|
||||||
updatedPeers.clear();
|
updatedPeers.clear();
|
||||||
|
cSetSavedPeers(SavedPeers());
|
||||||
|
cSetSavedPeersByTime(SavedPeersByTime());
|
||||||
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
|
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ namespace App {
|
||||||
int32 maxMsgId();
|
int32 maxMsgId();
|
||||||
|
|
||||||
ImagePtr image(const MTPPhotoSize &size);
|
ImagePtr image(const MTPPhotoSize &size);
|
||||||
|
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc);
|
||||||
StorageImageLocation imageLocation(const MTPPhotoSize &size);
|
StorageImageLocation imageLocation(const MTPPhotoSize &size);
|
||||||
|
|
||||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||||
|
|
|
@ -658,8 +658,8 @@ void Application::checkMapVersion() {
|
||||||
psRegisterCustomScheme();
|
psRegisterCustomScheme();
|
||||||
if (Local::oldMapVersion()) {
|
if (Local::oldMapVersion()) {
|
||||||
QString versionFeatures;
|
QString versionFeatures;
|
||||||
if (cDevVersion() && Local::oldMapVersion() < 8044) {
|
if (cDevVersion() && Local::oldMapVersion() < 8047) {
|
||||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sending media and recording audio status display");// .replace('@', qsl("@") + QChar(0x200D));
|
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Search for messages in conversation\n\xe2\x80\x94 Clear messages history in groups\n\xe2\x80\x94 Contacts without messages are hidden from the conversations list");// .replace('@', qsl("@") + QChar(0x200D));
|
||||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8045) {
|
} else if (!cDevVersion() && Local::oldMapVersion() < 8045) {
|
||||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ _byUsernameSel(-1),
|
||||||
_addContactLnk(this, lang(lng_add_contact_button)) {
|
_addContactLnk(this, lang(lng_add_contact_button)) {
|
||||||
DialogsIndexed &v(App::main()->dialogsList());
|
DialogsIndexed &v(App::main()->dialogsList());
|
||||||
for (DialogRow *r = v.list.begin; r != v.list.end; r = r->next) {
|
for (DialogRow *r = v.list.begin; r != v.list.end; r = r->next) {
|
||||||
if (r->history->peer->chat && !r->history->peer->asChat()->forbidden) {
|
if (r->history->peer->chat && !r->history->peer->asChat()->forbidden && !r->history->peer->asChat()->left) {
|
||||||
_contacts->addToEnd(r->history);
|
_contacts->addToEnd(r->history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ void ContactsInner::onAddBot() {
|
||||||
|
|
||||||
void ContactsInner::peerUpdated(PeerData *peer) {
|
void ContactsInner::peerUpdated(PeerData *peer) {
|
||||||
if (_chat && (!peer || peer == _chat)) {
|
if (_chat && (!peer || peer == _chat)) {
|
||||||
if (_chat->forbidden) {
|
if (_chat->forbidden || _chat->left) {
|
||||||
App::wnd()->hideLayer();
|
App::wnd()->hideLayer();
|
||||||
} else if (!_chat->participants.isEmpty() || _chat->count <= 0) {
|
} else if (!_chat->participants.isEmpty() || _chat->count <= 0) {
|
||||||
for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) {
|
for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) {
|
||||||
|
@ -180,11 +180,11 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
|
||||||
if (i == _contactsData.cend()) {
|
if (i == _contactsData.cend()) {
|
||||||
_contactsData.insert(peer, data = new ContactData());
|
_contactsData.insert(peer, data = new ContactData());
|
||||||
data->inchat = (_chat && !peer->chat) ? _chat->participants.contains(peer->asUser()) : false;
|
data->inchat = (_chat && !peer->chat) ? _chat->participants.contains(peer->asUser()) : false;
|
||||||
data->check = false;
|
data->check = _checkedContacts.contains(peer);
|
||||||
data->name.setText(st::profileListNameFont, peer->name, _textNameOptions);
|
data->name.setText(st::profileListNameFont, peer->name, _textNameOptions);
|
||||||
if (peer->chat) {
|
if (peer->chat) {
|
||||||
ChatData *chat = peer->asChat();
|
ChatData *chat = peer->asChat();
|
||||||
if (chat->forbidden) {
|
if (chat->forbidden || chat->left) {
|
||||||
data->online = lang(lng_chat_status_unaccessible);
|
data->online = lang(lng_chat_status_unaccessible);
|
||||||
} else {
|
} else {
|
||||||
data->online = lng_chat_status_members(lt_count, chat->count);
|
data->online = lng_chat_status_members(lt_count, chat->count);
|
||||||
|
@ -401,7 +401,7 @@ void ContactsInner::chooseParticipant() {
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsername.size()) {
|
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsername.size()) {
|
||||||
if (d_byUsername[_byUsernameSel]->inchat) return;
|
if (d_byUsername[_byUsernameSel]->inchat) return;
|
||||||
changeCheckState(d_byUsername[_byUsernameSel]);
|
changeCheckState(d_byUsername[_byUsernameSel], _byUsername[_byUsernameSel]);
|
||||||
} else {
|
} else {
|
||||||
if (!_sel || contactData(_sel)->inchat) return;
|
if (!_sel || contactData(_sel)->inchat) return;
|
||||||
changeCheckState(_sel);
|
changeCheckState(_sel);
|
||||||
|
@ -409,7 +409,7 @@ void ContactsInner::chooseParticipant() {
|
||||||
} else {
|
} else {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsernameFiltered.size()) {
|
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsernameFiltered.size()) {
|
||||||
if (d_byUsernameFiltered[_byUsernameSel]->inchat) return;
|
if (d_byUsernameFiltered[_byUsernameSel]->inchat) return;
|
||||||
changeCheckState(d_byUsernameFiltered[_byUsernameSel]);
|
changeCheckState(d_byUsernameFiltered[_byUsernameSel], _byUsernameFiltered[_byUsernameSel]);
|
||||||
|
|
||||||
ContactData *moving = d_byUsernameFiltered[_byUsernameSel];
|
ContactData *moving = d_byUsernameFiltered[_byUsernameSel];
|
||||||
int32 i = 0, l = d_byUsername.size();
|
int32 i = 0, l = d_byUsername.size();
|
||||||
|
@ -470,15 +470,17 @@ void ContactsInner::chooseParticipant() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsInner::changeCheckState(DialogRow *row) {
|
void ContactsInner::changeCheckState(DialogRow *row) {
|
||||||
changeCheckState(contactData(row));
|
changeCheckState(contactData(row), row->history->peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsInner::changeCheckState(ContactData *data) {
|
void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) {
|
||||||
if (data->check) {
|
if (data->check) {
|
||||||
data->check = false;
|
data->check = false;
|
||||||
|
_checkedContacts.remove(peer);
|
||||||
--_selCount;
|
--_selCount;
|
||||||
} else if (_selCount + (_chat ? _chat->count : 0) < cMaxGroupCount()) {
|
} else if (_selCount + (_chat ? _chat->count : 0) < cMaxGroupCount()) {
|
||||||
data->check = true;
|
data->check = true;
|
||||||
|
_checkedContacts.insert(peer, true);
|
||||||
++_selCount;
|
++_selCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,7 +695,7 @@ void ContactsInner::peopleReceived(const QString &query, const QVector<MTPContac
|
||||||
ContactData *d = new ContactData();
|
ContactData *d = new ContactData();
|
||||||
_byUsernameDatas.push_back(d);
|
_byUsernameDatas.push_back(d);
|
||||||
d->inchat = _chat ? _chat->participants.contains(u) : false;
|
d->inchat = _chat ? _chat->participants.contains(u) : false;
|
||||||
d->check = false;
|
d->check = _checkedContacts.contains(u);
|
||||||
d->name.setText(st::profileListNameFont, u->name, _textNameOptions);
|
d->name.setText(st::profileListNameFont, u->name, _textNameOptions);
|
||||||
d->online = '@' + u->username;
|
d->online = '@' + u->username;
|
||||||
|
|
||||||
|
@ -880,6 +882,11 @@ void ContactsInner::selectSkipPage(int32 h, int32 dir) {
|
||||||
|
|
||||||
QVector<UserData*> ContactsInner::selected() {
|
QVector<UserData*> ContactsInner::selected() {
|
||||||
QVector<UserData*> result;
|
QVector<UserData*> result;
|
||||||
|
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||||
|
if (_checkedContacts.contains(row->history->peer)) {
|
||||||
|
contactData(row); // fill _contactsData
|
||||||
|
}
|
||||||
|
}
|
||||||
result.reserve(_contactsData.size());
|
result.reserve(_contactsData.size());
|
||||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||||
if (i.value()->check && !i.key()->chat) {
|
if (i.value()->check && !i.key()->chat) {
|
||||||
|
@ -896,10 +903,15 @@ QVector<UserData*> ContactsInner::selected() {
|
||||||
|
|
||||||
QVector<MTPInputUser> ContactsInner::selectedInputs() {
|
QVector<MTPInputUser> ContactsInner::selectedInputs() {
|
||||||
QVector<MTPInputUser> result;
|
QVector<MTPInputUser> result;
|
||||||
|
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||||
|
if (_checkedContacts.contains(row->history->peer)) {
|
||||||
|
contactData(row); // fill _contactsData
|
||||||
|
}
|
||||||
|
}
|
||||||
result.reserve(_contactsData.size());
|
result.reserve(_contactsData.size());
|
||||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||||
if (i.value()->check && !i.key()->chat) {
|
if (i.value()->check && !i.key()->chat) {
|
||||||
result.push_back(i.key()->inputUser);
|
result.push_back(i.key()->asUser()->inputUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int32 i = 0, l = _byUsername.size(); i < l; ++i) {
|
for (int32 i = 0, l = _byUsername.size(); i < l; ++i) {
|
||||||
|
@ -911,6 +923,11 @@ QVector<MTPInputUser> ContactsInner::selectedInputs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerData *ContactsInner::selectedUser() {
|
PeerData *ContactsInner::selectedUser() {
|
||||||
|
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||||
|
if (_checkedContacts.contains(row->history->peer)) {
|
||||||
|
contactData(row); // fill _contactsData
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||||
if (i.value()->check) {
|
if (i.value()->check) {
|
||||||
return i.key();
|
return i.key();
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
void loadProfilePhotos(int32 yFrom);
|
void loadProfilePhotos(int32 yFrom);
|
||||||
void chooseParticipant();
|
void chooseParticipant();
|
||||||
void changeCheckState(DialogRow *row);
|
void changeCheckState(DialogRow *row);
|
||||||
void changeCheckState(ContactData *data);
|
void changeCheckState(ContactData *data, PeerData *peer);
|
||||||
|
|
||||||
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
||||||
|
|
||||||
|
@ -109,6 +109,8 @@ private:
|
||||||
};
|
};
|
||||||
typedef QMap<PeerData*, ContactData*> ContactsData;
|
typedef QMap<PeerData*, ContactData*> ContactsData;
|
||||||
ContactsData _contactsData;
|
ContactsData _contactsData;
|
||||||
|
typedef QMap<PeerData*, bool> CheckedContacts;
|
||||||
|
CheckedContacts _checkedContacts;
|
||||||
|
|
||||||
ContactData *contactData(DialogRow *row);
|
ContactData *contactData(DialogRow *row);
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
static const int32 AppVersion = 8046;
|
static const int32 AppVersion = 8047;
|
||||||
static const wchar_t *AppVersionStr = L"0.8.46";
|
static const wchar_t *AppVersionStr = L"0.8.47";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = true;
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
|
|
@ -86,12 +86,12 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
dialogs.list.paint(p, width(), r.top(), r.bottom(), active, selected);
|
dialogs.list.paint(p, width(), r.top(), r.bottom(), active, selected);
|
||||||
}
|
}
|
||||||
if (contactsNoDialogs.list.count) {
|
if (contactsNoDialogs.list.count && false) {
|
||||||
contactsNoDialogs.list.paint(p, width(), r.top() - otherStart, r.bottom() - otherStart, active, selected);
|
contactsNoDialogs.list.paint(p, width(), r.top() - otherStart, r.bottom() - otherStart, active, selected);
|
||||||
} else if (!otherStart) {
|
} else if (!otherStart) {
|
||||||
p.setFont(st::noContactsFont->f);
|
p.setFont(st::noContactsFont->f);
|
||||||
p.setPen(st::noContactsColor->p);
|
p.setPen(st::noContactsColor->p);
|
||||||
p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center);
|
p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (!hashtagResults.isEmpty()) {
|
if (!hashtagResults.isEmpty()) {
|
||||||
|
@ -317,7 +317,7 @@ void DialogsListWidget::onUpdateSelected(bool force) {
|
||||||
if (newSel) {
|
if (newSel) {
|
||||||
contactSel = false;
|
contactSel = false;
|
||||||
} else {
|
} else {
|
||||||
newSel = contactsNoDialogs.list.rowAtY(mouseY - otherStart, st::dlgHeight);
|
newSel = 0;// contactsNoDialogs.list.rowAtY(mouseY - otherStart, st::dlgHeight);
|
||||||
contactSel = true;
|
contactSel = true;
|
||||||
}
|
}
|
||||||
if (newSel != sel) {
|
if (newSel != sel) {
|
||||||
|
@ -442,6 +442,8 @@ void DialogsListWidget::removePeer(PeerData *peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Local::removeSavedPeer(peer);
|
||||||
|
|
||||||
emit App::main()->dialogsUpdated();
|
emit App::main()->dialogsUpdated();
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -481,7 +483,7 @@ void DialogsListWidget::dlgUpdated(History *history) {
|
||||||
if (i != dialogs.list.rowByPeer.cend()) {
|
if (i != dialogs.list.rowByPeer.cend()) {
|
||||||
update(0, i.value()->pos * st::dlgHeight, width(), st::dlgHeight);
|
update(0, i.value()->pos * st::dlgHeight, width(), st::dlgHeight);
|
||||||
} else {
|
} else {
|
||||||
i = contactsNoDialogs.list.rowByPeer.find(history->peer->id);
|
i = contactsNoDialogs.list.rowByPeer.end();// find(history->peer->id);
|
||||||
if (i != contactsNoDialogs.list.rowByPeer.cend()) {
|
if (i != contactsNoDialogs.list.rowByPeer.cend()) {
|
||||||
update(0, (dialogs.list.count + i.value()->pos) * st::dlgHeight, width(), st::dlgHeight);
|
update(0, (dialogs.list.count + i.value()->pos) * st::dlgHeight, width(), st::dlgHeight);
|
||||||
}
|
}
|
||||||
|
@ -771,6 +773,16 @@ void DialogsListWidget::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsListWidget::addAllSavedPeers() {
|
||||||
|
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
||||||
|
while (!saved.isEmpty()) {
|
||||||
|
History *history = App::history(saved.last()->id);
|
||||||
|
history->dialogs = dialogs.addToEnd(history);
|
||||||
|
contactsNoDialogs.del(history->peer);
|
||||||
|
saved.remove(saved.lastKey(), saved.last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsListWidget::searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount) {
|
void DialogsListWidget::searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount) {
|
||||||
if (fromStart) {
|
if (fromStart) {
|
||||||
clearSearchResults(false);
|
clearSearchResults(false);
|
||||||
|
@ -810,7 +822,7 @@ void DialogsListWidget::contactsReceived(const QVector<MTPContact> &contacts) {
|
||||||
App::self()->contact = 1;
|
App::self()->contact = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sel && contactsNoDialogs.list.count) {
|
if (!sel && contactsNoDialogs.list.count && false) {
|
||||||
sel = contactsNoDialogs.list.begin;
|
sel = contactsNoDialogs.list.begin;
|
||||||
contactSel = true;
|
contactSel = true;
|
||||||
}
|
}
|
||||||
|
@ -827,11 +839,11 @@ int32 DialogsListWidget::addNewContact(int32 uid, bool select) {
|
||||||
if (i == dialogs.list.rowByPeer.cend()) {
|
if (i == dialogs.list.rowByPeer.cend()) {
|
||||||
DialogRow *added = contactsNoDialogs.addByName(history);
|
DialogRow *added = contactsNoDialogs.addByName(history);
|
||||||
if (!added) return -1;
|
if (!added) return -1;
|
||||||
if (select) {
|
if (select && false) {
|
||||||
sel = added;
|
sel = added;
|
||||||
contactSel = true;
|
contactSel = true;
|
||||||
}
|
}
|
||||||
if (contactsNoDialogs.list.count == 1 && !dialogs.list.count) refresh();
|
// if (contactsNoDialogs.list.count == 1 && !dialogs.list.count) refresh();
|
||||||
return added ? ((dialogs.list.count + added->pos) * st::dlgHeight) : -1;
|
return added ? ((dialogs.list.count + added->pos) * st::dlgHeight) : -1;
|
||||||
}
|
}
|
||||||
if (select) {
|
if (select) {
|
||||||
|
@ -844,7 +856,7 @@ int32 DialogsListWidget::addNewContact(int32 uid, bool select) {
|
||||||
void DialogsListWidget::refresh(bool toTop) {
|
void DialogsListWidget::refresh(bool toTop) {
|
||||||
int32 h = 0;
|
int32 h = 0;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
h = (dialogs.list.count + contactsNoDialogs.list.count) * st::dlgHeight;
|
h = (dialogs.list.count/* + contactsNoDialogs.list.count*/) * st::dlgHeight;
|
||||||
if (h) {
|
if (h) {
|
||||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -936,6 +948,15 @@ void DialogsListWidget::clearFilter() {
|
||||||
|
|
||||||
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
|
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
|
||||||
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
|
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
|
||||||
|
if (history->lastMsg) {
|
||||||
|
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
||||||
|
while (!saved.isEmpty() && history->lastMsg->date < saved.lastKey()) {
|
||||||
|
History *history = App::history(saved.last()->id);
|
||||||
|
history->dialogs = dialogs.addToEnd(history);
|
||||||
|
contactsNoDialogs.del(history->peer);
|
||||||
|
saved.remove(saved.lastKey(), saved.last());
|
||||||
|
}
|
||||||
|
}
|
||||||
History::DialogLinks links = dialogs.addToEnd(history);
|
History::DialogLinks links = dialogs.addToEnd(history);
|
||||||
history->dialogs = links;
|
history->dialogs = links;
|
||||||
contactsNoDialogs.del(history->peer);
|
contactsNoDialogs.del(history->peer);
|
||||||
|
@ -1714,6 +1735,7 @@ void DialogsWidget::onSearchMore(MsgId minMsgId) {
|
||||||
void DialogsWidget::loadDialogs() {
|
void DialogsWidget::loadDialogs() {
|
||||||
if (dlgPreloading) return;
|
if (dlgPreloading) return;
|
||||||
if (dlgCount >= 0 && dlgOffset >= dlgCount) {
|
if (dlgCount >= 0 && dlgOffset >= dlgCount) {
|
||||||
|
list.addAllSavedPeers();
|
||||||
cSetDialogsReceived(true);
|
cSetDialogsReceived(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
DialogsListWidget(QWidget *parent, MainWidget *main);
|
DialogsListWidget(QWidget *parent, MainWidget *main);
|
||||||
|
|
||||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
|
void addAllSavedPeers();
|
||||||
void searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount);
|
void searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount);
|
||||||
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
||||||
void showMore(int32 pixels);
|
void showMore(int32 pixels);
|
||||||
|
|
|
@ -29,6 +29,9 @@ struct StorageImageLocation {
|
||||||
}
|
}
|
||||||
StorageImageLocation(int32 width, int32 height, const MTPDfileLocation &location) : width(width), height(height), dc(location.vdc_id.v), volume(location.vvolume_id.v), local(location.vlocal_id.v), secret(location.vsecret.v) {
|
StorageImageLocation(int32 width, int32 height, const MTPDfileLocation &location) : width(width), height(height), dc(location.vdc_id.v), volume(location.vvolume_id.v), local(location.vlocal_id.v), secret(location.vsecret.v) {
|
||||||
}
|
}
|
||||||
|
bool isNull() const {
|
||||||
|
return !dc;
|
||||||
|
}
|
||||||
int32 width, height;
|
int32 width, height;
|
||||||
int32 dc;
|
int32 dc;
|
||||||
uint64 volume;
|
uint64 volume;
|
||||||
|
@ -36,6 +39,13 @@ struct StorageImageLocation {
|
||||||
uint64 secret;
|
uint64 secret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const StorageImageLocation &a, const StorageImageLocation &b) {
|
||||||
|
return !memcmp(&a, &b, sizeof(StorageImageLocation));
|
||||||
|
}
|
||||||
|
inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation &b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
class Image {
|
class Image {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -613,7 +613,7 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
|
||||||
if (!h.value()->loadedAtBottom()) {
|
if (!h.value()->loadedAtBottom()) {
|
||||||
HistoryItem *item = h.value()->addToHistory(msg);
|
HistoryItem *item = h.value()->addToHistory(msg);
|
||||||
if (item) {
|
if (item) {
|
||||||
h.value()->lastMsg = item;
|
h.value()->setLastMessage(item);
|
||||||
if (msgState > 0) {
|
if (msgState > 0) {
|
||||||
h.value()->newItemAdded(item);
|
h.value()->newItemAdded(item);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +908,8 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to->push_back(adding);
|
to->push_back(adding);
|
||||||
lastMsg = adding;
|
setLastMessage(adding);
|
||||||
|
|
||||||
adding->y = to->height;
|
adding->y = to->height;
|
||||||
if (width) {
|
if (width) {
|
||||||
int32 dh = adding->resize(width);
|
int32 dh = adding->resize(width);
|
||||||
|
@ -919,6 +920,7 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newItemAdded(adding);
|
newItemAdded(adding);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMedia *media = adding->getMedia(true);
|
HistoryMedia *media = adding->getMedia(true);
|
||||||
if (media) {
|
if (media) {
|
||||||
HistoryMediaType mt = media->type();
|
HistoryMediaType mt = media->type();
|
||||||
|
@ -1414,14 +1416,24 @@ void History::getReadyFor(MsgId msgId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void History::setLastMessage(HistoryItem *msg) {
|
||||||
|
if (msg) {
|
||||||
|
if (!lastMsg) Local::removeSavedPeer(peer);
|
||||||
|
lastMsg = msg;
|
||||||
|
lastMsgDate = msg->date;
|
||||||
|
} else {
|
||||||
|
lastMsg = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void History::fixLastMessage(bool wasAtBottom) {
|
void History::fixLastMessage(bool wasAtBottom) {
|
||||||
if (wasAtBottom && isEmpty()) {
|
if (wasAtBottom && isEmpty()) {
|
||||||
wasAtBottom = false;
|
wasAtBottom = false;
|
||||||
}
|
}
|
||||||
if (wasAtBottom) {
|
if (wasAtBottom) {
|
||||||
lastMsg = back()->back();
|
setLastMessage(back()->back());
|
||||||
} else {
|
} else {
|
||||||
lastMsg = 0;
|
setLastMessage(0);
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->checkPeerHistory(peer);
|
App::main()->checkPeerHistory(peer);
|
||||||
}
|
}
|
||||||
|
@ -1482,7 +1494,7 @@ void History::clear(bool leaveItems) {
|
||||||
showFrom = 0;
|
showFrom = 0;
|
||||||
}
|
}
|
||||||
if (!leaveItems) {
|
if (!leaveItems) {
|
||||||
lastMsg = 0;
|
setLastMessage(0);
|
||||||
}
|
}
|
||||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||||
if (!_overview[i].isEmpty() || !_overviewIds[i].isEmpty()) {
|
if (!_overview[i].isEmpty() || !_overviewIds[i].isEmpty()) {
|
||||||
|
|
|
@ -204,6 +204,7 @@ struct History : public QList<HistoryBlock*> {
|
||||||
bool isReadyFor(MsgId msgId, bool check = false) const; // has messages for showing history at msgId
|
bool isReadyFor(MsgId msgId, bool check = false) const; // has messages for showing history at msgId
|
||||||
void getReadyFor(MsgId msgId);
|
void getReadyFor(MsgId msgId);
|
||||||
|
|
||||||
|
void setLastMessage(HistoryItem *msg);
|
||||||
void fixLastMessage(bool wasAtBottom);
|
void fixLastMessage(bool wasAtBottom);
|
||||||
|
|
||||||
MsgId minMsgId() const;
|
MsgId minMsgId() const;
|
||||||
|
@ -218,6 +219,7 @@ struct History : public QList<HistoryBlock*> {
|
||||||
PeerData *peer;
|
PeerData *peer;
|
||||||
bool oldLoaded, newLoaded;
|
bool oldLoaded, newLoaded;
|
||||||
HistoryItem *lastMsg;
|
HistoryItem *lastMsg;
|
||||||
|
QDateTime lastMsgDate;
|
||||||
|
|
||||||
typedef QList<HistoryItem*> NotifyQueue;
|
typedef QList<HistoryItem*> NotifyQueue;
|
||||||
NotifyQueue notifies;
|
NotifyQueue notifies;
|
||||||
|
@ -446,11 +448,11 @@ struct DialogsList {
|
||||||
|
|
||||||
DialogRow *row = addToEnd(history), *change = row;
|
DialogRow *row = addToEnd(history), *change = row;
|
||||||
const QString &peerName(history->peer->name);
|
const QString &peerName(history->peer->name);
|
||||||
while (change->prev && change->prev->history->peer->name > peerName) {
|
while (change->prev && change->prev->history->peer->name.compare(peerName, Qt::CaseInsensitive) > 0) {
|
||||||
change = change->prev;
|
change = change->prev;
|
||||||
}
|
}
|
||||||
if (!insertBefore(row, change)) {
|
if (!insertBefore(row, change)) {
|
||||||
while (change->next != end && change->next->history->peer->name < peerName) {
|
while (change->next != end && change->next->history->peer->name.compare(peerName, Qt::CaseInsensitive) < 0) {
|
||||||
change = change->next;
|
change = change->next;
|
||||||
}
|
}
|
||||||
insertAfter(row, change);
|
insertAfter(row, change);
|
||||||
|
|
|
@ -2724,7 +2724,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_history->mySendActions.contains(SendActionTyping)) updateSendAction(_history, SendActionTyping, false);
|
if (_history->mySendActions.contains(SendActionTyping)) updateSendAction(_history, SendActionTyping, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopGif();
|
stopGif();
|
||||||
|
@ -2912,7 +2912,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
} else {
|
} else {
|
||||||
_scroll.show();
|
_scroll.show();
|
||||||
}
|
}
|
||||||
if (!_peer->chat || !_peer->asChat()->forbidden) {
|
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
|
||||||
checkMentionDropdown();
|
checkMentionDropdown();
|
||||||
if (isBotStart()) {
|
if (isBotStart()) {
|
||||||
if (_botStart.isHidden()) {
|
if (_botStart.isHidden()) {
|
||||||
|
@ -4002,7 +4002,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
|
||||||
int32 t = unixtime();
|
int32 t = unixtime();
|
||||||
if (_peer->chat) {
|
if (_peer->chat) {
|
||||||
ChatData *chat = _peer->asChat();
|
ChatData *chat = _peer->asChat();
|
||||||
if (chat->forbidden) {
|
if (chat->forbidden || chat->left) {
|
||||||
text = lang(lng_chat_status_unaccessible);
|
text = lang(lng_chat_status_unaccessible);
|
||||||
} else if (chat->participants.isEmpty()) {
|
} else if (chat->participants.isEmpty()) {
|
||||||
text = _titlePeerText.isEmpty() ? lng_chat_status_members(lt_count, chat->count < 0 ? 0 : chat->count) : _titlePeerText;
|
text = _titlePeerText.isEmpty() ? lng_chat_status_members(lt_count, chat->count < 0 ? 0 : chat->count) : _titlePeerText;
|
||||||
|
@ -4391,7 +4391,7 @@ void HistoryWidget::onAudioProgress(MsgId newId) {
|
||||||
HistoryItem *item = App::histItemById(newId);
|
HistoryItem *item = App::histItemById(newId);
|
||||||
if (item) {
|
if (item) {
|
||||||
AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast<HistoryAudio*>(item->getMedia())->audio() : 0;
|
AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast<HistoryAudio*>(item->getMedia())->audio() : 0;
|
||||||
updateSendAction(item->history(), SendActionUploadAudio, audio->uploadOffset);
|
updateSendAction(item->history(), SendActionUploadAudio, audio ? audio->uploadOffset : 0);
|
||||||
msgUpdated(item->history()->peer->id, item);
|
msgUpdated(item->history()->peer->id, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4540,7 +4540,7 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
|
||||||
if (isBotStart()) {
|
if (isBotStart()) {
|
||||||
newScrollHeight -= _botStart.height();
|
newScrollHeight -= _botStart.height();
|
||||||
} else {
|
} else {
|
||||||
if (!_peer->chat || !_peer->asChat()->forbidden) {
|
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
|
||||||
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
|
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
|
||||||
}
|
}
|
||||||
if (replyToId() || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
|
if (replyToId() || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
|
#include "mainwidget.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -505,6 +506,7 @@ namespace {
|
||||||
lskUserSettings = 0x09, // no data
|
lskUserSettings = 0x09, // no data
|
||||||
lskRecentHashtags = 0x0a, // no data
|
lskRecentHashtags = 0x0a, // no data
|
||||||
lskStickers = 0x0b, // no data
|
lskStickers = 0x0b, // no data
|
||||||
|
lskSavedPeers = 0x0c, // no data
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QMap<PeerId, FileKey> DraftsMap;
|
typedef QMap<PeerId, FileKey> DraftsMap;
|
||||||
|
@ -530,6 +532,8 @@ namespace {
|
||||||
FileKey _recentHashtagsKey = 0;
|
FileKey _recentHashtagsKey = 0;
|
||||||
bool _recentHashtagsWereRead = false;
|
bool _recentHashtagsWereRead = false;
|
||||||
|
|
||||||
|
FileKey _savedPeersKey = 0;
|
||||||
|
|
||||||
typedef QPair<FileKey, qint32> FileDesc; // file, size
|
typedef QPair<FileKey, qint32> FileDesc; // file, size
|
||||||
typedef QMap<StorageKey, FileDesc> StorageMap;
|
typedef QMap<StorageKey, FileDesc> StorageMap;
|
||||||
StorageMap _imagesMap, _stickerImagesMap, _audiosMap;
|
StorageMap _imagesMap, _stickerImagesMap, _audiosMap;
|
||||||
|
@ -1432,7 +1436,7 @@ namespace {
|
||||||
DraftsNotReadMap draftsNotReadMap;
|
DraftsNotReadMap draftsNotReadMap;
|
||||||
StorageMap imagesMap, stickerImagesMap, audiosMap;
|
StorageMap imagesMap, stickerImagesMap, audiosMap;
|
||||||
qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0;
|
qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0;
|
||||||
quint64 locationsKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0;
|
quint64 locationsKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0, savedPeersKey = 0;
|
||||||
while (!map.stream.atEnd()) {
|
while (!map.stream.atEnd()) {
|
||||||
quint32 keyType;
|
quint32 keyType;
|
||||||
map.stream >> keyType;
|
map.stream >> keyType;
|
||||||
|
@ -1512,6 +1516,9 @@ namespace {
|
||||||
case lskStickers: {
|
case lskStickers: {
|
||||||
map.stream >> stickersKey;
|
map.stream >> stickersKey;
|
||||||
} break;
|
} break;
|
||||||
|
case lskSavedPeers: {
|
||||||
|
map.stream >> savedPeersKey;
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
|
LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
|
||||||
return Local::ReadMapFailed;
|
return Local::ReadMapFailed;
|
||||||
|
@ -1535,6 +1542,7 @@ namespace {
|
||||||
_locationsKey = locationsKey;
|
_locationsKey = locationsKey;
|
||||||
_recentStickersKeyOld = recentStickersKeyOld;
|
_recentStickersKeyOld = recentStickersKeyOld;
|
||||||
_stickersKey = stickersKey;
|
_stickersKey = stickersKey;
|
||||||
|
_savedPeersKey = savedPeersKey;
|
||||||
_backgroundKey = backgroundKey;
|
_backgroundKey = backgroundKey;
|
||||||
_userSettingsKey = userSettingsKey;
|
_userSettingsKey = userSettingsKey;
|
||||||
_recentHashtagsKey = recentHashtagsKey;
|
_recentHashtagsKey = recentHashtagsKey;
|
||||||
|
@ -1599,6 +1607,7 @@ namespace {
|
||||||
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_stickersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_stickersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
|
if (_savedPeersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_backgroundKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_backgroundKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_userSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_userSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_recentHashtagsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_recentHashtagsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
|
@ -1642,6 +1651,9 @@ namespace {
|
||||||
if (_stickersKey) {
|
if (_stickersKey) {
|
||||||
mapData.stream << quint32(lskStickers) << quint64(_stickersKey);
|
mapData.stream << quint32(lskStickers) << quint64(_stickersKey);
|
||||||
}
|
}
|
||||||
|
if (_savedPeersKey) {
|
||||||
|
mapData.stream << quint32(lskSavedPeers) << quint64(_savedPeersKey);
|
||||||
|
}
|
||||||
if (_backgroundKey) {
|
if (_backgroundKey) {
|
||||||
mapData.stream << quint32(lskBackground) << quint64(_backgroundKey);
|
mapData.stream << quint32(lskBackground) << quint64(_backgroundKey);
|
||||||
}
|
}
|
||||||
|
@ -1900,7 +1912,7 @@ namespace Local {
|
||||||
_draftsNotReadMap.clear();
|
_draftsNotReadMap.clear();
|
||||||
_stickerImagesMap.clear();
|
_stickerImagesMap.clear();
|
||||||
_audiosMap.clear();
|
_audiosMap.clear();
|
||||||
_locationsKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = 0;
|
_locationsKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0;
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
_writeMap(WriteMapNow);
|
_writeMap(WriteMapNow);
|
||||||
|
|
||||||
|
@ -2293,6 +2305,23 @@ namespace Local {
|
||||||
return _storageAudiosSize;
|
return _storageAudiosSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _writeStorageImageLocation(QDataStream &stream, const StorageImageLocation &loc) {
|
||||||
|
stream << qint32(loc.width) << qint32(loc.height);
|
||||||
|
stream << qint32(loc.dc) << quint64(loc.volume) << qint32(loc.local) << quint64(loc.secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 _storageImageLocationSize() {
|
||||||
|
// width + height + dc + volume + local + secret
|
||||||
|
return sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
||||||
|
}
|
||||||
|
|
||||||
|
StorageImageLocation _readStorageImageLocation(FileReadDescriptor &from) {
|
||||||
|
qint32 thumbWidth, thumbHeight, thumbDc, thumbLocal;
|
||||||
|
quint64 thumbVolume, thumbSecret;
|
||||||
|
from.stream >> thumbWidth >> thumbHeight >> thumbDc >> thumbVolume >> thumbLocal >> thumbSecret;
|
||||||
|
return StorageImageLocation(thumbWidth, thumbHeight, thumbDc, thumbVolume, thumbLocal, thumbSecret);
|
||||||
|
}
|
||||||
|
|
||||||
void _writeStickerSet(QDataStream &stream, uint64 setId) {
|
void _writeStickerSet(QDataStream &stream, uint64 setId) {
|
||||||
StickerSets::const_iterator it = cStickerSets().constFind(setId);
|
StickerSets::const_iterator it = cStickerSets().constFind(setId);
|
||||||
if (it == cStickerSets().cend()) return;
|
if (it == cStickerSets().cend()) return;
|
||||||
|
@ -2321,8 +2350,7 @@ namespace Local {
|
||||||
stream << qint32(StickerSetTypeEmpty);
|
stream << qint32(StickerSetTypeEmpty);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
const StorageImageLocation &loc(doc->sticker()->loc);
|
_writeStorageImageLocation(stream, doc->sticker()->loc);
|
||||||
stream << qint32(loc.width) << qint32(loc.height) << qint32(loc.dc) << quint64(loc.volume) << qint32(loc.local) << quint64(loc.secret);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2358,8 +2386,8 @@ namespace Local {
|
||||||
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt + type-of-set
|
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt + type-of-set
|
||||||
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->sticker()->alt) + sizeof(qint32);
|
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->sticker()->alt) + sizeof(qint32);
|
||||||
|
|
||||||
// thumb-width + thumb-height + thumb-dc + thumb-volume + thumb-local + thumb-secret
|
// loc
|
||||||
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
size += _storageImageLocationSize();
|
||||||
}
|
}
|
||||||
++setsCount;
|
++setsCount;
|
||||||
}
|
}
|
||||||
|
@ -2519,9 +2547,7 @@ namespace Local {
|
||||||
qint32 date, dc, size, width, height, type, typeOfSet;
|
qint32 date, dc, size, width, height, type, typeOfSet;
|
||||||
stickers.stream >> id >> access >> date >> name >> mime >> dc >> size >> width >> height >> type >> alt >> typeOfSet;
|
stickers.stream >> id >> access >> date >> name >> mime >> dc >> size >> width >> height >> type >> alt >> typeOfSet;
|
||||||
|
|
||||||
qint32 thumbWidth, thumbHeight, thumbDc, thumbLocal;
|
StorageImageLocation thumb(_readStorageImageLocation(stickers));
|
||||||
quint64 thumbVolume, thumbSecret;
|
|
||||||
stickers.stream >> thumbWidth >> thumbHeight >> thumbDc >> thumbVolume >> thumbLocal >> thumbSecret;
|
|
||||||
|
|
||||||
if (read.contains(id)) continue;
|
if (read.contains(id)) continue;
|
||||||
read.insert(id, true);
|
read.insert(id, true);
|
||||||
|
@ -2552,7 +2578,6 @@ namespace Local {
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageImageLocation thumb(thumbWidth, thumbHeight, thumbDc, thumbVolume, thumbLocal, thumbSecret);
|
|
||||||
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.dc ? ImagePtr(thumb) : ImagePtr(), dc, size, thumb);
|
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.dc ? ImagePtr(thumb) : ImagePtr(), dc, size, thumb);
|
||||||
if (!doc->sticker()) continue;
|
if (!doc->sticker()) continue;
|
||||||
|
|
||||||
|
@ -2705,6 +2730,193 @@ namespace Local {
|
||||||
cSetRecentSearchHashtags(search);
|
cSetRecentSearchHashtags(search);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 _peerSize(PeerData *peer) {
|
||||||
|
uint32 result = sizeof(quint64) + sizeof(quint64) + _storageImageLocationSize();
|
||||||
|
if (peer->chat) {
|
||||||
|
ChatData *chat = peer->asChat();
|
||||||
|
|
||||||
|
// name + count + date + version + admin + forbidden + left + invitationUrl
|
||||||
|
result += _stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(chat->invitationUrl);
|
||||||
|
} else {
|
||||||
|
UserData *user = peer->asUser();
|
||||||
|
|
||||||
|
// first + last + phone + username + access + onlineTill + contact + botInfoVersion
|
||||||
|
result += _stringSize(user->firstName) + _stringSize(user->lastName) + _stringSize(user->phone) + _stringSize(user->username) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _writePeer(QDataStream &stream, PeerData *peer) {
|
||||||
|
stream << quint64(peer->id) << quint64(peer->photoId);
|
||||||
|
_writeStorageImageLocation(stream, peer->photoLoc);
|
||||||
|
if (peer->chat) {
|
||||||
|
ChatData *chat = peer->asChat();
|
||||||
|
|
||||||
|
stream << chat->name << qint32(chat->count) << qint32(chat->date) << qint32(chat->version) << qint32(chat->admin);
|
||||||
|
stream << qint32(chat->forbidden ? 1 : 0) << qint32(chat->left ? 1 : 0) << chat->invitationUrl;
|
||||||
|
} else {
|
||||||
|
UserData *user = peer->asUser();
|
||||||
|
|
||||||
|
stream << user->firstName << user->lastName << user->phone << user->username << quint64(user->access) << qint32(user->onlineTill) << qint32(user->contact) << qint32(user->botInfo ? user->botInfo->version : -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerData *_readPeer(FileReadDescriptor &from) {
|
||||||
|
PeerData *result = 0;
|
||||||
|
quint64 peerId = 0, photoId = 0;
|
||||||
|
from.stream >> peerId >> photoId;
|
||||||
|
|
||||||
|
StorageImageLocation photoLoc(_readStorageImageLocation(from));
|
||||||
|
|
||||||
|
result = App::peer(peerId);
|
||||||
|
result->loaded = true;
|
||||||
|
if (result->chat) {
|
||||||
|
ChatData *chat = result->asChat();
|
||||||
|
|
||||||
|
QString name, invitationUrl;
|
||||||
|
qint32 count, date, version, admin, forbidden, left;
|
||||||
|
from.stream >> name >> count >> date >> version >> admin >> forbidden >> left >> invitationUrl;
|
||||||
|
|
||||||
|
chat->updateName(name, QString(), QString());
|
||||||
|
chat->count = count;
|
||||||
|
chat->date = date;
|
||||||
|
chat->version = version;
|
||||||
|
chat->admin = admin;
|
||||||
|
chat->forbidden = (forbidden == 1);
|
||||||
|
chat->left = (left == 1);
|
||||||
|
chat->invitationUrl = invitationUrl;
|
||||||
|
|
||||||
|
chat->input = MTP_inputPeerChat(MTP_int(App::chatFromPeer(chat->id)));
|
||||||
|
|
||||||
|
chat->photo = photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc);
|
||||||
|
} else {
|
||||||
|
UserData *user = result->asUser();
|
||||||
|
|
||||||
|
QString first, last, phone, username;
|
||||||
|
quint64 access;
|
||||||
|
qint32 onlineTill, contact, botInfoVersion;
|
||||||
|
from.stream >> first >> last >> phone >> username >> access >> onlineTill >> contact >> botInfoVersion;
|
||||||
|
|
||||||
|
bool showPhone = !isServiceUser(user->id) && (user->id != MTP::authedId()) && (contact <= 0);
|
||||||
|
QString pname = (showPhone && !phone.isEmpty()) ? App::formatPhone(phone) : QString();
|
||||||
|
|
||||||
|
user->setName(first, last, pname, username);
|
||||||
|
|
||||||
|
user->access = access;
|
||||||
|
user->onlineTill = onlineTill;
|
||||||
|
user->contact = contact;
|
||||||
|
user->setBotInfoVersion(botInfoVersion);
|
||||||
|
|
||||||
|
if (user->id == MTP::authedId()) {
|
||||||
|
user->input = MTP_inputPeerSelf();
|
||||||
|
user->inputUser = MTP_inputUserSelf();
|
||||||
|
} else if (user->contact > 0 || !user->access) {
|
||||||
|
user->input = MTP_inputPeerContact(MTP_int(App::userFromPeer(user->id)));
|
||||||
|
user->inputUser = MTP_inputUserContact(MTP_int(App::userFromPeer(user->id)));
|
||||||
|
} else {
|
||||||
|
user->input = MTP_inputPeerForeign(MTP_int(App::userFromPeer(user->id)), MTP_long(user->access));
|
||||||
|
user->inputUser = MTP_inputUserForeign(MTP_int(App::userFromPeer(user->id)), MTP_long(user->access));
|
||||||
|
}
|
||||||
|
|
||||||
|
user->photo = photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc);
|
||||||
|
}
|
||||||
|
App::markPeerUpdated(result);
|
||||||
|
emit App::main()->peerPhotoChanged(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeSavedPeers() {
|
||||||
|
if (!_working()) return;
|
||||||
|
|
||||||
|
const SavedPeers &saved(cSavedPeers());
|
||||||
|
if (saved.isEmpty()) {
|
||||||
|
if (_savedPeersKey) {
|
||||||
|
clearKey(_savedPeersKey);
|
||||||
|
_savedPeersKey = 0;
|
||||||
|
_mapChanged = true;
|
||||||
|
}
|
||||||
|
_writeMap();
|
||||||
|
} else {
|
||||||
|
if (!_savedPeersKey) {
|
||||||
|
_savedPeersKey = genKey();
|
||||||
|
_mapChanged = true;
|
||||||
|
_writeMap(WriteMapFast);
|
||||||
|
}
|
||||||
|
quint32 size = sizeof(quint32);
|
||||||
|
for (SavedPeers::const_iterator i = saved.cbegin(); i != saved.cend(); ++i) {
|
||||||
|
size += _peerSize(i.key()) + _dateTimeSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptedDescriptor data(size);
|
||||||
|
data.stream << quint32(saved.size());
|
||||||
|
for (SavedPeers::const_iterator i = saved.cbegin(); i != saved.cend(); ++i) {
|
||||||
|
_writePeer(data.stream, i.key());
|
||||||
|
data.stream << i.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileWriteDescriptor file(_savedPeersKey);
|
||||||
|
file.writeEncrypted(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void readSavedPeers() {
|
||||||
|
if (!_savedPeersKey) return;
|
||||||
|
|
||||||
|
FileReadDescriptor saved;
|
||||||
|
if (!readEncryptedFile(saved, _savedPeersKey)) {
|
||||||
|
clearKey(_savedPeersKey);
|
||||||
|
_savedPeersKey = 0;
|
||||||
|
_writeMap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 count = 0;
|
||||||
|
saved.stream >> count;
|
||||||
|
cRefSavedPeers().clear();
|
||||||
|
cRefSavedPeersByTime().clear();
|
||||||
|
QList<PeerData*> peers;
|
||||||
|
peers.reserve(count);
|
||||||
|
for (uint32 i = 0; i < count; ++i) {
|
||||||
|
PeerData *peer = _readPeer(saved);
|
||||||
|
if (!peer) break;
|
||||||
|
|
||||||
|
QDateTime t;
|
||||||
|
saved.stream >> t;
|
||||||
|
|
||||||
|
cRefSavedPeers().insert(peer, t);
|
||||||
|
cRefSavedPeersByTime().insert(t, peer);
|
||||||
|
peers.push_back(peer);
|
||||||
|
}
|
||||||
|
App::emitPeerUpdated();
|
||||||
|
App::api()->requestPeers(peers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSavedPeer(PeerData *peer, const QDateTime &position) {
|
||||||
|
SavedPeers &savedPeers(cRefSavedPeers());
|
||||||
|
SavedPeers::iterator i = savedPeers.find(peer);
|
||||||
|
if (i == savedPeers.cend()) {
|
||||||
|
savedPeers.insert(peer, position);
|
||||||
|
} else if (i.value() != position) {
|
||||||
|
cRefSavedPeersByTime().remove(i.value(), peer);
|
||||||
|
i.value() = position;
|
||||||
|
cRefSavedPeersByTime().insert(i.value(), peer);
|
||||||
|
}
|
||||||
|
writeSavedPeers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSavedPeer(PeerData *peer) {
|
||||||
|
SavedPeers &savedPeers(cRefSavedPeers());
|
||||||
|
if (savedPeers.isEmpty()) return;
|
||||||
|
|
||||||
|
SavedPeers::iterator i = savedPeers.find(peer);
|
||||||
|
if (i != savedPeers.cend()) {
|
||||||
|
cRefSavedPeersByTime().remove(i.value(), peer);
|
||||||
|
savedPeers.erase(i);
|
||||||
|
|
||||||
|
writeSavedPeers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ClearManagerData {
|
struct ClearManagerData {
|
||||||
QThread *thread;
|
QThread *thread;
|
||||||
StorageMap images, stickers, audios;
|
StorageMap images, stickers, audios;
|
||||||
|
@ -2764,6 +2976,10 @@ namespace Local {
|
||||||
_recentHashtagsKey = 0;
|
_recentHashtagsKey = 0;
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
}
|
}
|
||||||
|
if (_savedPeersKey) {
|
||||||
|
_savedPeersKey = 0;
|
||||||
|
_mapChanged = true;
|
||||||
|
}
|
||||||
_writeMap();
|
_writeMap();
|
||||||
} else {
|
} else {
|
||||||
if (task & ClearManagerStorage) {
|
if (task & ClearManagerStorage) {
|
||||||
|
|
|
@ -141,4 +141,8 @@ namespace Local {
|
||||||
void writeRecentHashtags();
|
void writeRecentHashtags();
|
||||||
void readRecentHashtags();
|
void readRecentHashtags();
|
||||||
|
|
||||||
|
void addSavedPeer(PeerData *peer, const QDateTime &position);
|
||||||
|
void removeSavedPeer(PeerData *peer);
|
||||||
|
void readSavedPeers();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -788,7 +788,7 @@ void MainWidget::deleteConversation(PeerData *peer) {
|
||||||
void MainWidget::clearHistory(PeerData *peer) {
|
void MainWidget::clearHistory(PeerData *peer) {
|
||||||
History *h = App::history(peer->id);
|
History *h = App::history(peer->id);
|
||||||
if (h->lastMsg) {
|
if (h->lastMsg) {
|
||||||
// Local::savePeerPosition(h->peer, h->lastMsg->date);
|
Local::addSavedPeer(h->peer, h->lastMsg->date);
|
||||||
}
|
}
|
||||||
h->clear();
|
h->clear();
|
||||||
h->newLoaded = h->oldLoaded = true;
|
h->newLoaded = h->oldLoaded = true;
|
||||||
|
@ -813,6 +813,8 @@ bool MainWidget::addParticipantFail(UserData *user, const RPCError &error) {
|
||||||
|
|
||||||
QString text = lang(lng_failed_add_participant);
|
QString text = lang(lng_failed_add_participant);
|
||||||
if (error.type() == "USER_LEFT_CHAT") { // trying to return banned user to his group
|
if (error.type() == "USER_LEFT_CHAT") { // trying to return banned user to his group
|
||||||
|
} else if (error.type() == "USER_NOT_MUTUAL_CONTACT") { // trying to return user who does not have me in contacts
|
||||||
|
text = lang(lng_failed_add_not_mutual);
|
||||||
} else if (error.type() == "USER_ALREADY_PARTICIPANT" && user->botInfo) {
|
} else if (error.type() == "USER_ALREADY_PARTICIPANT" && user->botInfo) {
|
||||||
text = lang(lng_bot_already_in_group);
|
text = lang(lng_bot_already_in_group);
|
||||||
}
|
}
|
||||||
|
@ -856,7 +858,12 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
|
||||||
if ((profile && profile->peer() == peer) || (overview && overview->peer() == peer) || _stack.contains(peer) || history.peer() == peer) {
|
if ((profile && profile->peer() == peer) || (overview && overview->peer() == peer) || _stack.contains(peer) || history.peer() == peer) {
|
||||||
showDialogs();
|
showDialogs();
|
||||||
}
|
}
|
||||||
|
if (peer->chat && peer->asChat()->left) {
|
||||||
dialogs.removePeer(peer);
|
dialogs.removePeer(peer);
|
||||||
|
} else {
|
||||||
|
History *h = App::historyLoaded(peer->id);
|
||||||
|
if (h) Local::addSavedPeer(peer, h->lastMsgDate);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
History *h = App::historyLoaded(peer->id);
|
History *h = App::historyLoaded(peer->id);
|
||||||
if (!h->lastMsg) {
|
if (!h->lastMsg) {
|
||||||
|
@ -2757,6 +2764,8 @@ void MainWidget::start(const MTPUser &user) {
|
||||||
Local::writeMtpData();
|
Local::writeMtpData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Local::readSavedPeers();
|
||||||
|
|
||||||
cSetOtherOnline(0);
|
cSetOtherOnline(0);
|
||||||
App::feedUsers(MTP_vector<MTPUser>(1, user));
|
App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||||
App::app()->startUpdateCheck();
|
App::app()->startUpdateCheck();
|
||||||
|
|
|
@ -159,6 +159,9 @@ int gOtherOnline = 0;
|
||||||
|
|
||||||
float64 gSongVolume = 0.9;
|
float64 gSongVolume = 0.9;
|
||||||
|
|
||||||
|
SavedPeers gSavedPeers;
|
||||||
|
SavedPeersByTime gSavedPeersByTime;
|
||||||
|
|
||||||
void settingsParseArgs(int argc, char *argv[]) {
|
void settingsParseArgs(int argc, char *argv[]) {
|
||||||
gCustomNotifies = true;
|
gCustomNotifies = true;
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
|
|
@ -308,4 +308,10 @@ DeclareSetting(int, OtherOnline);
|
||||||
|
|
||||||
DeclareSetting(float64, SongVolume);
|
DeclareSetting(float64, SongVolume);
|
||||||
|
|
||||||
|
struct PeerData;
|
||||||
|
typedef QMap<PeerData*, QDateTime> SavedPeers;
|
||||||
|
typedef QMultiMap<QDateTime, PeerData*> SavedPeersByTime;
|
||||||
|
DeclareRefSetting(SavedPeers, SavedPeers);
|
||||||
|
DeclareRefSetting(SavedPeersByTime, SavedPeersByTime);
|
||||||
|
|
||||||
void settingsParseArgs(int argc, char *argv[]);
|
void settingsParseArgs(int argc, char *argv[]);
|
||||||
|
|
|
@ -90,10 +90,10 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP
|
||||||
PeerData::PeerData(const PeerId &id) : id(id)
|
PeerData::PeerData(const PeerId &id) : id(id)
|
||||||
, loaded(false)
|
, loaded(false)
|
||||||
, chat(App::isChat(id))
|
, chat(App::isChat(id))
|
||||||
, access(0)
|
|
||||||
, colorIndex(peerColorIndex(id))
|
, colorIndex(peerColorIndex(id))
|
||||||
, color(peerColor(colorIndex))
|
, color(peerColor(colorIndex))
|
||||||
, photo(chat ? chatDefPhoto(colorIndex) : userDefPhoto(colorIndex))
|
, photo(chat ? chatDefPhoto(colorIndex) : userDefPhoto(colorIndex))
|
||||||
|
, photoId(UnknownPeerPhotoId)
|
||||||
, nameVersion(0)
|
, nameVersion(0)
|
||||||
, notify(UnknownNotifySettings)
|
, notify(UnknownNotifySettings)
|
||||||
{
|
{
|
||||||
|
@ -132,14 +132,16 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserData::setPhoto(const MTPUserProfilePhoto &p) {
|
void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well
|
||||||
PhotoId newPhotoId = photoId;
|
PhotoId newPhotoId = photoId;
|
||||||
ImagePtr newPhoto = photo;
|
ImagePtr newPhoto = photo;
|
||||||
|
StorageImageLocation newPhotoLoc = photoLoc;
|
||||||
switch (p.type()) {
|
switch (p.type()) {
|
||||||
case mtpc_userProfilePhoto: {
|
case mtpc_userProfilePhoto: {
|
||||||
const MTPDuserProfilePhoto d(p.c_userProfilePhoto());
|
const MTPDuserProfilePhoto d(p.c_userProfilePhoto());
|
||||||
newPhotoId = d.vphoto_id.v;
|
newPhotoId = d.vphoto_id.v;
|
||||||
newPhoto = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex));
|
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||||
|
newPhoto = newPhotoLoc.isNull() ? userDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
||||||
//App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
|
//App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
|
@ -151,11 +153,13 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) {
|
||||||
} else {
|
} else {
|
||||||
newPhoto = userDefPhoto(colorIndex);
|
newPhoto = userDefPhoto(colorIndex);
|
||||||
}
|
}
|
||||||
|
newPhotoLoc = StorageImageLocation();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
if (newPhotoId != photoId || newPhoto.v() != photo.v()) {
|
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) {
|
||||||
photoId = newPhotoId;
|
photoId = newPhotoId;
|
||||||
photo = newPhoto;
|
photo = newPhoto;
|
||||||
|
photoLoc = newPhotoLoc;
|
||||||
emit App::main()->peerPhotoChanged(this);
|
emit App::main()->peerPhotoChanged(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +230,7 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||||
botInfo->inited = false;
|
botInfo->inited = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserData::setBotInfo(const MTPBotInfo &info) {
|
void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||||
switch (info.type()) {
|
switch (info.type()) {
|
||||||
case mtpc_botInfoEmpty:
|
case mtpc_botInfoEmpty:
|
||||||
|
@ -305,24 +310,34 @@ void UserData::madeAction() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) {
|
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well
|
||||||
|
PhotoId newPhotoId = photoId;
|
||||||
|
ImagePtr newPhoto = photo;
|
||||||
|
StorageImageLocation newPhotoLoc = photoLoc;
|
||||||
switch (p.type()) {
|
switch (p.type()) {
|
||||||
case mtpc_chatPhoto: {
|
case mtpc_chatPhoto: {
|
||||||
const MTPDchatPhoto d(p.c_chatPhoto());
|
const MTPDchatPhoto d(p.c_chatPhoto());
|
||||||
photo = ImagePtr(160, 160, d.vphoto_small, chatDefPhoto(colorIndex));
|
|
||||||
photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
|
||||||
if (phId != UnknownPeerPhotoId) {
|
if (phId != UnknownPeerPhotoId) {
|
||||||
photoId = phId;
|
newPhotoId = phId;
|
||||||
}
|
}
|
||||||
|
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||||
|
newPhoto = newPhotoLoc.isNull() ? chatDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
||||||
|
// photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
photo = chatDefPhoto(colorIndex);
|
newPhotoId = 0;
|
||||||
photoFull = ImagePtr();
|
newPhotoLoc = StorageImageLocation();
|
||||||
photoId = 0;
|
newPhoto = chatDefPhoto(colorIndex);
|
||||||
|
// photoFull = ImagePtr();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) {
|
||||||
|
photoId = newPhotoId;
|
||||||
|
photo = newPhoto;
|
||||||
|
photoLoc = newPhotoLoc;
|
||||||
emit App::main()->peerPhotoChanged(this);
|
emit App::main()->peerPhotoChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PhotoLink::onClick(Qt::MouseButton button) const {
|
void PhotoLink::onClick(Qt::MouseButton button) const {
|
||||||
if (button == Qt::LeftButton) {
|
if (button == Qt::LeftButton) {
|
||||||
|
|
|
@ -59,8 +59,10 @@ style::color peerColor(int32 index);
|
||||||
ImagePtr userDefPhoto(int32 index);
|
ImagePtr userDefPhoto(int32 index);
|
||||||
ImagePtr chatDefPhoto(int32 index);
|
ImagePtr chatDefPhoto(int32 index);
|
||||||
|
|
||||||
struct ChatData;
|
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
|
||||||
struct UserData;
|
struct UserData;
|
||||||
|
struct ChatData;
|
||||||
struct PeerData {
|
struct PeerData {
|
||||||
PeerData(const PeerId &id);
|
PeerData(const PeerId &id);
|
||||||
virtual ~PeerData() {
|
virtual ~PeerData() {
|
||||||
|
@ -94,13 +96,13 @@ struct PeerData {
|
||||||
|
|
||||||
bool loaded;
|
bool loaded;
|
||||||
bool chat;
|
bool chat;
|
||||||
uint64 access;
|
|
||||||
MTPinputPeer input;
|
MTPinputPeer input;
|
||||||
MTPinputUser inputUser;
|
|
||||||
|
|
||||||
int32 colorIndex;
|
int32 colorIndex;
|
||||||
style::color color;
|
style::color color;
|
||||||
ImagePtr photo;
|
ImagePtr photo;
|
||||||
|
PhotoId photoId;
|
||||||
|
StorageImageLocation photoLoc;
|
||||||
|
|
||||||
int32 nameVersion;
|
int32 nameVersion;
|
||||||
|
|
||||||
|
@ -165,11 +167,9 @@ struct BotInfo {
|
||||||
QString startToken, startGroupToken;
|
QString startToken, startGroupToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
|
||||||
|
|
||||||
struct PhotoData;
|
struct PhotoData;
|
||||||
struct UserData : public PeerData {
|
struct UserData : public PeerData {
|
||||||
UserData(const PeerId &id) : PeerData(id), photoId(UnknownPeerPhotoId), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
UserData(const PeerId &id) : PeerData(id), access(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPUserProfilePhoto &photo);
|
void setPhoto(const MTPUserProfilePhoto &photo);
|
||||||
void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username);
|
void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username);
|
||||||
|
@ -180,12 +180,15 @@ struct UserData : public PeerData {
|
||||||
|
|
||||||
void madeAction(); // pseudo-online
|
void madeAction(); // pseudo-online
|
||||||
|
|
||||||
|
uint64 access;
|
||||||
|
|
||||||
|
MTPinputUser inputUser;
|
||||||
|
|
||||||
QString firstName;
|
QString firstName;
|
||||||
QString lastName;
|
QString lastName;
|
||||||
QString username;
|
QString username;
|
||||||
QString phone;
|
QString phone;
|
||||||
Text nameText;
|
Text nameText;
|
||||||
PhotoId photoId;
|
|
||||||
TextLinkPtr lnk;
|
TextLinkPtr lnk;
|
||||||
int32 onlineTill;
|
int32 onlineTill;
|
||||||
int32 contact; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact
|
int32 contact; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact
|
||||||
|
@ -198,7 +201,7 @@ struct UserData : public PeerData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChatData : public PeerData {
|
struct ChatData : public PeerData {
|
||||||
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(UnknownPeerPhotoId) {
|
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0) {
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||||
int32 count;
|
int32 count;
|
||||||
|
@ -216,8 +219,7 @@ struct ChatData : public PeerData {
|
||||||
typedef QMap<UserData*, bool> MarkupSenders;
|
typedef QMap<UserData*, bool> MarkupSenders;
|
||||||
MarkupSenders markupSenders;
|
MarkupSenders markupSenders;
|
||||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||||
ImagePtr photoFull;
|
// ImagePtr photoFull;
|
||||||
PhotoId photoId;
|
|
||||||
QString invitationUrl;
|
QString invitationUrl;
|
||||||
// geo
|
// geo
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.8.46</string>
|
<string>0.8.47</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
|
|
Binary file not shown.
|
@ -130,6 +130,7 @@
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<AdditionalOptions>/Zm110 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
|
@ -1707,7 +1707,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.8.46;
|
CURRENT_PROJECT_VERSION = 0.8.47;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
@ -1725,7 +1725,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 0.8.46;
|
CURRENT_PROJECT_VERSION = 0.8.47;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_OPTIMIZATION_LEVEL = fast;
|
GCC_OPTIMIZATION_LEVEL = fast;
|
||||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||||
|
@ -1751,10 +1751,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.8.46;
|
CURRENT_PROJECT_VERSION = 0.8.47;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||||
DYLIB_CURRENT_VERSION = 0.8.46;
|
DYLIB_CURRENT_VERSION = 0.8.47;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
|
@ -1885,10 +1885,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.8.46;
|
CURRENT_PROJECT_VERSION = 0.8.47;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||||
DYLIB_CURRENT_VERSION = 0.8.46;
|
DYLIB_CURRENT_VERSION = 0.8.47;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
echo 0.8 8046 0.8.46 0
|
echo 0.8 8047 0.8.47 1
|
||||||
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
||||||
|
|
Loading…
Reference in New Issue