mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Merge branch 'dev'
This commit is contained in:
commit
b19467bb07
52 changed files with 2878 additions and 791 deletions
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "New message text..";
|
"lng_edit_message_text" = "New message text..";
|
||||||
"lng_deleted" = "Unknown";
|
"lng_deleted" = "Unknown";
|
||||||
"lng_deleted_message" = "Deleted message";
|
"lng_deleted_message" = "Deleted message";
|
||||||
|
"lng_pinned_message" = "Pinned message";
|
||||||
|
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
|
||||||
|
"lng_pinned_pin_sure" = "Would you like to pin this message?";
|
||||||
|
"lng_pinned_pin" = "Pin";
|
||||||
|
"lng_pinned_unpin" = "Unpin";
|
||||||
|
"lng_pinned_notify" = "Notify all members";
|
||||||
|
|
||||||
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
||||||
"lng_start_msgs" = "START MESSAGING";
|
"lng_start_msgs" = "START MESSAGING";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Add Members";
|
"lng_profile_add_participant" = "Add Members";
|
||||||
"lng_profile_delete_and_exit" = "Leave";
|
"lng_profile_delete_and_exit" = "Leave";
|
||||||
"lng_profile_kick" = "Remove";
|
"lng_profile_kick" = "Remove";
|
||||||
|
"lng_profile_admin" = "admin";
|
||||||
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
||||||
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
||||||
"lng_profile_sure_kick_admin" = "Remove {user} from administrators?";
|
"lng_profile_sure_kick_admin" = "Remove {user} from administrators?";
|
||||||
|
@ -469,13 +476,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Next";
|
"lng_create_group_next" = "Next";
|
||||||
"lng_create_group_create" = "Create";
|
"lng_create_group_create" = "Create";
|
||||||
"lng_create_group_title" = "New Group";
|
"lng_create_group_title" = "New Group";
|
||||||
"lng_create_group_about" = "Groups are ideal for smaller communities,\nthey can have up to {count:_not_used|# member|# members}";
|
"lng_create_group_about" = "Groups are ideal for limited communities,\nthey can have up to {count:_not_used|# member|# members}";
|
||||||
"lng_create_channel_title" = "New Channel";
|
"lng_create_channel_title" = "New Channel";
|
||||||
"lng_create_channel_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
"lng_create_channel_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
||||||
"lng_create_public_channel_title" = "Public Channel";
|
"lng_create_public_channel_title" = "Public Channel";
|
||||||
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
||||||
"lng_create_private_channel_title" = "Private Channel";
|
"lng_create_private_channel_title" = "Private Channel";
|
||||||
"lng_create_private_channel_about" = "Only people with a special invite link may join";
|
"lng_create_private_channel_about" = "Only people with a special invite link may join";
|
||||||
|
"lng_create_public_group_title" = "Public Group";
|
||||||
|
"lng_create_public_group_about" = "Anyone can find the group in search and join, chat history is available to everybody";
|
||||||
|
"lng_create_private_group_title" = "Private Group";
|
||||||
|
"lng_create_private_group_about" = "People can only join if they were invited or have an invite link";
|
||||||
"lng_create_channel_comments" = "Enable Comments";
|
"lng_create_channel_comments" = "Enable Comments";
|
||||||
"lng_create_channel_comments_about" = "If you enable comments, members will be able to discuss your posts in the channel";
|
"lng_create_channel_comments_about" = "If you enable comments, members will be able to discuss your posts in the channel";
|
||||||
"lng_create_group_skip" = "Skip";
|
"lng_create_group_skip" = "Skip";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} created group «{title}»";
|
"lng_action_created_chat" = "{from} created group «{title}»";
|
||||||
"lng_action_created_channel" = "Channel «{title}» created";
|
"lng_action_created_channel" = "Channel «{title}» created";
|
||||||
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
|
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
|
||||||
|
"lng_action_pinned_message" = "{from} pinned «{text}»";
|
||||||
|
"lng_action_pinned_media" = "{from} pinned {media}";
|
||||||
|
"lng_action_pinned_media_photo" = "a photo";
|
||||||
|
"lng_action_pinned_media_video" = "a video file";
|
||||||
|
"lng_action_pinned_media_audio" = "an audio file";
|
||||||
|
"lng_action_pinned_media_voice" = "a voice message";
|
||||||
|
"lng_action_pinned_media_file" = "a file";
|
||||||
|
"lng_action_pinned_media_gif" = "a GIF animation";
|
||||||
|
"lng_action_pinned_media_contact" = "a contact information";
|
||||||
|
"lng_action_pinned_media_location" = "a location mark";
|
||||||
|
"lng_action_pinned_media_sticker" = "a sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# member|# members} limit reached";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# member|# members} limit reached";
|
||||||
"lng_profile_migrate_about" = "If you'd like to go over this limit, you can upgrade your group to a supergroup. In supergroups:";
|
"lng_profile_migrate_about" = "If you'd like to go over this limit, you can upgrade your group to a supergroup. In supergroups:";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— Notifications are muted by default";
|
"lng_profile_migrate_feature4" = "— Notifications are muted by default";
|
||||||
"lng_profile_migrate_button" = "Upgrade to supergroup";
|
"lng_profile_migrate_button" = "Upgrade to supergroup";
|
||||||
"lng_profile_migrate_sure" = "Are you sure you want to upgrade this group to supergroup? This action cannot be undone.";
|
"lng_profile_migrate_sure" = "Are you sure you want to upgrade this group to supergroup? This action cannot be undone.";
|
||||||
|
"lng_profile_convert_button" = "Convert to supergroup";
|
||||||
|
"lng_profile_convert_title" = "Convert to supergroup";
|
||||||
|
"lng_profile_convert_about" = "In supergroups:";
|
||||||
|
"lng_profile_convert_feature1" = "— New members see the full message history";
|
||||||
|
"lng_profile_convert_feature2" = "— Messages are deleted for all members";
|
||||||
|
"lng_profile_convert_feature3" = "— Members can edit their own messages";
|
||||||
|
"lng_profile_convert_feature4" = "— Creator can set a public link for the group";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Note:{bold_end} This action can not be undone";
|
||||||
|
"lng_profile_convert_confirm" = "Convert";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "You will be able to add up to {count:_not_used_|# member|# members} after you upgrade your group to a supergroup.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# comment|# comments}";
|
"lng_channel_comments_count" = "{count:_not_used_|# comment|# comments}";
|
||||||
"lng_channel_hide_comments" = "Hide comments";
|
"lng_channel_hide_comments" = "Hide comments";
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Ban User";
|
||||||
|
"lng_delete_all_from" = "Delete all from this user";
|
||||||
"lng_report_spam" = "Report Spam";
|
"lng_report_spam" = "Report Spam";
|
||||||
"lng_report_spam_hide" = "Hide";
|
"lng_report_spam_hide" = "Hide";
|
||||||
"lng_report_spam_thanks" = "Thank you for your report!";
|
"lng_report_spam_thanks" = "Thank you for your report!";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Forward Message";
|
"lng_context_forward_msg" = "Forward Message";
|
||||||
"lng_context_delete_msg" = "Delete Message";
|
"lng_context_delete_msg" = "Delete Message";
|
||||||
"lng_context_select_msg" = "Select Message";
|
"lng_context_select_msg" = "Select Message";
|
||||||
|
"lng_context_pin_msg" = "Pin Message";
|
||||||
|
"lng_context_unpin_msg" = "Unpin Message";
|
||||||
"lng_context_cancel_upload" = "Cancel Upload";
|
"lng_context_cancel_upload" = "Cancel Upload";
|
||||||
"lng_context_copy_selected" = "Copy Selected Text";
|
"lng_context_copy_selected" = "Copy Selected Text";
|
||||||
"lng_context_forward_selected" = "Forward Selected";
|
"lng_context_forward_selected" = "Forward Selected";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 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" = "— Edit your messages in channels and supergroups.\n— Share links to specific posts in channels via the post context menu.\n— Add admin signatures to messages in channels.\n— Send silent messages in channels that will not notify members. Useful for non-urgent or late night posting.";
|
"lng_new_version_text" = "PUBLIC GROUPS, PINNED POSTS, 5,000 MEMBERS\n\n— Groups can now have 5,000 members (up from 1,000)\n— Groups of any size may be converted to supergroups\n\nNew tools for supergroup admins:\n\n— Make your group public by setting up a public link – anyone will be able to view the chat and join it\n— Pin messages to keep important updates visible and notify all members\n— Select messages to delete, report as spam, block users, or remove all messages from a user\n\nMore about this update:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,13 @@ layerBg: black;
|
||||||
|
|
||||||
overBg: #edf2f5;
|
overBg: #edf2f5;
|
||||||
|
|
||||||
|
labelDefFlat: flatLabel {
|
||||||
|
font: font(fsize);
|
||||||
|
minWidth: 100px;
|
||||||
|
width: 0px;
|
||||||
|
align: align(left);
|
||||||
|
}
|
||||||
|
|
||||||
boxBg: white;
|
boxBg: white;
|
||||||
boxVerticalMargin: 10px;
|
boxVerticalMargin: 10px;
|
||||||
boxWidth: 320px;
|
boxWidth: 320px;
|
||||||
|
@ -75,6 +82,8 @@ boxPadding: margins(26px, 30px, 34px, 8px);
|
||||||
boxMaxListHeight: 600px;
|
boxMaxListHeight: 600px;
|
||||||
boxFontSize: 14px;
|
boxFontSize: 14px;
|
||||||
boxTextFont: font(boxFontSize);
|
boxTextFont: font(boxFontSize);
|
||||||
|
boxLittleSkip: 10px;
|
||||||
|
boxMediumSkip: 20px;
|
||||||
|
|
||||||
boxTitleFg: #444444;
|
boxTitleFg: #444444;
|
||||||
boxTitleFont: font(boxFontSize bold);
|
boxTitleFont: font(boxFontSize bold);
|
||||||
|
@ -126,6 +135,10 @@ redBoxLinkButton: linkButton(defaultBoxLinkButton) {
|
||||||
overColor: #d15948;
|
overColor: #d15948;
|
||||||
downColor: #db6352;
|
downColor: #db6352;
|
||||||
}
|
}
|
||||||
|
boxLabel: flatLabel(labelDefFlat) {
|
||||||
|
font: font(boxFontSize);
|
||||||
|
align: align(topleft);
|
||||||
|
}
|
||||||
|
|
||||||
defaultInputArea: InputArea {
|
defaultInputArea: InputArea {
|
||||||
textFg: black;
|
textFg: black;
|
||||||
|
@ -611,13 +624,6 @@ scrollCountries: flatScroll(scrollDef) {
|
||||||
|
|
||||||
lnkText: #0f7dc7;
|
lnkText: #0f7dc7;
|
||||||
|
|
||||||
labelDefFlat: flatLabel {
|
|
||||||
font: font(fsize);
|
|
||||||
minWidth: 100px;
|
|
||||||
width: 0px;
|
|
||||||
align: align(left);
|
|
||||||
}
|
|
||||||
|
|
||||||
introBtnTop: 288px;
|
introBtnTop: 288px;
|
||||||
introSkip: 45px;
|
introSkip: 45px;
|
||||||
introFinishSkip: 15px;
|
introFinishSkip: 15px;
|
||||||
|
|
|
@ -29,89 +29,65 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
ApiWrap::ApiWrap(QObject *parent) : QObject(parent) {
|
ApiWrap::ApiWrap(QObject *parent) : QObject(parent)
|
||||||
|
, _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) {
|
||||||
App::initBackground();
|
App::initBackground();
|
||||||
|
|
||||||
connect(&_replyToTimer, SIGNAL(timeout()), this, SLOT(resolveReplyTo()));
|
|
||||||
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
|
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::init() {
|
void ApiWrap::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::itemRemoved(HistoryItem *item) {
|
void ApiWrap::requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback) {
|
||||||
if (HistoryReply *reply = item->toHistoryReply()) {
|
MessageDataRequest::CallbackPtr pcallback(callback);
|
||||||
ChannelData *channel = reply->history()->peer->asChannel();
|
MessageDataRequest &req(channel ? _channelMessageDataRequests[channel][msgId] : _messageDataRequests[msgId]);
|
||||||
ReplyToRequests *requests(replyToRequests(channel, true));
|
req.callbacks.append(pcallback);
|
||||||
if (requests) {
|
if (!req.req) _messageDataResolveDelayed->call();
|
||||||
ReplyToRequests::iterator i = requests->find(reply->replyToId());
|
|
||||||
if (i != requests->cend()) {
|
|
||||||
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
|
|
||||||
if ((*j) == reply) {
|
|
||||||
j = i->replies.erase(j);
|
|
||||||
} else {
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i->replies.isEmpty()) {
|
|
||||||
requests->erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (channel && requests->isEmpty()) {
|
|
||||||
_channelReplyToRequests.remove(channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestReplyTo(HistoryReply *reply, ChannelData *channel, MsgId id) {
|
ApiWrap::MessageIds ApiWrap::collectMessageIds(const MessageDataRequests &requests) {
|
||||||
ReplyToRequest &req(channel ? _channelReplyToRequests[channel][id] : _replyToRequests[id]);
|
|
||||||
req.replies.append(reply);
|
|
||||||
if (!req.req) _replyToTimer.start(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiWrap::MessageIds ApiWrap::collectMessageIds(const ReplyToRequests &requests) {
|
|
||||||
MessageIds result;
|
MessageIds result;
|
||||||
result.reserve(requests.size());
|
result.reserve(requests.size());
|
||||||
for (ReplyToRequests::const_iterator i = requests.cbegin(), e = requests.cend(); i != e; ++i) {
|
for (MessageDataRequests::const_iterator i = requests.cbegin(), e = requests.cend(); i != e; ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
result.push_back(MTP_int(i.key()));
|
result.push_back(MTP_int(i.key()));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiWrap::ReplyToRequests *ApiWrap::replyToRequests(ChannelData *channel, bool onlyExisting) {
|
ApiWrap::MessageDataRequests *ApiWrap::messageDataRequests(ChannelData *channel, bool onlyExisting) {
|
||||||
if (channel) {
|
if (channel) {
|
||||||
ChannelReplyToRequests::iterator i = _channelReplyToRequests.find(channel);
|
ChannelMessageDataRequests::iterator i = _channelMessageDataRequests.find(channel);
|
||||||
if (i == _channelReplyToRequests.cend()) {
|
if (i == _channelMessageDataRequests.cend()) {
|
||||||
if (onlyExisting) return 0;
|
if (onlyExisting) return 0;
|
||||||
i = _channelReplyToRequests.insert(channel, ReplyToRequests());
|
i = _channelMessageDataRequests.insert(channel, MessageDataRequests());
|
||||||
}
|
}
|
||||||
return &i.value();
|
return &i.value();
|
||||||
}
|
}
|
||||||
return &_replyToRequests;
|
return &_messageDataRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::resolveReplyTo() {
|
void ApiWrap::resolveMessageDatas() {
|
||||||
if (_replyToRequests.isEmpty() && _channelReplyToRequests.isEmpty()) return;
|
if (_messageDataRequests.isEmpty() && _channelMessageDataRequests.isEmpty()) return;
|
||||||
|
|
||||||
MessageIds ids = collectMessageIds(_replyToRequests);
|
MessageIds ids = collectMessageIds(_messageDataRequests);
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo, (ChannelData*)0), RPCFailHandlerPtr(), 0, 5);
|
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotMessageDatas, (ChannelData*)nullptr), RPCFailHandlerPtr(), 0, 5);
|
||||||
for (ReplyToRequests::iterator i = _replyToRequests.begin(); i != _replyToRequests.cend(); ++i) {
|
for (MessageDataRequests::iterator i = _messageDataRequests.begin(); i != _messageDataRequests.cend(); ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
i.value().req = req;
|
i.value().req = req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ChannelReplyToRequests::iterator j = _channelReplyToRequests.begin(); j != _channelReplyToRequests.cend();) {
|
for (ChannelMessageDataRequests::iterator j = _channelMessageDataRequests.begin(); j != _channelMessageDataRequests.cend();) {
|
||||||
if (j->isEmpty()) {
|
if (j->isEmpty()) {
|
||||||
j = _channelReplyToRequests.erase(j);
|
j = _channelMessageDataRequests.erase(j);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MessageIds ids = collectMessageIds(j.value());
|
MessageIds ids = collectMessageIds(j.value());
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
mtpRequestId req = MTP::send(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo, j.key()), RPCFailHandlerPtr(), 0, 5);
|
mtpRequestId req = MTP::send(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotMessageDatas, j.key()), RPCFailHandlerPtr(), 0, 5);
|
||||||
for (ReplyToRequests::iterator i = j->begin(); i != j->cend(); ++i) {
|
for (MessageDataRequests::iterator i = j->begin(); i != j->cend(); ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
i.value().req = req;
|
i.value().req = req;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +96,7 @@ void ApiWrap::resolveReplyTo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) {
|
void ApiWrap::gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||||
switch (msgs.type()) {
|
switch (msgs.type()) {
|
||||||
case mtpc_messages_messages: {
|
case mtpc_messages_messages: {
|
||||||
const MTPDmessages_messages &d(msgs.c_messages_messages());
|
const MTPDmessages_messages &d(msgs.c_messages_messages());
|
||||||
|
@ -141,10 +117,10 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
if (channel) {
|
if (channel) {
|
||||||
channel->ptsReceived(d.vpts.v);
|
channel->ptsReceived(d.vpts.v);
|
||||||
} else {
|
} else {
|
||||||
LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotReplyTo)"));
|
LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotDependencyItem)"));
|
||||||
}
|
}
|
||||||
if (d.has_collapsed()) { // should not be returned
|
if (d.has_collapsed()) { // should not be returned
|
||||||
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotReplyTo)"));
|
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotDependencyItem)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
|
@ -152,16 +128,12 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
App::feedMsgs(d.vmessages, NewMessageExisting);
|
App::feedMsgs(d.vmessages, NewMessageExisting);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
ReplyToRequests *requests(replyToRequests(channel, true));
|
MessageDataRequests *requests(messageDataRequests(channel, true));
|
||||||
if (requests) {
|
if (requests) {
|
||||||
for (ReplyToRequests::iterator i = requests->begin(); i != requests->cend();) {
|
for (MessageDataRequests::iterator i = requests->begin(); i != requests->cend();) {
|
||||||
if (i.value().req == req) {
|
if (i.value().req == req) {
|
||||||
for (QList<HistoryReply*>::const_iterator j = i.value().replies.cbegin(), e = i.value().replies.cend(); j != e; ++j) {
|
for (MessageDataRequest::Callbacks::const_iterator j = i.value().callbacks.cbegin(), e = i.value().callbacks.cend(); j != e; ++j) {
|
||||||
if (*j) {
|
(*j)->call(channel, i.key());
|
||||||
(*j)->updateReplyTo(true);
|
|
||||||
} else {
|
|
||||||
App::main()->updateReplyTo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
i = requests->erase(i);
|
i = requests->erase(i);
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +141,7 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channel && requests->isEmpty()) {
|
if (channel && requests->isEmpty()) {
|
||||||
_channelReplyToRequests.remove(channel);
|
_channelMessageDataRequests.remove(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,6 +289,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (channel->isMegagroup()) {
|
||||||
|
if (f.has_pinned_msg_id()) {
|
||||||
|
channel->mgInfo->pinnedMsgId = f.vpinned_msg_id.v;
|
||||||
|
} else {
|
||||||
|
channel->mgInfo->pinnedMsgId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
channel->fullUpdated();
|
channel->fullUpdated();
|
||||||
|
|
||||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
||||||
|
@ -344,14 +323,21 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) {
|
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) {
|
||||||
const MTPDuserFull &d(result.c_userFull());
|
const MTPDuserFull &d(result.c_userFull());
|
||||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||||
App::feedPhoto(d.vprofile_photo);
|
if (d.has_profile_photo()) {
|
||||||
|
App::feedPhoto(d.vprofile_photo);
|
||||||
|
}
|
||||||
App::feedUserLink(MTP_int(peerToUser(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
|
App::feedUserLink(MTP_int(peerToUser(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
peer->asUser()->setBotInfo(d.vbot_info);
|
if (d.has_bot_info()) {
|
||||||
peer->asUser()->blocked = mtpIsTrue(d.vblocked) ? UserIsBlocked : UserIsNotBlocked;
|
peer->asUser()->setBotInfo(d.vbot_info);
|
||||||
|
} else {
|
||||||
|
peer->asUser()->setBotInfoVersion(-1);
|
||||||
|
}
|
||||||
|
peer->asUser()->blocked = d.is_blocked() ? UserIsBlocked : UserIsNotBlocked;
|
||||||
|
peer->asUser()->about = d.has_about() ? qs(d.vabout) : QString();
|
||||||
|
|
||||||
if (req) {
|
if (req) {
|
||||||
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
||||||
|
@ -526,7 +512,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
|
||||||
UserData *u = App::user(userId);
|
UserData *u = App::user(userId);
|
||||||
if (bots) {
|
if (bots) {
|
||||||
if (u->botInfo) {
|
if (u->botInfo) {
|
||||||
peer->mgInfo->bots.insert(u, true);
|
peer->mgInfo->bots.insert(u);
|
||||||
botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
|
botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
|
||||||
if (!u->botInfo->inited) {
|
if (!u->botInfo->inited) {
|
||||||
needBotsInfos = true;
|
needBotsInfos = true;
|
||||||
|
@ -538,9 +524,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
|
||||||
} else {
|
} else {
|
||||||
if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
|
if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
|
||||||
peer->mgInfo->lastParticipants.push_back(u);
|
peer->mgInfo->lastParticipants.push_back(u);
|
||||||
if (admin) peer->mgInfo->lastAdmins.insert(u, true);
|
if (admin) peer->mgInfo->lastAdmins.insert(u);
|
||||||
if (u->botInfo) {
|
if (u->botInfo) {
|
||||||
peer->mgInfo->bots.insert(u, true);
|
peer->mgInfo->bots.insert(u);
|
||||||
if (peer->mgInfo->botStatus != 0 && peer->mgInfo->botStatus < 2) {
|
if (peer->mgInfo->botStatus != 0 && peer->mgInfo->botStatus < 2) {
|
||||||
peer->mgInfo->botStatus = 2;
|
peer->mgInfo->botStatus = 2;
|
||||||
}
|
}
|
||||||
|
@ -647,15 +633,23 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt
|
||||||
int32 i = kick.first->asChannel()->mgInfo->lastParticipants.indexOf(kick.second);
|
int32 i = kick.first->asChannel()->mgInfo->lastParticipants.indexOf(kick.second);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
|
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
|
||||||
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
|
|
||||||
}
|
}
|
||||||
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
|
|
||||||
if (kick.first->asChannel()->count > 1) {
|
if (kick.first->asChannel()->count > 1) {
|
||||||
kick.first->asChannel()->count--;
|
--kick.first->asChannel()->count;
|
||||||
} else {
|
} else {
|
||||||
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
|
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
|
||||||
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
|
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
|
||||||
}
|
}
|
||||||
|
if (kick.first->asChannel()->mgInfo->lastAdmins.contains(kick.second)) {
|
||||||
|
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
|
||||||
|
if (kick.first->asChannel()->adminsCount > 1) {
|
||||||
|
--kick.first->asChannel()->adminsCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
|
||||||
|
if (kick.first->asChannel()->mgInfo->bots.isEmpty() && kick.first->asChannel()->mgInfo->botStatus > 0) {
|
||||||
|
kick.first->asChannel()->mgInfo->botStatus = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit fullPeerUpdated(kick.first);
|
emit fullPeerUpdated(kick.first);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,8 @@ public:
|
||||||
ApiWrap(QObject *parent);
|
ApiWrap(QObject *parent);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *item);
|
typedef SharedCallback2<void, ChannelData*, MsgId> RequestMessageDataCallback;
|
||||||
|
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback);
|
||||||
void requestReplyTo(HistoryReply *reply, ChannelData *channel, MsgId id);
|
|
||||||
|
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(PeerData *peer);
|
||||||
void requestPeer(PeerData *peer);
|
void requestPeer(PeerData *peer);
|
||||||
|
@ -59,35 +58,37 @@ signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void resolveReplyTo();
|
void resolveMessageDatas();
|
||||||
void resolveWebPages();
|
void resolveWebPages();
|
||||||
|
|
||||||
void delayedRequestParticipantsCount();
|
void delayedRequestParticipantsCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void gotReplyTo(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
struct ReplyToRequest {
|
struct MessageDataRequest {
|
||||||
ReplyToRequest() : req(0) {
|
MessageDataRequest() : req(0) {
|
||||||
}
|
}
|
||||||
|
typedef SharedCallback2<void, ChannelData*, MsgId>::Ptr CallbackPtr;
|
||||||
|
typedef QList<CallbackPtr> Callbacks;
|
||||||
mtpRequestId req;
|
mtpRequestId req;
|
||||||
QList<HistoryReply*> replies;
|
Callbacks callbacks;
|
||||||
};
|
};
|
||||||
typedef QMap<MsgId, ReplyToRequest> ReplyToRequests;
|
typedef QMap<MsgId, MessageDataRequest> MessageDataRequests;
|
||||||
ReplyToRequests _replyToRequests;
|
MessageDataRequests _messageDataRequests;
|
||||||
typedef QMap<ChannelData*, ReplyToRequests> ChannelReplyToRequests;
|
typedef QMap<ChannelData*, MessageDataRequests> ChannelMessageDataRequests;
|
||||||
ChannelReplyToRequests _channelReplyToRequests;
|
ChannelMessageDataRequests _channelMessageDataRequests;
|
||||||
SingleTimer _replyToTimer;
|
SingleDelayedCall *_messageDataResolveDelayed;
|
||||||
typedef QVector<MTPint> MessageIds;
|
typedef QVector<MTPint> MessageIds;
|
||||||
MessageIds collectMessageIds(const ReplyToRequests &requests);
|
MessageIds collectMessageIds(const MessageDataRequests &requests);
|
||||||
ReplyToRequests *replyToRequests(ChannelData *channel, bool onlyExisting = false);
|
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||||
|
|
||||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||||
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
|
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
|
||||||
bool gotPeerFullFailed(PeerData *peer, const RPCError &err);
|
bool gotPeerFullFailed(PeerData *peer, const RPCError &err);
|
||||||
typedef QMap<PeerData*, mtpRequestId> PeerRequests;
|
typedef QMap<PeerData*, mtpRequestId> PeerRequests;
|
||||||
PeerRequests _fullPeerRequests;
|
PeerRequests _fullPeerRequests;
|
||||||
|
|
||||||
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 gotChats(const MTPmessages_Chats &result);
|
||||||
|
|
|
@ -67,8 +67,8 @@ namespace {
|
||||||
SharedContactItems sharedContactItems;
|
SharedContactItems sharedContactItems;
|
||||||
GifItems gifItems;
|
GifItems gifItems;
|
||||||
|
|
||||||
typedef QMap<HistoryItem*, QMap<HistoryReply*, bool> > RepliesTo;
|
typedef QMap<HistoryItem*, OrderedSet<HistoryItem*> > DependentItems;
|
||||||
RepliesTo repliesTo;
|
DependentItems dependentItems;
|
||||||
|
|
||||||
Histories histories;
|
Histories histories;
|
||||||
|
|
||||||
|
@ -413,6 +413,9 @@ namespace App {
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
if (!minimal && d.is_self() && uname != data->username) {
|
||||||
|
SignalHandlers::setSelfUsername(uname);
|
||||||
|
}
|
||||||
data->setName(fname, lname, pname, uname);
|
data->setName(fname, lname, pname, uname);
|
||||||
if (d.has_photo()) {
|
if (d.has_photo()) {
|
||||||
data->setPhoto(d.vphoto);
|
data->setPhoto(d.vphoto);
|
||||||
|
@ -433,8 +436,8 @@ namespace App {
|
||||||
data->setBotInfoVersion(-1);
|
data->setBotInfoVersion(-1);
|
||||||
}
|
}
|
||||||
data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone.isEmpty() ? -1 : 0);
|
data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone.isEmpty() ? -1 : 0);
|
||||||
if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsNoButton) != dbiprsNoButton) {
|
if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsHidden) != dbiprsHidden) {
|
||||||
cRefReportSpamStatuses().insert(data->id, dbiprsNoButton);
|
cRefReportSpamStatuses().insert(data->id, dbiprsHidden);
|
||||||
Local::writeReportSpamStatuses();
|
Local::writeReportSpamStatuses();
|
||||||
}
|
}
|
||||||
if (d.is_self() && ::self != data) {
|
if (d.is_self() && ::self != data) {
|
||||||
|
@ -486,6 +489,7 @@ namespace App {
|
||||||
for (QVector<MTPChat>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
for (QVector<MTPChat>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||||
const MTPchat &chat(*i);
|
const MTPchat &chat(*i);
|
||||||
data = 0;
|
data = 0;
|
||||||
|
bool minimal = false;
|
||||||
switch (chat.type()) {
|
switch (chat.type()) {
|
||||||
case mtpc_chat: {
|
case mtpc_chat: {
|
||||||
const MTPDchat &d(chat.c_chat());
|
const MTPDchat &d(chat.c_chat());
|
||||||
|
@ -566,24 +570,36 @@ namespace App {
|
||||||
const MTPDchannel &d(chat.c_channel());
|
const MTPDchannel &d(chat.c_channel());
|
||||||
|
|
||||||
PeerId peer(peerFromChannel(d.vid.v));
|
PeerId peer(peerFromChannel(d.vid.v));
|
||||||
data = App::channel(peer);
|
minimal = d.is_min();
|
||||||
data->input = MTP_inputPeerChannel(d.vid, d.vaccess_hash);
|
if (minimal) {
|
||||||
|
data = App::channelLoaded(peer);
|
||||||
|
if (!data) {
|
||||||
|
continue; // minimal is not loaded, need to make getDifference
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data = App::channel(peer);
|
||||||
|
data->input = MTP_inputPeerChannel(d.vid, d.has_access_hash() ? d.vaccess_hash : MTP_long(0));
|
||||||
|
}
|
||||||
|
|
||||||
ChannelData *cdata = data->asChannel();
|
ChannelData *cdata = data->asChannel();
|
||||||
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
|
if (minimal) {
|
||||||
|
int32 mask = MTPDchannel::flag_broadcast | MTPDchannel::flag_verified | MTPDchannel::flag_megagroup | MTPDchannel::flag_democracy;
|
||||||
|
cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask);
|
||||||
|
} else {
|
||||||
|
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
|
||||||
|
cdata->access = d.vaccess_hash.v;
|
||||||
|
cdata->date = d.vdate.v;
|
||||||
|
cdata->flags = d.vflags.v;
|
||||||
|
if (cdata->version < d.vversion.v) {
|
||||||
|
cdata->version = d.vversion.v;
|
||||||
|
}
|
||||||
|
}
|
||||||
QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString();
|
QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString();
|
||||||
cdata->setName(qs(d.vtitle), uname);
|
cdata->setName(qs(d.vtitle), uname);
|
||||||
|
|
||||||
cdata->access = d.vaccess_hash.v;
|
|
||||||
cdata->date = d.vdate.v;
|
|
||||||
cdata->flags = d.vflags.v;
|
|
||||||
cdata->isForbidden = false;
|
cdata->isForbidden = false;
|
||||||
cdata->flagsUpdated();
|
cdata->flagsUpdated();
|
||||||
cdata->setPhoto(d.vphoto);
|
cdata->setPhoto(d.vphoto);
|
||||||
if (cdata->version < d.vversion.v) {
|
|
||||||
cdata->version = d.vversion.v;
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case mtpc_channelForbidden: {
|
case mtpc_channelForbidden: {
|
||||||
const MTPDchannelForbidden &d(chat.c_channelForbidden());
|
const MTPDchannelForbidden &d(chat.c_channelForbidden());
|
||||||
|
@ -664,10 +680,10 @@ namespace App {
|
||||||
if (user) {
|
if (user) {
|
||||||
chat->participants[user] = pversion;
|
chat->participants[user] = pversion;
|
||||||
if (inviter == MTP::authedId()) {
|
if (inviter == MTP::authedId()) {
|
||||||
chat->invitedByMe[user] = true;
|
chat->invitedByMe.insert(user);
|
||||||
}
|
}
|
||||||
if (i->type() == mtpc_chatParticipantAdmin) {
|
if (i->type() == mtpc_chatParticipantAdmin) {
|
||||||
chat->admins[user] = true;
|
chat->admins.insert(user);
|
||||||
if (user->isSelf()) {
|
if (user->isSelf()) {
|
||||||
chat->flags |= MTPDchat::flag_admin;
|
chat->flags |= MTPDchat::flag_admin;
|
||||||
}
|
}
|
||||||
|
@ -736,7 +752,7 @@ namespace App {
|
||||||
} else if (chat->participants.find(user) == chat->participants.end()) {
|
} else if (chat->participants.find(user) == chat->participants.end()) {
|
||||||
chat->participants[user] = (chat->participants.isEmpty() ? 1 : chat->participants.begin().value());
|
chat->participants[user] = (chat->participants.isEmpty() ? 1 : chat->participants.begin().value());
|
||||||
if (d.vinviter_id.v == MTP::authedId()) {
|
if (d.vinviter_id.v == MTP::authedId()) {
|
||||||
chat->invitedByMe[user] = true;
|
chat->invitedByMe.insert(user);
|
||||||
} else {
|
} else {
|
||||||
chat->invitedByMe.remove(user);
|
chat->invitedByMe.remove(user);
|
||||||
}
|
}
|
||||||
|
@ -876,7 +892,7 @@ namespace App {
|
||||||
if (chat->noParticipantInfo()) {
|
if (chat->noParticipantInfo()) {
|
||||||
App::api()->requestFullPeer(chat);
|
App::api()->requestFullPeer(chat);
|
||||||
} else {
|
} else {
|
||||||
chat->admins.insert(user, true);
|
chat->admins.insert(user);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (user->isSelf()) {
|
if (user->isSelf()) {
|
||||||
|
@ -937,6 +953,7 @@ namespace App {
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->dlgUpdated(existing->history(), existing->id);
|
App::main()->dlgUpdated(existing->history(), existing->id);
|
||||||
}
|
}
|
||||||
|
App::historyUpdateDependent(existing);
|
||||||
Notify::historyItemResized(existing);
|
Notify::historyItemResized(existing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,8 +1161,8 @@ namespace App {
|
||||||
switch (myLink.type()) {
|
switch (myLink.type()) {
|
||||||
case mtpc_contactLinkContact:
|
case mtpc_contactLinkContact:
|
||||||
user->contact = 1;
|
user->contact = 1;
|
||||||
if (user->contact == 1 && cReportSpamStatuses().value(user->id, dbiprsNoButton) != dbiprsNoButton) {
|
if (user->contact == 1 && cReportSpamStatuses().value(user->id, dbiprsHidden) != dbiprsHidden) {
|
||||||
cRefReportSpamStatuses().insert(user->id, dbiprsNoButton);
|
cRefReportSpamStatuses().insert(user->id, dbiprsHidden);
|
||||||
Local::writeReportSpamStatuses();
|
Local::writeReportSpamStatuses();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1784,20 +1801,32 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
historyItemDetached(item);
|
historyItemDetached(item);
|
||||||
RepliesTo::iterator j = ::repliesTo.find(item);
|
DependentItems::iterator j = ::dependentItems.find(item);
|
||||||
if (j != ::repliesTo.cend()) {
|
if (j != ::dependentItems.cend()) {
|
||||||
for (QMap<HistoryReply*, bool>::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
for (OrderedSet<HistoryItem*>::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
||||||
k.key()->replyToReplaced(item, 0);
|
k.key()->dependencyItemRemoved(item);
|
||||||
}
|
}
|
||||||
::repliesTo.erase(j);
|
::dependentItems.erase(j);
|
||||||
}
|
}
|
||||||
if (App::main() && !App::quitting()) {
|
if (App::main() && !App::quitting()) {
|
||||||
App::main()->itemRemoved(item);
|
App::main()->itemRemoved(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void historyUpdateDependent(HistoryItem *item) {
|
||||||
|
DependentItems::iterator j = ::dependentItems.find(item);
|
||||||
|
if (j != ::dependentItems.cend()) {
|
||||||
|
for (OrderedSet<HistoryItem*>::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
||||||
|
k.key()->updateDependencyItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->itemEdited(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void historyClearMsgs() {
|
void historyClearMsgs() {
|
||||||
::repliesTo.clear();
|
::dependentItems.clear();
|
||||||
|
|
||||||
QVector<HistoryItem*> toDelete;
|
QVector<HistoryItem*> toDelete;
|
||||||
for (MsgsData::const_iterator i = msgsData.cbegin(), e = msgsData.cend(); i != e; ++i) {
|
for (MsgsData::const_iterator i = msgsData.cbegin(), e = msgsData.cend(); i != e; ++i) {
|
||||||
|
@ -1869,16 +1898,16 @@ namespace App {
|
||||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void historyRegReply(HistoryReply *reply, HistoryItem *to) {
|
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency) {
|
||||||
::repliesTo[to].insert(reply, true);
|
::dependentItems[dependency].insert(dependent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void historyUnregReply(HistoryReply *reply, HistoryItem *to) {
|
void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency) {
|
||||||
RepliesTo::iterator i = ::repliesTo.find(to);
|
DependentItems::iterator i = ::dependentItems.find(dependency);
|
||||||
if (i != ::repliesTo.cend()) {
|
if (i != ::dependentItems.cend()) {
|
||||||
i.value().remove(reply);
|
i.value().remove(dependent);
|
||||||
if (i.value().isEmpty()) {
|
if (i.value().isEmpty()) {
|
||||||
::repliesTo.erase(i);
|
::dependentItems.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,16 +144,26 @@ namespace App {
|
||||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead);
|
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead);
|
||||||
History *historyLoaded(const PeerId &peer);
|
History *historyLoaded(const PeerId &peer);
|
||||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||||
|
inline History *history(const PeerData *peer) {
|
||||||
|
return history(peer->id);
|
||||||
|
}
|
||||||
|
inline History *historyLoaded(const PeerData *peer) {
|
||||||
|
return historyLoaded(peer->id);
|
||||||
|
}
|
||||||
|
inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) {
|
||||||
|
return histItemById(channel ? peerToChannel(channel->id) : 0, itemId);
|
||||||
|
}
|
||||||
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||||
return histItemById(msgId.channel, msgId.msg);
|
return histItemById(msgId.channel, msgId.msg);
|
||||||
}
|
}
|
||||||
void historyRegItem(HistoryItem *item);
|
void historyRegItem(HistoryItem *item);
|
||||||
void historyItemDetached(HistoryItem *item);
|
void historyItemDetached(HistoryItem *item);
|
||||||
void historyUnregItem(HistoryItem *item);
|
void historyUnregItem(HistoryItem *item);
|
||||||
|
void historyUpdateDependent(HistoryItem *item);
|
||||||
void historyClearMsgs();
|
void historyClearMsgs();
|
||||||
void historyClearItems();
|
void historyClearItems();
|
||||||
void historyRegReply(HistoryReply *reply, HistoryItem *to);
|
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||||
void historyUnregReply(HistoryReply *reply, HistoryItem *to);
|
void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||||
|
|
||||||
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
|
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
|
||||||
void historyUnregRandom(uint64 randomId);
|
void historyUnregRandom(uint64 randomId);
|
||||||
|
|
|
@ -1019,11 +1019,12 @@ void AppClass::checkMapVersion() {
|
||||||
if (Local::oldMapVersion() < AppVersion) {
|
if (Local::oldMapVersion() < AppVersion) {
|
||||||
if (Local::oldMapVersion()) {
|
if (Local::oldMapVersion()) {
|
||||||
QString versionFeatures;
|
QString versionFeatures;
|
||||||
if ((cDevVersion() || cBetaVersion()) && Local::oldMapVersion() < 9029) {
|
if ((cDevVersion() || cBetaVersion()) && Local::oldMapVersion() < 9031) {
|
||||||
QString ctrl = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? qsl("Cmd") : qsl("Ctrl");
|
// QString ctrl = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? qsl("Cmd") : qsl("Ctrl");
|
||||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 %1+W or %2+F4 for close window\n\xe2\x80\x94 %3+L to lock Telegram if you use a local passcode\n\xe2\x80\x94 Bug fixes and other minor improvements").arg(ctrl).arg(ctrl).arg(ctrl);// .replace('@', qsl("@") + QChar(0x200D));
|
// versionFeatures = QString::fromUtf8("\xe2\x80\x94 %1+W or %2+F4 for close window\n\xe2\x80\x94 %3+L to lock Telegram if you use a local passcode\n\xe2\x80\x94 Bug fixes and other minor improvements").arg(ctrl).arg(ctrl).arg(ctrl);// .replace('@', qsl("@") + QChar(0x200D));
|
||||||
} else if (Local::oldMapVersion() < 9027) {
|
versionFeatures = lng_new_version_text(lt_link, qsl("https://telegram.org/blog/supergroups5k")).trimmed();
|
||||||
versionFeatures = lang(lng_new_version_text).trimmed();
|
} else if (Local::oldMapVersion() < 9031) {
|
||||||
|
versionFeatures = lng_new_version_text(lt_link, qsl("https://telegram.org/blog/supergroups5k")).trimmed();
|
||||||
} else {
|
} else {
|
||||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ NewGroupBox::NewGroupBox() : AbstractBox(),
|
||||||
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
||||||
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
||||||
_aboutGroupWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x()),
|
_aboutGroupWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x()),
|
||||||
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, Global::ChatSizeMax()), _defaultOptions, _aboutGroupWidth),
|
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, Global::MegagroupSizeMax()), _defaultOptions, _aboutGroupWidth),
|
||||||
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
||||||
_next(this, lang(lng_create_group_next), st::defaultBoxButton),
|
_next(this, lang(lng_create_group_next), st::defaultBoxButton),
|
||||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
@ -605,12 +605,12 @@ void GroupInfoBox::onPhotoReady(const QImage &img) {
|
||||||
SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : AbstractBox()
|
SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : AbstractBox()
|
||||||
, _channel(channel)
|
, _channel(channel)
|
||||||
, _existing(existing)
|
, _existing(existing)
|
||||||
, _public(this, qsl("channel_privacy"), 0, lang(lng_create_public_channel_title), true)
|
, _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true)
|
||||||
, _private(this, qsl("channel_privacy"), 1, lang(lng_create_private_channel_title))
|
, _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title))
|
||||||
, _comments(this, lang(lng_create_channel_comments), false)
|
, _comments(this, lang(lng_create_channel_comments), false)
|
||||||
, _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x())
|
, _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x())
|
||||||
, _aboutPublic(st::normalFont, lang(lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutPublic(st::normalFont, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _aboutPrivate(st::normalFont, lang(lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutPrivate(st::normalFont, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _aboutComments(st::normalFont, lang(lng_create_channel_comments_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutComments(st::normalFont, lang(lng_create_channel_comments_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _link(this, st::defaultInputField, QString(), channel->username, true)
|
, _link(this, st::defaultInputField, QString(), channel->username, true)
|
||||||
, _linkOver(false)
|
, _linkOver(false)
|
||||||
|
@ -626,7 +626,7 @@ SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : Abstract
|
||||||
_checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail));
|
_checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail));
|
||||||
|
|
||||||
_aboutPublicHeight = _aboutPublic.countHeight(_aboutPublicWidth);
|
_aboutPublicHeight = _aboutPublic.countHeight(_aboutPublicWidth);
|
||||||
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
updateMaxHeight();
|
||||||
|
|
||||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
connect(&_skip, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_skip, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
@ -669,6 +669,14 @@ void SetupChannelBox::showDone() {
|
||||||
_link.setFocus();
|
_link.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupChannelBox::updateMaxHeight() {
|
||||||
|
if (!_channel->isMegagroup() || _public.checked()) {
|
||||||
|
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
||||||
|
} else {
|
||||||
|
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetupChannelBox::keyPressEvent(QKeyEvent *e) {
|
void SetupChannelBox::keyPressEvent(QKeyEvent *e) {
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||||
if (_link.hasFocus()) {
|
if (_link.hasFocus()) {
|
||||||
|
@ -699,22 +707,26 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) {
|
||||||
//QRect aboutComments(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _comments.y() + _comments.height(), _aboutPublicWidth, _aboutPublicHeight);
|
//QRect aboutComments(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _comments.y() + _comments.height(), _aboutPublicWidth, _aboutPublicHeight);
|
||||||
//_aboutComments.drawLeft(p, aboutComments.x(), aboutComments.y(), aboutComments.width(), width());
|
//_aboutComments.drawLeft(p, aboutComments.x(), aboutComments.y(), aboutComments.width(), width());
|
||||||
|
|
||||||
p.setPen(st::black);
|
if (!_channel->isMegagroup() || !_link.isHidden()) {
|
||||||
p.setFont(st::newGroupLinkFont);
|
p.setPen(st::black);
|
||||||
p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), lang(_link.isHidden() ? lng_create_group_invite_link : lng_create_group_link));
|
p.setFont(st::newGroupLinkFont);
|
||||||
|
p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), lang(_link.isHidden() ? lng_create_group_invite_link : lng_create_group_link));
|
||||||
|
}
|
||||||
|
|
||||||
if (_link.isHidden()) {
|
if (_link.isHidden()) {
|
||||||
QTextOption option(style::al_left);
|
if (!_channel->isMegagroup()) {
|
||||||
option.setWrapMode(QTextOption::WrapAnywhere);
|
QTextOption option(style::al_left);
|
||||||
p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont);
|
option.setWrapMode(QTextOption::WrapAnywhere);
|
||||||
p.setPen(st::btnDefLink.color);
|
p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont);
|
||||||
p.drawText(_invitationLink, _channel->invitationUrl, option);
|
p.setPen(st::btnDefLink.color);
|
||||||
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
|
p.drawText(_invitationLink, _channel->invitationUrl, option);
|
||||||
p.setOpacity(a_goodOpacity.current());
|
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
|
||||||
p.setPen(st::setGoodColor);
|
p.setOpacity(a_goodOpacity.current());
|
||||||
p.setFont(st::boxTextFont);
|
p.setPen(st::setGoodColor);
|
||||||
p.drawTextRight(st::boxPadding.right(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
|
p.setFont(st::boxTextFont);
|
||||||
p.setOpacity(1);
|
p.drawTextRight(st::boxPadding.right(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
|
||||||
|
p.setOpacity(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_errorText.isEmpty()) {
|
if (!_errorText.isEmpty()) {
|
||||||
|
@ -879,6 +891,9 @@ void SetupChannelBox::onPrivacyChange() {
|
||||||
_link.hide();
|
_link.hide();
|
||||||
setFocus();
|
setFocus();
|
||||||
}
|
}
|
||||||
|
if (_channel->isMegagroup()) {
|
||||||
|
updateMaxHeight();
|
||||||
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,7 +944,10 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
|
||||||
|
|
||||||
_checkRequestId = 0;
|
_checkRequestId = 0;
|
||||||
QString err(error.type());
|
QString err(error.type());
|
||||||
if (err == "CHANNELS_ADMIN_PUBLIC_TOO_MUCH") {
|
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
} else if (err == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
|
||||||
if (_existing) {
|
if (_existing) {
|
||||||
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -938,11 +956,11 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
|
||||||
onPrivacyChange();
|
onPrivacyChange();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (err == "USERNAME_INVALID") {
|
} else if (err == qstr("USERNAME_INVALID")) {
|
||||||
_errorText = lang(lng_create_channel_link_invalid);
|
_errorText = lang(lng_create_channel_link_invalid);
|
||||||
update();
|
update();
|
||||||
return true;
|
return true;
|
||||||
} else if (err == "USERNAME_OCCUPIED" && _checkUsername != _channel->username) {
|
} else if (err == qstr("USERNAME_OCCUPIED") && _checkUsername != _channel->username) {
|
||||||
_errorText = lang(lng_create_channel_link_occupied);
|
_errorText = lang(lng_create_channel_link_occupied);
|
||||||
update();
|
update();
|
||||||
return true;
|
return true;
|
||||||
|
@ -957,7 +975,10 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) {
|
||||||
|
|
||||||
_checkRequestId = 0;
|
_checkRequestId = 0;
|
||||||
QString err(error.type());
|
QString err(error.type());
|
||||||
if (err == "CHANNELS_ADMIN_PUBLIC_TOO_MUCH") {
|
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
} else if (err == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
|
||||||
if (_existing) {
|
if (_existing) {
|
||||||
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1094,7 +1115,8 @@ void EditNameTitleBox::onSave() {
|
||||||
}
|
}
|
||||||
_sentName = first;
|
_sentName = first;
|
||||||
if (_peer == App::self()) {
|
if (_peer == App::self()) {
|
||||||
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_string(first), MTP_string(last)), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
|
int32 flags = MTPaccount_UpdateProfile::flag_first_name | MTPaccount_UpdateProfile::flag_last_name;
|
||||||
|
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_int(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
|
||||||
} else if (_peer->isChat()) {
|
} else if (_peer->isChat()) {
|
||||||
_requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail));
|
_requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail));
|
||||||
}
|
}
|
||||||
|
@ -1197,11 +1219,14 @@ void EditChannelBox::showAll() {
|
||||||
_description.show();
|
_description.show();
|
||||||
_save.show();
|
_save.show();
|
||||||
_cancel.show();
|
_cancel.show();
|
||||||
if (_channel->isMegagroup()) {
|
if (_channel->canEditUsername()) {
|
||||||
|
_publicLink.show();
|
||||||
|
} else {
|
||||||
_publicLink.hide();
|
_publicLink.hide();
|
||||||
|
}
|
||||||
|
if (_channel->isMegagroup()) {
|
||||||
_sign.hide();
|
_sign.hide();
|
||||||
} else {
|
} else {
|
||||||
_publicLink.show();
|
|
||||||
_sign.show();
|
_sign.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,7 +1270,9 @@ void EditChannelBox::updateMaxHeight() {
|
||||||
if (!_channel->isMegagroup()) {
|
if (!_channel->isMegagroup()) {
|
||||||
h += st::newGroupPublicLinkPadding.top() + _sign.height() + st::newGroupPublicLinkPadding.bottom();
|
h += st::newGroupPublicLinkPadding.top() + _sign.height() + st::newGroupPublicLinkPadding.bottom();
|
||||||
}
|
}
|
||||||
h += st::newGroupPublicLinkPadding.top() + _publicLink.height() + st::newGroupPublicLinkPadding.bottom();
|
if (_channel->canEditUsername()) {
|
||||||
|
h += st::newGroupPublicLinkPadding.top() + _publicLink.height() + st::newGroupPublicLinkPadding.bottom();
|
||||||
|
}
|
||||||
h += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
h += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
||||||
setMaxHeight(h);
|
setMaxHeight(h);
|
||||||
}
|
}
|
||||||
|
@ -1258,7 +1285,11 @@ void EditChannelBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
_sign.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
_sign.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
|
||||||
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign.y() + _sign.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
if (_channel->isMegagroup()) {
|
||||||
|
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
} else {
|
||||||
|
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign.y() + _sign.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
}
|
||||||
|
|
||||||
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
||||||
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
||||||
|
|
|
@ -211,6 +211,8 @@ private:
|
||||||
bool onCheckFail(const RPCError &error);
|
bool onCheckFail(const RPCError &error);
|
||||||
bool onFirstCheckFail(const RPCError &error);
|
bool onFirstCheckFail(const RPCError &error);
|
||||||
|
|
||||||
|
void updateMaxHeight();
|
||||||
|
|
||||||
ChannelData *_channel;
|
ChannelData *_channel;
|
||||||
bool _existing;
|
bool _existing;
|
||||||
|
|
||||||
|
|
|
@ -34,19 +34,19 @@ TextParseOptions _confirmBoxTextOptions = {
|
||||||
Qt::LayoutDirectionAuto, // dir
|
Qt::LayoutDirectionAuto, // dir
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, const QString &cancelText, const style::BoxButton &cancelStyle) : AbstractBox(st::boxWidth),
|
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, const QString &cancelText, const style::BoxButton &cancelStyle) : AbstractBox(st::boxWidth)
|
||||||
_informative(false),
|
, _informative(false)
|
||||||
_text(100),
|
, _text(100)
|
||||||
_confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle),
|
, _confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle)
|
||||||
_cancel(this, cancelText.isEmpty() ? lang(lng_cancel) : cancelText, cancelStyle) {
|
, _cancel(this, cancelText.isEmpty() ? lang(lng_cancel) : cancelText, cancelStyle) {
|
||||||
init(text);
|
init(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, bool informative) : AbstractBox(st::boxWidth),
|
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, bool informative) : AbstractBox(st::boxWidth)
|
||||||
_informative(true),
|
, _informative(true)
|
||||||
_text(100),
|
, _text(100)
|
||||||
_confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle),
|
, _confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle)
|
||||||
_cancel(this, QString(), st::cancelBoxButton) {
|
, _cancel(this, QString(), st::cancelBoxButton) {
|
||||||
init(text);
|
init(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,17 +174,18 @@ void ConfirmBox::resizeEvent(QResizeEvent *e) {
|
||||||
_cancel.moveToRight(st::boxButtonPadding.right() + _confirm.width() + st::boxButtonPadding.left(), _confirm.y());
|
_cancel.moveToRight(st::boxButtonPadding.right() + _confirm.width() + st::boxButtonPadding.left(), _confirm.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmLinkBox::ConfirmLinkBox(const QString &url) : ConfirmBox(lang(lng_open_this_link) + qsl("\n\n") + url, lang(lng_open_link)), _url(url) {
|
ConfirmLinkBox::ConfirmLinkBox(const QString &url) : ConfirmBox(lang(lng_open_this_link) + qsl("\n\n") + url, lang(lng_open_link))
|
||||||
|
, _url(url) {
|
||||||
connect(this, SIGNAL(confirmed()), this, SLOT(onOpenLink()));
|
connect(this, SIGNAL(confirmed()), this, SLOT(onOpenLink()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmLinkBox::onOpenLink() {
|
void ConfirmLinkBox::onOpenLink() {
|
||||||
|
Ui::hideLayer();
|
||||||
if (reMailStart().match(_url).hasMatch()) {
|
if (reMailStart().match(_url).hasMatch()) {
|
||||||
EmailLink(_url).onClick(Qt::LeftButton);
|
EmailLink(_url).onClick(Qt::LeftButton);
|
||||||
} else {
|
} else {
|
||||||
TextLink(_url).onClick(Qt::LeftButton);
|
TextLink(_url).onClick(Qt::LeftButton);
|
||||||
}
|
}
|
||||||
Ui::hideLayer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxInviteBox::MaxInviteBox(const QString &link) : AbstractBox(st::boxWidth)
|
MaxInviteBox::MaxInviteBox(const QString &link) : AbstractBox(st::boxWidth)
|
||||||
|
@ -279,3 +280,226 @@ void MaxInviteBox::resizeEvent(QResizeEvent *e) {
|
||||||
_close.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _close.height());
|
_close.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _close.height());
|
||||||
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConvertToSupergroupBox::ConvertToSupergroupBox(ChatData *chat) : AbstractBox(st::boxWideWidth)
|
||||||
|
, _chat(chat)
|
||||||
|
, _text(100)
|
||||||
|
, _note(100)
|
||||||
|
, _convert(this, lang(lng_profile_convert_confirm), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
QStringList text;
|
||||||
|
text.push_back(lang(lng_profile_convert_feature1));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature2));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature3));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature4));
|
||||||
|
|
||||||
|
textstyleSet(&st::boxTextStyle);
|
||||||
|
_text.setText(st::boxTextFont, text.join('\n'), _confirmBoxTextOptions);
|
||||||
|
_note.setText(st::boxTextFont, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
|
||||||
|
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
||||||
|
_textHeight = _text.countHeight(_textWidth);
|
||||||
|
setMaxHeight(st::boxTitleHeight + _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth) + st::boxButtonPadding.top() + _convert.height() + st::boxButtonPadding.bottom());
|
||||||
|
textstyleRestore();
|
||||||
|
|
||||||
|
connect(&_convert, SIGNAL(clicked()), this, SLOT(onConvert()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::onConvert() {
|
||||||
|
MTP::send(MTPmessages_MigrateChat(_chat->inputChat), rpcDone(&ConvertToSupergroupBox::convertDone), rpcFail(&ConvertToSupergroupBox::convertFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
const QVector<MTPChat> *v = 0;
|
||||||
|
switch (updates.type()) {
|
||||||
|
case mtpc_updates: v = &updates.c_updates().vchats.c_vector().v; break;
|
||||||
|
case mtpc_updatesCombined: v = &updates.c_updatesCombined().vchats.c_vector().v; break;
|
||||||
|
default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerData *peer = 0;
|
||||||
|
if (v && !v->isEmpty()) {
|
||||||
|
for (int32 i = 0, l = v->size(); i < l; ++i) {
|
||||||
|
if (v->at(i).type() == mtpc_channel) {
|
||||||
|
peer = App::channel(v->at(i).c_channel().vid.v);
|
||||||
|
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||||
|
QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!peer) {
|
||||||
|
LOG(("API Error: channel not found in updates (ProfileInner::migrateDone)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConvertToSupergroupBox::convertFail(const RPCError &error) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::hideAll() {
|
||||||
|
_convert.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::showAll() {
|
||||||
|
_convert.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::keyPressEvent(QKeyEvent *e) {
|
||||||
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||||
|
onConvert();
|
||||||
|
} else {
|
||||||
|
AbstractBox::keyPressEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
if (paint(p)) return;
|
||||||
|
|
||||||
|
paintTitle(p, lang(lng_profile_convert_title));
|
||||||
|
|
||||||
|
// draw box title / text
|
||||||
|
p.setPen(st::black);
|
||||||
|
textstyleSet(&st::boxTextStyle);
|
||||||
|
_text.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight, _textWidth, width());
|
||||||
|
_note.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight + _textHeight + st::boxPadding.bottom(), _textWidth, width());
|
||||||
|
textstyleRestore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_convert.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _convert.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _convert.width() + st::boxButtonPadding.left(), _convert.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
PinMessageBox::PinMessageBox(ChannelData *channel, MsgId msgId) : AbstractBox(st::boxWidth)
|
||||||
|
, _channel(channel)
|
||||||
|
, _msgId(msgId)
|
||||||
|
, _text(this, lang(lng_pinned_pin_sure), st::boxLabel)
|
||||||
|
, _notify(this, lang(lng_pinned_notify), true)
|
||||||
|
, _pin(this, lang(lng_pinned_pin), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
|
, _requestId(0) {
|
||||||
|
_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||||
|
setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _notify.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _pin.height() + st::boxButtonPadding.bottom());
|
||||||
|
|
||||||
|
connect(&_pin, SIGNAL(clicked()), this, SLOT(onPin()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_text.moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
||||||
|
_notify.moveToLeft(st::boxPadding.left(), _text.y() + _text.height() + st::boxMediumSkip);
|
||||||
|
_pin.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _pin.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _pin.width() + st::boxButtonPadding.left(), _pin.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::onPin() {
|
||||||
|
if (_requestId) return;
|
||||||
|
|
||||||
|
int32 flags = _notify.checked() ? 0 : MTPchannels_UpdatePinnedMessage::flag_silent;
|
||||||
|
_requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_int(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::showAll() {
|
||||||
|
_text.show();
|
||||||
|
_notify.show();
|
||||||
|
_pin.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::hideAll() {
|
||||||
|
_text.hide();
|
||||||
|
_notify.hide();
|
||||||
|
_pin.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::pinDone(const MTPUpdates &updates) {
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
|
Ui::hideLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PinMessageBox::pinFail(const RPCError &error) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RichDeleteMessageBox::RichDeleteMessageBox(ChannelData *channel, UserData *from, MsgId msgId) : AbstractBox(st::boxWidth)
|
||||||
|
, _channel(channel)
|
||||||
|
, _from(from)
|
||||||
|
, _msgId(msgId)
|
||||||
|
, _text(this, lang(lng_selected_delete_sure_this), st::boxLabel)
|
||||||
|
, _banUser(this, lang(lng_ban_user), false)
|
||||||
|
, _reportSpam(this, lang(lng_report_spam), false)
|
||||||
|
, _deleteAll(this, lang(lng_delete_all_from), false)
|
||||||
|
, _delete(this, lang(lng_box_delete), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
t_assert(_channel != nullptr);
|
||||||
|
|
||||||
|
_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||||
|
setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _banUser.height() + st::boxLittleSkip + _reportSpam.height() + st::boxLittleSkip + _deleteAll.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _delete.height() + st::boxButtonPadding.bottom());
|
||||||
|
|
||||||
|
connect(&_delete, SIGNAL(clicked()), this, SLOT(onDelete()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_text.moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
||||||
|
_banUser.moveToLeft(st::boxPadding.left(), _text.y() + _text.height() + st::boxMediumSkip);
|
||||||
|
_reportSpam.moveToLeft(st::boxPadding.left(), _banUser.y() + _banUser.height() + st::boxLittleSkip);
|
||||||
|
_deleteAll.moveToLeft(st::boxPadding.left(), _reportSpam.y() + _reportSpam.height() + st::boxLittleSkip);
|
||||||
|
_delete.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _delete.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _delete.width() + st::boxButtonPadding.left(), _delete.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::onDelete() {
|
||||||
|
if (_banUser.checked()) {
|
||||||
|
MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
|
||||||
|
}
|
||||||
|
if (_reportSpam.checked()) {
|
||||||
|
MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId))));
|
||||||
|
}
|
||||||
|
if (_deleteAll.checked()) {
|
||||||
|
App::main()->deleteAllFromUser(_channel, _from);
|
||||||
|
}
|
||||||
|
if (auto item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
|
||||||
|
bool wasLast = (item->history()->lastMsg == item);
|
||||||
|
item->destroy();
|
||||||
|
if (_msgId > 0) {
|
||||||
|
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)));
|
||||||
|
} else if (wasLast) {
|
||||||
|
App::main()->checkPeerHistory(_channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Notify::historyItemsResized();
|
||||||
|
Ui::hideLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::showAll() {
|
||||||
|
_text.show();
|
||||||
|
_banUser.show();
|
||||||
|
_reportSpam.show();
|
||||||
|
_deleteAll.show();
|
||||||
|
_delete.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::hideAll() {
|
||||||
|
_text.hide();
|
||||||
|
_banUser.hide();
|
||||||
|
_reportSpam.hide();
|
||||||
|
_deleteAll.hide();
|
||||||
|
_delete.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public:
|
||||||
void mouseMoveEvent(QMouseEvent *e);
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
void mousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void hideAll();
|
void hideAll();
|
||||||
|
@ -133,3 +133,100 @@ private:
|
||||||
anim::fvalue a_goodOpacity;
|
anim::fvalue a_goodOpacity;
|
||||||
Animation _a_good;
|
Animation _a_good;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConvertToSupergroupBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ConvertToSupergroupBox(ChatData *chat);
|
||||||
|
void keyPressEvent(QKeyEvent *e);
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onConvert();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void hideAll();
|
||||||
|
void showAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void convertDone(const MTPUpdates &updates);
|
||||||
|
bool convertFail(const RPCError &error);
|
||||||
|
|
||||||
|
ChatData *_chat;
|
||||||
|
Text _text, _note;
|
||||||
|
int32 _textWidth, _textHeight;
|
||||||
|
|
||||||
|
BoxButton _convert, _cancel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PinMessageBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PinMessageBox(ChannelData *channel, MsgId msgId);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onPin();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void showAll();
|
||||||
|
void hideAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void pinDone(const MTPUpdates &updates);
|
||||||
|
bool pinFail(const RPCError &error);
|
||||||
|
|
||||||
|
ChannelData *_channel;
|
||||||
|
MsgId _msgId;
|
||||||
|
|
||||||
|
FlatLabel _text;
|
||||||
|
Checkbox _notify;
|
||||||
|
|
||||||
|
BoxButton _pin, _cancel;
|
||||||
|
|
||||||
|
mtpRequestId _requestId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RichDeleteMessageBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RichDeleteMessageBox(ChannelData *channel, UserData *from, MsgId msgId);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onDelete();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void showAll();
|
||||||
|
void hideAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ChannelData *_channel;
|
||||||
|
UserData *_from;
|
||||||
|
MsgId _msgId;
|
||||||
|
|
||||||
|
FlatLabel _text;
|
||||||
|
Checkbox _banUser, _reportSpam, _deleteAll;
|
||||||
|
|
||||||
|
BoxButton _delete, _cancel;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -257,6 +257,18 @@ void ContactsInner::addAdminDone(const MTPUpdates &result, mtpRequestId req) {
|
||||||
if (req != _addAdminRequestId) return;
|
if (req != _addAdminRequestId) return;
|
||||||
|
|
||||||
_addAdminRequestId = 0;
|
_addAdminRequestId = 0;
|
||||||
|
if (_addAdmin && _channel && _channel->isMegagroup()) {
|
||||||
|
if (_channel->mgInfo->lastParticipants.indexOf(_addAdmin) < 0) {
|
||||||
|
_channel->mgInfo->lastParticipants.push_front(_addAdmin);
|
||||||
|
}
|
||||||
|
_channel->mgInfo->lastAdmins.insert(_addAdmin);
|
||||||
|
if (_addAdmin->botInfo) {
|
||||||
|
_channel->mgInfo->bots.insert(_addAdmin);
|
||||||
|
if (_channel->mgInfo->botStatus != 0 && _channel->mgInfo->botStatus < 2) {
|
||||||
|
_channel->mgInfo->botStatus = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_addAdminBox) _addAdminBox->onClose();
|
if (_addAdminBox) _addAdminBox->onClose();
|
||||||
emit adminAdded();
|
emit adminAdded();
|
||||||
}
|
}
|
||||||
|
@ -427,7 +439,7 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b
|
||||||
sel = false;
|
sel = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (data->inchat || data->check || selectedCount() >= ((_channel && _channel->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
|
if (data->inchat || data->check || selectedCount() >= Global::MegagroupSizeMax()) {
|
||||||
sel = false;
|
sel = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,6 +783,8 @@ void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) {
|
||||||
data->check = true;
|
data->check = true;
|
||||||
_checkedContacts.insert(peer, true);
|
_checkedContacts.insert(peer, true);
|
||||||
++_selCount;
|
++_selCount;
|
||||||
|
} else if ((!_channel || !_channel->isMegagroup()) && selectedCount() >= Global::ChatSizeMax() && selectedCount() < Global::MegagroupSizeMax()) {
|
||||||
|
Ui::showLayer(new InformBox(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())), KeepOtherLayers);
|
||||||
}
|
}
|
||||||
if (cnt != _selCount) emit chosenChanged();
|
if (cnt != _selCount) emit chosenChanged();
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1549,7 @@ void ContactsBox::paintEvent(QPaintEvent *e) {
|
||||||
paintTitle(p, lang(lng_channel_admins));
|
paintTitle(p, lang(lng_channel_admins));
|
||||||
} else if (_inner.chat() || _inner.creating() != CreatingGroupNone) {
|
} else if (_inner.chat() || _inner.creating() != CreatingGroupNone) {
|
||||||
QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant));
|
QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant));
|
||||||
QString additional(addingAdmin ? QString() : QString("%1 / %2").arg(_inner.selectedCount()).arg(((_inner.channel() && _inner.channel()->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())));
|
QString additional(addingAdmin ? QString() : QString("%1 / %2").arg(_inner.selectedCount()).arg(Global::MegagroupSizeMax()));
|
||||||
paintTitle(p, title, additional);
|
paintTitle(p, title, additional);
|
||||||
} else if (_inner.bot()) {
|
} else if (_inner.bot()) {
|
||||||
paintTitle(p, lang(lng_bot_choose_group));
|
paintTitle(p, lang(lng_bot_choose_group));
|
||||||
|
@ -1669,7 +1683,7 @@ void ContactsBox::setAdminDone(UserData *user, const MTPBool &result) {
|
||||||
if (_inner.chat()->noParticipantInfo()) {
|
if (_inner.chat()->noParticipantInfo()) {
|
||||||
App::api()->requestFullPeer(_inner.chat());
|
App::api()->requestFullPeer(_inner.chat());
|
||||||
} else {
|
} else {
|
||||||
_inner.chat()->admins.insert(user, true);
|
_inner.chat()->admins.insert(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--_saveRequestId;
|
--_saveRequestId;
|
||||||
|
@ -2182,6 +2196,16 @@ void MembersInner::membersReceived(const MTPchannels_ChannelParticipants &result
|
||||||
_datas.push_back(0);
|
_datas.push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update admins if we got all of them
|
||||||
|
if (_filter == MembersFilterAdmins && _channel->isMegagroup() && _rows.size() < Global::ChatSizeMax()) {
|
||||||
|
_channel->mgInfo->lastAdmins.clear();
|
||||||
|
for (int32 i = 0, l = _rows.size(); i != l; ++i) {
|
||||||
|
if (_roles.at(i) == MemberRoleCreator || _roles.at(i) == MemberRoleEditor) {
|
||||||
|
_channel->mgInfo->lastAdmins.insert(_rows.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_rows.isEmpty()) {
|
if (_rows.isEmpty()) {
|
||||||
_rows.push_back(App::self());
|
_rows.push_back(App::self());
|
||||||
|
|
|
@ -22,8 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
static const int32 AppVersion = 9030;
|
static const int32 AppVersion = 9030;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.30";
|
static const wchar_t *AppVersionStr = L"0.9.30";
|
||||||
static const bool DevVersion = true;
|
static const bool DevVersion = false;
|
||||||
//#define BETA_VERSION (9028002ULL) // just comment this line to build public version
|
#define BETA_VERSION (9030002ULL) // just comment this line to build public version
|
||||||
|
|
||||||
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";
|
||||||
|
@ -171,6 +171,8 @@ enum {
|
||||||
|
|
||||||
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
||||||
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
|
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
|
||||||
|
|
||||||
|
PinnedMessageTextLimit = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool isNotificationsUser(uint64 id) {
|
inline bool isNotificationsUser(uint64 id) {
|
||||||
|
|
|
@ -619,7 +619,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (_menuPeer->isUser()) {
|
if (_menuPeer->isUser()) {
|
||||||
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
_menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
||||||
if (_menuPeer->asUser()->access != UserNoAccess) {
|
if (_menuPeer->asUser()->access != UserNoAccess && _menuPeer != App::self()) {
|
||||||
_menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true);
|
_menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true);
|
||||||
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
}
|
}
|
||||||
|
@ -2094,6 +2094,7 @@ void DialogsWidget::onChooseByDrag() {
|
||||||
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
||||||
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||||
if (inPeer) {
|
if (inPeer) {
|
||||||
|
onCancelSearch();
|
||||||
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
||||||
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
||||||
_inner.searchInPeer(_searchInPeer);
|
_inner.searchInPeer(_searchInPeer);
|
||||||
|
|
|
@ -4578,10 +4578,10 @@ void MentionsDropdown::recount(bool resetScroll) {
|
||||||
if (h > _boundings.height()) h = _boundings.height();
|
if (h > _boundings.height()) h = _boundings.height();
|
||||||
if (h > maxh) h = maxh;
|
if (h > maxh) h = maxh;
|
||||||
if (width() != _boundings.width() || height() != h) {
|
if (width() != _boundings.width() || height() != h) {
|
||||||
setGeometry(0, _boundings.height() - h, _boundings.width(), h);
|
setGeometry(_boundings.x(), _boundings.y() + _boundings.height() - h, _boundings.width(), h);
|
||||||
_scroll.resize(_boundings.width(), h);
|
_scroll.resize(_boundings.width(), h);
|
||||||
} else if (y() != _boundings.height() - h) {
|
} else if (y() != _boundings.y() + _boundings.height() - h) {
|
||||||
move(0, _boundings.height() - h);
|
move(_boundings.x(), _boundings.y() + _boundings.height() - h);
|
||||||
}
|
}
|
||||||
if (resetScroll) st = 0;
|
if (resetScroll) st = 0;
|
||||||
if (st != oldst) _scroll.scrollToY(st);
|
if (st != oldst) _scroll.scrollToY(st);
|
||||||
|
|
|
@ -371,6 +371,8 @@ struct GlobalDataStruct {
|
||||||
int32 PushChatLimit = 2;
|
int32 PushChatLimit = 2;
|
||||||
int32 SavedGifsLimit = 200;
|
int32 SavedGifsLimit = 200;
|
||||||
int32 EditTimeLimit = 172800;
|
int32 EditTimeLimit = 172800;
|
||||||
|
|
||||||
|
Global::HiddenPinnedMessagesMap HiddenPinnedMessages;
|
||||||
};
|
};
|
||||||
GlobalDataStruct *GlobalData = 0;
|
GlobalDataStruct *GlobalData = 0;
|
||||||
|
|
||||||
|
@ -413,4 +415,6 @@ namespace Global {
|
||||||
DefineVar(Global, int32, SavedGifsLimit);
|
DefineVar(Global, int32, SavedGifsLimit);
|
||||||
DefineVar(Global, int32, EditTimeLimit);
|
DefineVar(Global, int32, EditTimeLimit);
|
||||||
|
|
||||||
|
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -159,6 +159,9 @@ namespace Global {
|
||||||
DeclareVar(int32, SavedGifsLimit);
|
DeclareVar(int32, SavedGifsLimit);
|
||||||
DeclareVar(int32, EditTimeLimit);
|
DeclareVar(int32, EditTimeLimit);
|
||||||
|
|
||||||
|
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
|
||||||
|
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Adaptive {
|
namespace Adaptive {
|
||||||
|
|
|
@ -53,6 +53,13 @@ void FlatLabel::setRichText(const QString &text) {
|
||||||
setMouseTracking(_text.hasLinks());
|
setMouseTracking(_text.hasLinks());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatLabel::resizeToWidth(int32 width) {
|
||||||
|
textstyleSet(&_tst);
|
||||||
|
int32 w = width, h = _text.countHeight(w);
|
||||||
|
textstyleRestore();
|
||||||
|
resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
void FlatLabel::setLink(uint16 lnkIndex, const TextLinkPtr &lnk) {
|
void FlatLabel::setLink(uint16 lnkIndex, const TextLinkPtr &lnk) {
|
||||||
_text.setLink(lnkIndex, lnk);
|
_text.setLink(lnkIndex, lnk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ public:
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
void setRichText(const QString &text);
|
void setRichText(const QString &text);
|
||||||
|
|
||||||
|
void resizeToWidth(int32 width);
|
||||||
|
|
||||||
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -212,6 +212,18 @@ QString textcmdStopColor() {
|
||||||
return result.append(TextCommand).append(QChar(TextCommandNoColor)).append(TextCommand);
|
return result.append(TextCommand).append(QChar(TextCommandNoColor)).append(TextCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString textcmdStartSemibold() {
|
||||||
|
QString result;
|
||||||
|
result.reserve(3);
|
||||||
|
return result.append(TextCommand).append(QChar(TextCommandSemibold)).append(TextCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString textcmdStopSemibold() {
|
||||||
|
QString result;
|
||||||
|
result.reserve(3);
|
||||||
|
return result.append(TextCommand).append(QChar(TextCommandNoSemibold)).append(TextCommand);
|
||||||
|
}
|
||||||
|
|
||||||
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink) {
|
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink) {
|
||||||
const QChar *result = from + 1;
|
const QChar *result = from + 1;
|
||||||
if (*from != TextCommand || result >= end) return from;
|
if (*from != TextCommand || result >= end) return from;
|
||||||
|
@ -223,6 +235,8 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink)
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TextCommandBold:
|
case TextCommandBold:
|
||||||
case TextCommandNoBold:
|
case TextCommandNoBold:
|
||||||
|
case TextCommandSemibold:
|
||||||
|
case TextCommandNoSemibold:
|
||||||
case TextCommandItalic:
|
case TextCommandItalic:
|
||||||
case TextCommandNoItalic:
|
case TextCommandNoItalic:
|
||||||
case TextCommandUnderline:
|
case TextCommandUnderline:
|
||||||
|
@ -498,6 +512,20 @@ public:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TextCommandSemibold:
|
||||||
|
if (!(flags & TextBlockFSemibold)) {
|
||||||
|
createBlock();
|
||||||
|
flags |= TextBlockFSemibold;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextCommandNoSemibold:
|
||||||
|
if (flags & TextBlockFSemibold) {
|
||||||
|
createBlock();
|
||||||
|
flags &= ~TextBlockFSemibold;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TextCommandItalic:
|
case TextCommandItalic:
|
||||||
if (!(flags & TextBlockFItalic)) {
|
if (!(flags & TextBlockFItalic)) {
|
||||||
createBlock();
|
createBlock();
|
||||||
|
|
|
@ -564,11 +564,13 @@ enum TextCommands {
|
||||||
TextCommandNoItalic = 0x04,
|
TextCommandNoItalic = 0x04,
|
||||||
TextCommandUnderline = 0x05,
|
TextCommandUnderline = 0x05,
|
||||||
TextCommandNoUnderline = 0x06,
|
TextCommandNoUnderline = 0x06,
|
||||||
TextCommandLinkIndex = 0x07, // 0 - NoLink
|
TextCommandSemibold = 0x07,
|
||||||
TextCommandLinkText = 0x08,
|
TextCommandNoSemibold = 0x08,
|
||||||
TextCommandColor = 0x09,
|
TextCommandLinkIndex = 0x09, // 0 - NoLink
|
||||||
TextCommandNoColor = 0x0A,
|
TextCommandLinkText = 0x0A,
|
||||||
TextCommandSkipBlock = 0x0B,
|
TextCommandColor = 0x0B,
|
||||||
|
TextCommandNoColor = 0x0C,
|
||||||
|
TextCommandSkipBlock = 0x0D,
|
||||||
|
|
||||||
TextCommandLangTag = 0x20,
|
TextCommandLangTag = 0x20,
|
||||||
};
|
};
|
||||||
|
@ -747,6 +749,8 @@ QString textcmdLink(ushort lnkIndex, const QString &text);
|
||||||
QString textcmdLink(const QString &url, const QString &text);
|
QString textcmdLink(const QString &url, const QString &text);
|
||||||
QString textcmdStartColor(const style::color &color);
|
QString textcmdStartColor(const style::color &color);
|
||||||
QString textcmdStopColor();
|
QString textcmdStopColor();
|
||||||
|
QString textcmdStartSemibold();
|
||||||
|
QString textcmdStopSemibold();
|
||||||
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink = true);
|
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink = true);
|
||||||
|
|
||||||
inline bool chIsSpace(QChar ch, bool rich = false) {
|
inline bool chIsSpace(QChar ch, bool rich = false) {
|
||||||
|
|
|
@ -204,3 +204,28 @@ private:
|
||||||
const style::color &_color;
|
const style::color &_color;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SingleDelayedCall : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SingleDelayedCall(QObject *parent, const char *member) : QObject(parent), _pending(false), _member(member) {
|
||||||
|
}
|
||||||
|
void call() {
|
||||||
|
if (!_pending) {
|
||||||
|
_pending = true;
|
||||||
|
QMetaObject::invokeMethod(this, "makeDelayedCall", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void makeDelayedCall() {
|
||||||
|
_pending = false;
|
||||||
|
QMetaObject::invokeMethod(parent(), _member);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _pending;
|
||||||
|
const char *_member;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -1409,7 +1409,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
||||||
}
|
}
|
||||||
if (user->botInfo) {
|
if (user->botInfo) {
|
||||||
peer->asChannel()->mgInfo->bots.insert(user, true);
|
peer->asChannel()->mgInfo->bots.insert(user);
|
||||||
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
||||||
peer->asChannel()->mgInfo->botStatus = 2;
|
peer->asChannel()->mgInfo->botStatus = 2;
|
||||||
}
|
}
|
||||||
|
@ -1427,7 +1427,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
peer->asChannel()->mgInfo->lastParticipants.push_front(result->from()->asUser());
|
peer->asChannel()->mgInfo->lastParticipants.push_front(result->from()->asUser());
|
||||||
}
|
}
|
||||||
if (result->from()->asUser()->botInfo) {
|
if (result->from()->asUser()->botInfo) {
|
||||||
peer->asChannel()->mgInfo->bots.insert(result->from()->asUser(), true);
|
peer->asChannel()->mgInfo->bots.insert(result->from()->asUser());
|
||||||
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
||||||
peer->asChannel()->mgInfo->botStatus = 2;
|
peer->asChannel()->mgInfo->botStatus = 2;
|
||||||
}
|
}
|
||||||
|
@ -1454,7 +1454,18 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
peer->asChannel()->mgInfo->lastParticipants.removeAt(index);
|
peer->asChannel()->mgInfo->lastParticipants.removeAt(index);
|
||||||
}
|
}
|
||||||
peer->asChannel()->mgInfo->lastAdmins.remove(user);
|
if (peer->asChannel()->count > 1) {
|
||||||
|
--peer->asChannel()->count;
|
||||||
|
} else {
|
||||||
|
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
|
||||||
|
peer->asChannel()->mgInfo->lastParticipantsCount = 0;
|
||||||
|
}
|
||||||
|
if (peer->asChannel()->mgInfo->lastAdmins.contains(user)) {
|
||||||
|
peer->asChannel()->mgInfo->lastAdmins.remove(user);
|
||||||
|
if (peer->asChannel()->adminsCount > 1) {
|
||||||
|
--peer->asChannel()->adminsCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
peer->asChannel()->mgInfo->bots.remove(user);
|
peer->asChannel()->mgInfo->bots.remove(user);
|
||||||
if (peer->asChannel()->mgInfo->bots.isEmpty() && peer->asChannel()->mgInfo->botStatus > 0) {
|
if (peer->asChannel()->mgInfo->bots.isEmpty() && peer->asChannel()->mgInfo->botStatus > 0) {
|
||||||
peer->asChannel()->mgInfo->botStatus = -1;
|
peer->asChannel()->mgInfo->botStatus = -1;
|
||||||
|
@ -1509,6 +1520,13 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
//const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
|
//const MTPDmessageActionChannelMigrateFrom &d(action.c_messageActionChannelMigrateFrom());
|
||||||
//PeerData *chat = App::peerLoaded(peerFromChat(d.vchat_id));
|
//PeerData *chat = App::peerLoaded(peerFromChat(d.vchat_id));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case mtpc_messageActionPinMessage: {
|
||||||
|
if (d.has_reply_to_msg_id() && result && result->history()->peer->isMegagroup()) {
|
||||||
|
result->history()->peer->asChannel()->mgInfo->pinnedMsgId = d.vreply_to_msg_id.v;
|
||||||
|
if (App::main()) emit App::main()->peerUpdated(result->history()->peer);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -1540,7 +1558,7 @@ HistoryItem *History::createItemDocument(HistoryBlock *block, MsgId id, int32 fl
|
||||||
HistoryItem *History::createItemPhoto(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
|
HistoryItem *History::createItemPhoto(HistoryBlock *block, MsgId id, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
|
||||||
HistoryItem *result = 0;
|
HistoryItem *result = 0;
|
||||||
|
|
||||||
if (flags & MTPDmessage::flag_reply_to_msg_id && replyTo > 0) {
|
if ((flags & MTPDmessage::flag_reply_to_msg_id) && replyTo > 0) {
|
||||||
result = new HistoryReply(this, block, id, flags, viaBotId, replyTo, date, from, photo, caption);
|
result = new HistoryReply(this, block, id, flags, viaBotId, replyTo, date, from, photo, caption);
|
||||||
} else {
|
} else {
|
||||||
result = new HistoryMessage(this, block, id, flags, viaBotId, date, from, photo, caption);
|
result = new HistoryMessage(this, block, id, flags, viaBotId, date, from, photo, caption);
|
||||||
|
@ -1735,7 +1753,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
||||||
} else if (peer->isMegagroup()) {
|
} else if (peer->isMegagroup()) {
|
||||||
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
||||||
if (adding->from()->asUser()->botInfo) {
|
if (adding->from()->asUser()->botInfo) {
|
||||||
peer->asChannel()->mgInfo->bots.insert(adding->from()->asUser(), true);
|
peer->asChannel()->mgInfo->bots.insert(adding->from()->asUser());
|
||||||
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
if (peer->asChannel()->mgInfo->botStatus != 0 && peer->asChannel()->mgInfo->botStatus < 2) {
|
||||||
peer->asChannel()->mgInfo->botStatus = 2;
|
peer->asChannel()->mgInfo->botStatus = 2;
|
||||||
}
|
}
|
||||||
|
@ -1756,14 +1774,14 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
|
||||||
if (adding->hasReplyMarkup()) {
|
if (adding->hasReplyMarkup()) {
|
||||||
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
int32 markupFlags = App::replyMarkup(channelId(), adding->id).flags;
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || adding->mentionsMe()) {
|
||||||
QMap<PeerData*, bool> *markupSenders = 0;
|
OrderedSet<PeerData*> *markupSenders = 0;
|
||||||
if (peer->isChat()) {
|
if (peer->isChat()) {
|
||||||
markupSenders = &peer->asChat()->markupSenders;
|
markupSenders = &peer->asChat()->markupSenders;
|
||||||
} else if (peer->isMegagroup()) {
|
} else if (peer->isMegagroup()) {
|
||||||
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
||||||
}
|
}
|
||||||
if (markupSenders) {
|
if (markupSenders) {
|
||||||
markupSenders->insert(adding->from(), true);
|
markupSenders->insert(adding->from());
|
||||||
}
|
}
|
||||||
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
|
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
|
||||||
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !peer->isMegagroup() && !adding->out())) {
|
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !peer->isMegagroup() && !adding->out())) {
|
||||||
|
@ -1970,7 +1988,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
bool channel = isChannel();
|
bool channel = isChannel();
|
||||||
int32 mask = 0;
|
int32 mask = 0;
|
||||||
QList<UserData*> *lastAuthors = 0;
|
QList<UserData*> *lastAuthors = 0;
|
||||||
QMap<PeerData*, bool> *markupSenders = 0;
|
OrderedSet<PeerData*> *markupSenders = 0;
|
||||||
if (peer->isChat()) {
|
if (peer->isChat()) {
|
||||||
lastAuthors = &peer->asChat()->lastAuthors;
|
lastAuthors = &peer->asChat()->lastAuthors;
|
||||||
markupSenders = &peer->asChat()->markupSenders;
|
markupSenders = &peer->asChat()->markupSenders;
|
||||||
|
@ -2000,7 +2018,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::flag_selective) || item->mentionsMe()) {
|
||||||
bool wasKeyboardHide = markupSenders->contains(item->author());
|
bool wasKeyboardHide = markupSenders->contains(item->author());
|
||||||
if (!wasKeyboardHide) {
|
if (!wasKeyboardHide) {
|
||||||
markupSenders->insert(item->author(), true);
|
markupSenders->insert(item->author());
|
||||||
}
|
}
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
||||||
if (!lastKeyboardInited) {
|
if (!lastKeyboardInited) {
|
||||||
|
@ -2902,6 +2920,12 @@ void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryDependentItemCallback::call(ChannelData *channel, MsgId msgId) const {
|
||||||
|
if (HistoryItem *item = App::histItemById(_dependent)) {
|
||||||
|
item->updateDependencyItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from) : y(0)
|
HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from) : y(0)
|
||||||
, id(msgId)
|
, id(msgId)
|
||||||
, date(msgDate)
|
, date(msgDate)
|
||||||
|
@ -2918,6 +2942,9 @@ void HistoryItem::destroy() {
|
||||||
detach();
|
detach();
|
||||||
if (history()->isChannel()) {
|
if (history()->isChannel()) {
|
||||||
history()->asChannelHistory()->messageDeleted(this);
|
history()->asChannelHistory()->messageDeleted(this);
|
||||||
|
if (history()->peer->isMegagroup() && history()->peer->asChannel()->mgInfo->pinnedMsgId == id) {
|
||||||
|
history()->peer->asChannel()->mgInfo->pinnedMsgId = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (history()->lastMsg == this) {
|
if (history()->lastMsg == this) {
|
||||||
history()->fixLastMessage(wasAtBottom);
|
history()->fixLastMessage(wasAtBottom);
|
||||||
|
@ -3563,7 +3590,7 @@ ImagePtr HistoryPhoto::replyPreview() {
|
||||||
return _data->makeReplyPreview();
|
return _data->makeReplyPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryVideo::HistoryVideo(DocumentData *document, const QString &caption, HistoryItem *parent) : HistoryFileMedia()
|
HistoryVideo::HistoryVideo(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
||||||
, _data(document)
|
, _data(document)
|
||||||
, _thumbw(1)
|
, _thumbw(1)
|
||||||
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
|
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
|
||||||
|
@ -3643,6 +3670,7 @@ int32 HistoryVideo::resize(int32 width, const HistoryItem *parent) {
|
||||||
tw = width;
|
tw = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_thumbw = qMax(tw, 1);
|
||||||
int32 minWidth = qMax(st::minPhotoSize, parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
int32 minWidth = qMax(st::minPhotoSize, parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
||||||
minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
||||||
_width = qMax(_thumbw, int32(minWidth));
|
_width = qMax(_thumbw, int32(minWidth));
|
||||||
|
@ -5229,6 +5257,8 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||||
_attach = new HistorySticker(_data->doc);
|
_attach = new HistorySticker(_data->doc);
|
||||||
} else if (_data->doc->isAnimation()) {
|
} else if (_data->doc->isAnimation()) {
|
||||||
_attach = new HistoryGif(_data->doc, QString(), parent);
|
_attach = new HistoryGif(_data->doc, QString(), parent);
|
||||||
|
} else if (_data->doc->isVideo()) {
|
||||||
|
_attach = new HistoryVideo(_data->doc, QString(), parent);
|
||||||
} else {
|
} else {
|
||||||
_attach = new HistoryDocument(_data->doc, QString(), parent);
|
_attach = new HistoryDocument(_data->doc, QString(), parent);
|
||||||
}
|
}
|
||||||
|
@ -6891,7 +6921,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||||
bool inText = false;
|
bool inText = false;
|
||||||
bool breakEverywhere = (fwd->_text.countHeight(trect.width()) > 2 * st::semiboldFont->height);
|
bool breakEverywhere = (fwd->_text.countHeight(trect.width()) > 2 * st::semiboldFont->height);
|
||||||
textstyleSet(&st::inFwdTextStyle);
|
textstyleSet(&st::inFwdTextStyle);
|
||||||
fwd->_text.getState(lnk, inText, x - trect.left(), y - trect.top(), trect.right() - trect.left(), style::al_left, breakEverywhere);
|
fwd->_text.getState(lnk, inText, x - trect.left(), y - trect.top(), trect.width(), style::al_left, breakEverywhere);
|
||||||
textstyleRestore();
|
textstyleRestore();
|
||||||
if (breakEverywhere) {
|
if (breakEverywhere) {
|
||||||
state = HistoryInForwardedCursorState;
|
state = HistoryInForwardedCursorState;
|
||||||
|
@ -7035,7 +7065,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmess
|
||||||
, _maxReplyWidth(0)
|
, _maxReplyWidth(0)
|
||||||
, _replyToVia(0) {
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7047,7 +7077,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
|
||||||
, _maxReplyWidth(0)
|
, _maxReplyWidth(0)
|
||||||
, _replyToVia(0) {
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7059,7 +7089,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
|
||||||
, _maxReplyWidth(0)
|
, _maxReplyWidth(0)
|
||||||
, _replyToVia(0) {
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestMessageData(history->peer->asChannel(), replyToMsgId, new HistoryDependentItemCallback(fullId()));
|
||||||
}
|
}
|
||||||
replyToNameUpdated();
|
replyToNameUpdated();
|
||||||
}
|
}
|
||||||
|
@ -7085,11 +7115,19 @@ void HistoryReply::initDimensions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryReply::updateReplyTo(bool force) {
|
bool HistoryReply::updateReplyTo(bool force) {
|
||||||
if (replyToMsg || !replyToMsgId) return true;
|
if (!force) {
|
||||||
replyToMsg = App::histItemById(channelId(), replyToMsgId);
|
if (replyToMsg || !replyToMsgId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!replyToMsg) {
|
||||||
|
replyToMsg = App::histItemById(channelId(), replyToMsgId);
|
||||||
|
if (replyToMsg) {
|
||||||
|
App::historyRegDependency(this, replyToMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (replyToMsg) {
|
if (replyToMsg) {
|
||||||
App::historyRegReply(this, replyToMsg);
|
|
||||||
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
|
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
|
||||||
|
|
||||||
replyToNameUpdated();
|
replyToNameUpdated();
|
||||||
|
@ -7146,20 +7184,14 @@ HistoryItem *HistoryReply::replyToMessage() const {
|
||||||
return replyToMsg;
|
return replyToMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryReply::replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
void HistoryReply::dependencyItemRemoved(HistoryItem *dependency) {
|
||||||
if (replyToMsg == oldItem) {
|
if (replyToMsg == dependency) {
|
||||||
delete _replyToVia;
|
delete _replyToVia;
|
||||||
_replyToVia = 0;
|
_replyToVia = 0;
|
||||||
replyToMsg = newItem;
|
|
||||||
if (!newItem) {
|
replyToMsg = nullptr;
|
||||||
replyToMsgId = 0;
|
replyToMsgId = 0;
|
||||||
initDimensions();
|
initDimensions();
|
||||||
} else if (!replyToMsg->Is<HistoryMessageForwarded>()) {
|
|
||||||
if (UserData *bot = replyToMsg->viaBot()) {
|
|
||||||
_replyToVia = new HistoryMessageVia(0);
|
|
||||||
_replyToVia->create(peerToUser(bot->id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7301,7 +7333,7 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||||
|
|
||||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||||
if (y >= trect.top() && y < trect.top() + h) {
|
if (y >= trect.top() && y < trect.top() + h) {
|
||||||
if (replyToMsg && y >= trect.top() + st::msgReplyPadding.top() && y < trect.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() && x >= trect.left() && x < trect.right()) {
|
if (replyToMsg && y >= trect.top() + st::msgReplyPadding.top() && y < trect.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() && x >= trect.left() && x < trect.left() + trect.width()) {
|
||||||
lnk = replyToLnk;
|
lnk = replyToLnk;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -7347,13 +7379,16 @@ void HistoryReply::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, i
|
||||||
|
|
||||||
HistoryReply::~HistoryReply() {
|
HistoryReply::~HistoryReply() {
|
||||||
if (replyToMsg) {
|
if (replyToMsg) {
|
||||||
App::historyUnregReply(this, replyToMsg);
|
App::historyUnregDependency(this, replyToMsg);
|
||||||
} else if (replyToMsgId && App::api()) {
|
|
||||||
App::api()->itemRemoved(this);
|
|
||||||
}
|
}
|
||||||
deleteAndMark(_replyToVia);
|
deleteAndMark(_replyToVia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HistoryServicePinned::HistoryServicePinned(Interfaces *)
|
||||||
|
: msgId(0)
|
||||||
|
, msg(0) {
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
QList<TextLinkPtr> links;
|
QList<TextLinkPtr> links;
|
||||||
LangString text = lang(lng_message_empty);
|
LangString text = lang(lng_message_empty);
|
||||||
|
@ -7396,9 +7431,6 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
text = lng_action_add_users_many(lt_from, from, lt_users, text);
|
text = lng_action_add_users_many(lt_from, from, lt_users, text);
|
||||||
}
|
}
|
||||||
if (foundSelf) {
|
if (foundSelf) {
|
||||||
if (unread() && history()->peer->isChat() && !history()->peer->asChat()->inviterForSpamReport && _from->isUser()) {
|
|
||||||
history()->peer->asChat()->inviterForSpamReport = peerToUser(_from->id);
|
|
||||||
}
|
|
||||||
if (history()->peer->isMegagroup()) {
|
if (history()->peer->isMegagroup()) {
|
||||||
history()->peer->asChannel()->mgInfo->joinedMessageFound = true;
|
history()->peer->asChannel()->mgInfo->joinedMessageFound = true;
|
||||||
}
|
}
|
||||||
|
@ -7422,11 +7454,6 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
case mtpc_messageActionChatCreate: {
|
case mtpc_messageActionChatCreate: {
|
||||||
const MTPDmessageActionChatCreate &d(action.c_messageActionChatCreate());
|
const MTPDmessageActionChatCreate &d(action.c_messageActionChatCreate());
|
||||||
text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle)));
|
text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle)));
|
||||||
if (unread()) {
|
|
||||||
if (history()->peer->isChat() && !history()->peer->asChat()->inviterForSpamReport && _from->isUser() && peerToUser(_from->id) != MTP::authedId()) {
|
|
||||||
history()->peer->asChat()->inviterForSpamReport = peerToUser(_from->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChannelCreate: {
|
case mtpc_messageActionChannelCreate: {
|
||||||
|
@ -7486,6 +7513,15 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case mtpc_messageActionPinMessage: {
|
||||||
|
if (updatePinnedText(&from, &text)) {
|
||||||
|
HistoryServicePinned *pinned = Get<HistoryServicePinned>();
|
||||||
|
t_assert(pinned != nullptr);
|
||||||
|
|
||||||
|
links.push_back(pinned->lnk);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
default: from = QString(); break;
|
default: from = QString(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7500,19 +7536,136 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HistoryServiceMsg::updatePinned(bool force) {
|
||||||
|
HistoryServicePinned *pinned = Get<HistoryServicePinned>();
|
||||||
|
t_assert(pinned != nullptr);
|
||||||
|
|
||||||
|
if (!force) {
|
||||||
|
if (!pinned->msgId || pinned->msg) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pinned->lnk) {
|
||||||
|
pinned->lnk = TextLinkPtr(new MessageLink(history()->peer->id, pinned->msgId));
|
||||||
|
}
|
||||||
|
bool gotDependencyItem = false;
|
||||||
|
if (!pinned->msg) {
|
||||||
|
pinned->msg = App::histItemById(channelId(), pinned->msgId);
|
||||||
|
if (pinned->msg) {
|
||||||
|
App::historyRegDependency(this, pinned->msg);
|
||||||
|
gotDependencyItem = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pinned->msg) {
|
||||||
|
updatePinnedText();
|
||||||
|
} else if (force) {
|
||||||
|
if (pinned->msgId > 0) {
|
||||||
|
pinned->msgId = 0;
|
||||||
|
gotDependencyItem = true;
|
||||||
|
}
|
||||||
|
updatePinnedText();
|
||||||
|
}
|
||||||
|
if (force) {
|
||||||
|
initDimensions();
|
||||||
|
Notify::historyItemResized(this);
|
||||||
|
if (gotDependencyItem && App::wnd()) {
|
||||||
|
App::wnd()->notifySettingGot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (pinned->msg || !pinned->msgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryServiceMsg::updatePinnedText(const QString *pfrom, QString *ptext) {
|
||||||
|
bool result = false;
|
||||||
|
QString from, text;
|
||||||
|
if (pfrom) {
|
||||||
|
from = *pfrom;
|
||||||
|
} else {
|
||||||
|
from = textcmdLink(1, _from->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextLinkPtr second;
|
||||||
|
HistoryServicePinned *pinned = Get<HistoryServicePinned>();
|
||||||
|
if (pinned && pinned->msg) {
|
||||||
|
HistoryMedia *media = pinned->msg->getMedia();
|
||||||
|
QString mediaText;
|
||||||
|
switch (media ? media->type() : MediaTypeCount) {
|
||||||
|
case MediaTypePhoto: mediaText = lang(lng_action_pinned_media_photo); break;
|
||||||
|
case MediaTypeVideo: mediaText = lang(lng_action_pinned_media_video); break;
|
||||||
|
case MediaTypeContact: mediaText = lang(lng_action_pinned_media_contact); break;
|
||||||
|
case MediaTypeFile: mediaText = lang(lng_action_pinned_media_file); break;
|
||||||
|
case MediaTypeGif: mediaText = lang(lng_action_pinned_media_gif); break;
|
||||||
|
case MediaTypeSticker: mediaText = lang(lng_action_pinned_media_sticker); break;
|
||||||
|
case MediaTypeLocation: mediaText = lang(lng_action_pinned_media_location); break;
|
||||||
|
case MediaTypeMusicFile: mediaText = lang(lng_action_pinned_media_audio); break;
|
||||||
|
case MediaTypeVoiceFile: mediaText = lang(lng_action_pinned_media_voice); break;
|
||||||
|
}
|
||||||
|
if (mediaText.isEmpty()) {
|
||||||
|
QString original = pinned->msg->originalText();
|
||||||
|
int32 cutat = 0, limit = PinnedMessageTextLimit, size = original.size();
|
||||||
|
for (; limit > 0;) {
|
||||||
|
--limit;
|
||||||
|
if (cutat >= size) break;
|
||||||
|
if (original.at(cutat).isLowSurrogate() && cutat + 1 < size && original.at(cutat + 1).isHighSurrogate()) {
|
||||||
|
cutat += 2;
|
||||||
|
} else {
|
||||||
|
++cutat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!limit && cutat + 5 < size) {
|
||||||
|
original = original.mid(0, cutat) + qstr("..");
|
||||||
|
}
|
||||||
|
text = lng_action_pinned_message(lt_from, from, lt_text, textcmdLink(2, original));
|
||||||
|
} else {
|
||||||
|
text = lng_action_pinned_media(lt_from, from, lt_media, textcmdLink(2, mediaText));
|
||||||
|
}
|
||||||
|
second = pinned->lnk;
|
||||||
|
result = true;
|
||||||
|
} else if (pinned && pinned->msgId) {
|
||||||
|
text = lng_action_pinned_media(lt_from, from, lt_media, textcmdLink(2, lang(lng_contacts_loading)));
|
||||||
|
second = pinned->lnk;
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
text = lng_action_pinned_media(lt_from, from, lt_media, lang(lng_deleted_message));
|
||||||
|
}
|
||||||
|
if (ptext) {
|
||||||
|
*ptext = text;
|
||||||
|
} else {
|
||||||
|
setServiceText(text);
|
||||||
|
_text.setLink(1, TextLinkPtr(new PeerLink(_from)));
|
||||||
|
if (second) {
|
||||||
|
_text.setLink(2, second);
|
||||||
|
}
|
||||||
|
if (history()->textCachedFor == this) {
|
||||||
|
history()->textCachedFor = 0;
|
||||||
|
}
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->dlgUpdated(history(), id);
|
||||||
|
}
|
||||||
|
App::historyUpdateDependent(this);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg) :
|
HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg) :
|
||||||
HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
|
HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
|
||||||
, _text(st::msgMinWidth)
|
, _text(st::msgMinWidth)
|
||||||
, _media(0)
|
, _media(0) {
|
||||||
{
|
if (msg.has_reply_to_msg_id()) {
|
||||||
|
UpdateInterfaces(HistoryServicePinned::Bit());
|
||||||
|
MsgId pinnedMsgId = Get<HistoryServicePinned>()->msgId = msg.vreply_to_msg_id.v;
|
||||||
|
if (!updatePinned() && App::api()) {
|
||||||
|
App::api()->requestMessageData(history->peer->asChannel(), pinnedMsgId, new HistoryDependentItemCallback(fullId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
setMessageByAction(msg.vaction);
|
setMessageByAction(msg.vaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags, HistoryMedia *media, int32 from) :
|
HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags, HistoryMedia *media, int32 from) :
|
||||||
HistoryItem(history, block, msgId, flags, date, from)
|
HistoryItem(history, block, msgId, flags, date, from)
|
||||||
, _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth)
|
, _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth)
|
||||||
, _media(media)
|
, _media(media) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryServiceMsg::initDimensions() {
|
void HistoryServiceMsg::initDimensions() {
|
||||||
|
@ -7701,7 +7854,12 @@ HistoryMedia *HistoryServiceMsg::getMedia(bool inOverview) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryServiceMsg::~HistoryServiceMsg() {
|
HistoryServiceMsg::~HistoryServiceMsg() {
|
||||||
delete _media;
|
if (auto pinned = Get<HistoryServicePinned>()) {
|
||||||
|
if (pinned->msg) {
|
||||||
|
App::historyUnregDependency(this, pinned->msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deleteAndMark(_media);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryDateMsg::HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date) :
|
HistoryDateMsg::HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date) :
|
||||||
|
|
|
@ -115,7 +115,6 @@ struct FakeDialogRow {
|
||||||
enum HistoryMediaType {
|
enum HistoryMediaType {
|
||||||
MediaTypePhoto,
|
MediaTypePhoto,
|
||||||
MediaTypeVideo,
|
MediaTypeVideo,
|
||||||
MediaTypeGeo,
|
|
||||||
MediaTypeContact,
|
MediaTypeContact,
|
||||||
MediaTypeFile,
|
MediaTypeFile,
|
||||||
MediaTypeGif,
|
MediaTypeGif,
|
||||||
|
@ -909,6 +908,17 @@ struct HistoryMessageForwarded : public BasicInterface<HistoryMessageForwarded>
|
||||||
mutable Text _text;
|
mutable Text _text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HistoryDependentItemCallback : public SharedCallback2<void, ChannelData*, MsgId> {
|
||||||
|
public:
|
||||||
|
HistoryDependentItemCallback(FullMsgId dependent) : _dependent(dependent) {
|
||||||
|
}
|
||||||
|
void call(ChannelData *channel, MsgId msgId) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FullMsgId _dependent;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class HistoryMedia;
|
class HistoryMedia;
|
||||||
class HistoryItem : public HistoryElem, public Interfaces {
|
class HistoryItem : public HistoryElem, public Interfaces {
|
||||||
public:
|
public:
|
||||||
|
@ -919,6 +929,18 @@ public:
|
||||||
virtual int32 resize(int32 width) = 0; // return new height
|
virtual int32 resize(int32 width) = 0; // return new height
|
||||||
virtual void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const = 0;
|
virtual void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const = 0;
|
||||||
|
|
||||||
|
virtual void dependencyItemRemoved(HistoryItem *dependency) {
|
||||||
|
}
|
||||||
|
virtual bool updateDependencyItem() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual MsgId dependencyMsgId() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual bool notificationReady() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual UserData *viaBot() const {
|
virtual UserData *viaBot() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1068,9 +1090,20 @@ public:
|
||||||
return (channel->amEditor() || channel->amModerator() || out());
|
return (channel->amEditor() || channel->amModerator() || out());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canPin() const {
|
||||||
|
return id > 0 && _history->peer->isMegagroup() && (_history->peer->asChannel()->amEditor() || _history->peer->asChannel()->amCreator()) && toHistoryMessage();
|
||||||
|
}
|
||||||
|
|
||||||
bool canEdit(const QDateTime &cur) const;
|
bool canEdit(const QDateTime &cur) const;
|
||||||
|
|
||||||
|
bool suggestBanReportDeleteAll() const {
|
||||||
|
auto channel = history()->peer->asChannel();
|
||||||
|
if (!channel || (!channel->amEditor() && !channel->amCreator())) return false;
|
||||||
|
return !isPost() && !out() && from()->isUser() && toHistoryMessage();
|
||||||
|
}
|
||||||
|
|
||||||
bool hasDirectLink() const {
|
bool hasDirectLink() const {
|
||||||
return id > 0 && _history->peer->isChannel() && _history->peer->asChannel()->isPublic();
|
return id > 0 && _history->peer->isChannel() && _history->peer->asChannel()->isPublic() && !_history->peer->isMegagroup();
|
||||||
}
|
}
|
||||||
QString directLink() const {
|
QString directLink() const {
|
||||||
return hasDirectLink() ? qsl("https://telegram.me/") + _history->peer->asChannel()->username + '/' + QString::number(id) : QString();
|
return hasDirectLink() ? qsl("https://telegram.me/") + _history->peer->asChannel()->username + '/' + QString::number(id) : QString();
|
||||||
|
@ -1494,7 +1527,7 @@ private:
|
||||||
class HistoryVideo : public HistoryFileMedia {
|
class HistoryVideo : public HistoryFileMedia {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryVideo(DocumentData *document, const QString &caption, HistoryItem *parent);
|
HistoryVideo(DocumentData *document, const QString &caption, const HistoryItem *parent);
|
||||||
HistoryVideo(const HistoryVideo &other);
|
HistoryVideo(const HistoryVideo &other);
|
||||||
HistoryMediaType type() const {
|
HistoryMediaType type() const {
|
||||||
return MediaTypeVideo;
|
return MediaTypeVideo;
|
||||||
|
@ -1528,6 +1561,9 @@ public:
|
||||||
}
|
}
|
||||||
ImagePtr replyPreview();
|
ImagePtr replyPreview();
|
||||||
|
|
||||||
|
QString getCaption() const {
|
||||||
|
return _caption.original();
|
||||||
|
}
|
||||||
bool needsBubble(const HistoryItem *parent) const {
|
bool needsBubble(const HistoryItem *parent) const {
|
||||||
return !_caption.isEmpty() || parent->Is<HistoryMessageForwarded>() || parent->toHistoryReply() || parent->viaBot();
|
return !_caption.isEmpty() || parent->Is<HistoryMessageForwarded>() || parent->toHistoryReply() || parent->viaBot();
|
||||||
}
|
}
|
||||||
|
@ -2227,37 +2263,41 @@ public:
|
||||||
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
|
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
|
||||||
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
|
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
|
||||||
|
|
||||||
void initDimensions();
|
void initDimensions() override;
|
||||||
|
|
||||||
bool updateReplyTo(bool force = false);
|
bool updateDependencyItem() override {
|
||||||
void replyToNameUpdated() const;
|
return updateReplyTo(true);
|
||||||
|
}
|
||||||
|
MsgId dependencyMsgId() const override {
|
||||||
|
return replyToId();
|
||||||
|
}
|
||||||
int32 replyToWidth() const;
|
int32 replyToWidth() const;
|
||||||
|
|
||||||
TextLinkPtr replyToLink() const;
|
TextLinkPtr replyToLink() const;
|
||||||
|
|
||||||
MsgId replyToId() const;
|
MsgId replyToId() const;
|
||||||
HistoryItem *replyToMessage() const;
|
HistoryItem *replyToMessage() const;
|
||||||
void replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
void dependencyItemRemoved(HistoryItem *dependency) override;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
|
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
|
||||||
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
||||||
void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
void drawMessageText(Painter &p, QRect trect, uint32 selection) const override;
|
||||||
int32 resize(int32 width);
|
int32 resize(int32 width) override;
|
||||||
void resizeVia(int32 w) const;
|
void resizeVia(int32 w) const;
|
||||||
bool hasPoint(int32 x, int32 y) const;
|
bool hasPoint(int32 x, int32 y) const override;
|
||||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override;
|
||||||
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const override;
|
||||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override;
|
||||||
|
|
||||||
PeerData *replyTo() const {
|
PeerData *replyTo() const {
|
||||||
return replyToMsg ? replyToMsg->author() : 0;
|
return replyToMsg ? replyToMsg->author() : 0;
|
||||||
}
|
}
|
||||||
QString selectedText(uint32 selection) const;
|
QString selectedText(uint32 selection) const override;
|
||||||
|
|
||||||
HistoryReply *toHistoryReply() { // dynamic_cast optimize
|
HistoryReply *toHistoryReply() override { // dynamic_cast optimize
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
const HistoryReply *toHistoryReply() const { // dynamic_cast optimize
|
const HistoryReply *toHistoryReply() const override { // dynamic_cast optimize
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2265,6 +2305,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
bool updateReplyTo(bool force = false);
|
||||||
|
void replyToNameUpdated() const;
|
||||||
|
|
||||||
MsgId replyToMsgId;
|
MsgId replyToMsgId;
|
||||||
HistoryItem *replyToMsg;
|
HistoryItem *replyToMsg;
|
||||||
TextLinkPtr replyToLnk;
|
TextLinkPtr replyToLnk;
|
||||||
|
@ -2296,46 +2339,70 @@ inline int32 newForwardedFlags(PeerData *p, int32 from, HistoryMessage *fwd) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HistoryServicePinned : public BasicInterface<HistoryServicePinned> {
|
||||||
|
HistoryServicePinned(Interfaces *);
|
||||||
|
|
||||||
|
MsgId msgId;
|
||||||
|
HistoryItem *msg;
|
||||||
|
TextLinkPtr lnk;
|
||||||
|
};
|
||||||
|
|
||||||
class HistoryServiceMsg : public HistoryItem {
|
class HistoryServiceMsg : public HistoryItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
|
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
|
||||||
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0);
|
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0, int32 from = 0);
|
||||||
|
|
||||||
void initDimensions();
|
void initDimensions() override;
|
||||||
|
|
||||||
|
bool updateDependencyItem() override {
|
||||||
|
return updatePinned(true);
|
||||||
|
}
|
||||||
|
MsgId dependencyMsgId() const override {
|
||||||
|
if (const HistoryServicePinned *pinned = Get<HistoryServicePinned>()) {
|
||||||
|
return pinned->msgId;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool notificationReady() const override {
|
||||||
|
if (const HistoryServicePinned *pinned = Get<HistoryServicePinned>()) {
|
||||||
|
return (pinned->msg || !pinned->msgId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void countPositionAndSize(int32 &left, int32 &width) const;
|
void countPositionAndSize(int32 &left, int32 &width) const;
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
|
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const override;
|
||||||
int32 resize(int32 width);
|
int32 resize(int32 width) override;
|
||||||
bool hasPoint(int32 x, int32 y) const;
|
bool hasPoint(int32 x, int32 y) const override;
|
||||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const override;
|
||||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const override;
|
||||||
uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const {
|
uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const override {
|
||||||
return _text.adjustSelection(from, to, type);
|
return _text.adjustSelection(from, to, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void linkOver(const TextLinkPtr &lnk) {
|
void linkOver(const TextLinkPtr &lnk) override {
|
||||||
if (_media) _media->linkOver(this, lnk);
|
if (_media) _media->linkOver(this, lnk);
|
||||||
}
|
}
|
||||||
void linkOut(const TextLinkPtr &lnk) {
|
void linkOut(const TextLinkPtr &lnk) override {
|
||||||
if (_media) _media->linkOut(this, lnk);
|
if (_media) _media->linkOut(this, lnk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const;
|
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const override;
|
||||||
QString notificationText() const;
|
QString notificationText() const override;
|
||||||
|
|
||||||
bool needCheck() const {
|
bool needCheck() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool serviceMsg() const {
|
bool serviceMsg() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
QString selectedText(uint32 selection) const;
|
QString selectedText(uint32 selection) const override;
|
||||||
QString inDialogsText() const;
|
QString inDialogsText() const override;
|
||||||
QString inReplyText() const;
|
QString inReplyText() const override;
|
||||||
|
|
||||||
HistoryMedia *getMedia(bool inOverview = false) const;
|
HistoryMedia *getMedia(bool inOverview = false) const override;
|
||||||
|
|
||||||
void setServiceText(const QString &text);
|
void setServiceText(const QString &text);
|
||||||
|
|
||||||
|
@ -2344,6 +2411,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void setMessageByAction(const MTPmessageAction &action);
|
void setMessageByAction(const MTPmessageAction &action);
|
||||||
|
bool updatePinned(bool force = false);
|
||||||
|
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
|
||||||
|
|
||||||
Text _text;
|
Text _text;
|
||||||
HistoryMedia *_media;
|
HistoryMedia *_media;
|
||||||
|
|
|
@ -877,6 +877,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (item->canEdit(::date(unixtime()))) {
|
if (item->canEdit(::date(unixtime()))) {
|
||||||
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
||||||
}
|
}
|
||||||
|
if (item->canPin()) {
|
||||||
|
bool ispinned = (item->history()->peer->asChannel()->mgInfo->pinnedMsgId == item->id);
|
||||||
|
_menu->addAction(lang(ispinned ? lng_context_unpin_msg : lng_context_pin_msg), _widget, ispinned ? SLOT(onUnpinMessage()) : SLOT(onPinMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lnkPhoto) {
|
if (lnkPhoto) {
|
||||||
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
||||||
|
@ -933,6 +937,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (item->canEdit(::date(unixtime()))) {
|
if (item->canEdit(::date(unixtime()))) {
|
||||||
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
||||||
}
|
}
|
||||||
|
if (item->canPin()) {
|
||||||
|
bool ispinned = (item->history()->peer->asChannel()->mgInfo->pinnedMsgId == item->id);
|
||||||
|
_menu->addAction(lang(ispinned ? lng_context_unpin_msg : lng_context_pin_msg), _widget, ispinned ? SLOT(onUnpinMessage()) : SLOT(onPinMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (item && item->id > 0 && isUponSelected != -2) {
|
if (item && item->id > 0 && isUponSelected != -2) {
|
||||||
|
@ -942,6 +950,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (item->canEdit(::date(unixtime()))) {
|
if (item->canEdit(::date(unixtime()))) {
|
||||||
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
_menu->addAction(lang(lng_context_edit_msg), _widget, SLOT(onEditMessage()));
|
||||||
}
|
}
|
||||||
|
if (item->canPin()) {
|
||||||
|
bool ispinned = (item->history()->peer->asChannel()->mgInfo->pinnedMsgId == item->id);
|
||||||
|
_menu->addAction(lang(ispinned ? lng_context_unpin_msg : lng_context_pin_msg), _widget, ispinned ? SLOT(onUnpinMessage()) : SLOT(onPinMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item && !isUponSelected && !_contextMenuLnk) {
|
if (item && !isUponSelected && !_contextMenuLnk) {
|
||||||
if (HistoryMedia *media = (msg ? msg->getMedia() : 0)) {
|
if (HistoryMedia *media = (msg ? msg->getMedia() : 0)) {
|
||||||
|
@ -2632,8 +2644,10 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _editMsgId(0)
|
, _editMsgId(0)
|
||||||
, _replyEditMsg(0)
|
, _replyEditMsg(0)
|
||||||
, _fieldBarCancel(this, st::replyCancel)
|
, _fieldBarCancel(this, st::replyCancel)
|
||||||
|
, _pinnedBar(0)
|
||||||
, _saveEditMsgRequestId(0)
|
, _saveEditMsgRequestId(0)
|
||||||
, _reportSpamStatus(dbiprsUnknown)
|
, _reportSpamStatus(dbiprsUnknown)
|
||||||
|
, _reportSpamSettingRequestId(ReportSpamRequestNeeded)
|
||||||
, _previewData(0)
|
, _previewData(0)
|
||||||
, _previewRequest(0)
|
, _previewRequest(0)
|
||||||
, _previewCancelled(false)
|
, _previewCancelled(false)
|
||||||
|
@ -2687,6 +2701,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _inRecord(false)
|
, _inRecord(false)
|
||||||
, _inField(false)
|
, _inField(false)
|
||||||
, _inReplyEdit(false)
|
, _inReplyEdit(false)
|
||||||
|
, _inPinnedMsg(false)
|
||||||
, a_recordingLevel(0, 0)
|
, a_recordingLevel(0, 0)
|
||||||
, _recordingSamples(0)
|
, _recordingSamples(0)
|
||||||
, a_recordOver(0, 0)
|
, a_recordOver(0, 0)
|
||||||
|
@ -2777,7 +2792,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
_fieldBarCancel.hide();
|
_fieldBarCancel.hide();
|
||||||
|
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
_scroll.move(0, 0);
|
|
||||||
_collapseComments.setParent(&_scroll);
|
_collapseComments.setParent(&_scroll);
|
||||||
|
|
||||||
_kbScroll.setFocusPolicy(Qt::NoFocus);
|
_kbScroll.setFocusPolicy(Qt::NoFocus);
|
||||||
|
@ -3500,7 +3514,7 @@ void HistoryWidget::applyDraft(bool parseLinks) {
|
||||||
if (_editMsgId || _replyToId) {
|
if (_editMsgId || _replyToId) {
|
||||||
updateReplyEditTexts();
|
updateReplyEditTexts();
|
||||||
if (!_replyEditMsg && App::api()) {
|
if (!_replyEditMsg && App::api()) {
|
||||||
App::api()->requestReplyTo(0, _peer->asChannel(), _editMsgId ? _editMsgId : _replyToId);
|
App::api()->requestMessageData(_peer->asChannel(), _editMsgId ? _editMsgId : _replyToId, new ReplyEditMessageDataCallback());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3591,6 +3605,11 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
if (_migrated && _migrated->unreadBar) {
|
if (_migrated && _migrated->unreadBar) {
|
||||||
_migrated->unreadBar->destroy();
|
_migrated->unreadBar->destroy();
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar) {
|
||||||
|
delete _pinnedBar;
|
||||||
|
_pinnedBar = nullptr;
|
||||||
|
_inPinnedMsg = false;
|
||||||
|
}
|
||||||
_history = _migrated = 0;
|
_history = _migrated = 0;
|
||||||
updateBotKeyboard();
|
updateBotKeyboard();
|
||||||
}
|
}
|
||||||
|
@ -3626,6 +3645,10 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
}
|
}
|
||||||
|
|
||||||
_unblockRequest = _reportSpamRequest = 0;
|
_unblockRequest = _reportSpamRequest = 0;
|
||||||
|
if (_reportSpamSettingRequestId > 0) {
|
||||||
|
MTP::cancel(_reportSpamSettingRequestId);
|
||||||
|
}
|
||||||
|
_reportSpamSettingRequestId = ReportSpamRequestNeeded;
|
||||||
|
|
||||||
_titlePeerText = QString();
|
_titlePeerText = QString();
|
||||||
_titlePeerTextWidth = 0;
|
_titlePeerTextWidth = 0;
|
||||||
|
@ -3672,6 +3695,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
|
|
||||||
_updateHistoryItems.stop();
|
_updateHistoryItems.stop();
|
||||||
|
|
||||||
|
pinnedMsgVisibilityUpdated();
|
||||||
if (_history->lastWidth || _history->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
|
if (_history->lastWidth || _history->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
|
||||||
_fixedInScrollMsgId = 0;
|
_fixedInScrollMsgId = 0;
|
||||||
_fixedInScrollMsgTop = 0;
|
_fixedInScrollMsgTop = 0;
|
||||||
|
@ -3681,7 +3705,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
doneShow();
|
doneShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
App::main()->peerUpdated(_peer);
|
emit App::main()->peerUpdated(_peer);
|
||||||
|
|
||||||
Local::readDraftsWithCursors(_history);
|
Local::readDraftsWithCursors(_history);
|
||||||
if (_migrated) {
|
if (_migrated) {
|
||||||
|
@ -3770,96 +3794,101 @@ bool HistoryWidget::contentOverlapped(const QRect &globalRect) {
|
||||||
|
|
||||||
void HistoryWidget::updateReportSpamStatus() {
|
void HistoryWidget::updateReportSpamStatus() {
|
||||||
if (!_peer || (_peer->isUser() && (peerToUser(_peer->id) == MTP::authedId() || isNotificationsUser(_peer->id) || isServiceUser(_peer->id) || _peer->asUser()->botInfo))) {
|
if (!_peer || (_peer->isUser() && (peerToUser(_peer->id) == MTP::authedId() || isNotificationsUser(_peer->id) || isServiceUser(_peer->id) || _peer->asUser()->botInfo))) {
|
||||||
|
_reportSpamStatus = dbiprsHidden;
|
||||||
|
return;
|
||||||
|
} else if (!_firstLoadRequest && _history->isEmpty()) {
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
_reportSpamStatus = dbiprsNoButton;
|
||||||
|
if (cReportSpamStatuses().contains(_peer->id)) {
|
||||||
|
cRefReportSpamStatuses().remove(_peer->id);
|
||||||
|
Local::writeReportSpamStatuses();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
ReportSpamStatuses::const_iterator i = cReportSpamStatuses().constFind(_peer->id);
|
ReportSpamStatuses::const_iterator i = cReportSpamStatuses().constFind(_peer->id);
|
||||||
if (i != cReportSpamStatuses().cend()) {
|
if (i != cReportSpamStatuses().cend()) {
|
||||||
_reportSpamStatus = i.value();
|
_reportSpamStatus = i.value();
|
||||||
|
if (_reportSpamStatus == dbiprsNoButton) {
|
||||||
|
_reportSpamStatus = dbiprsHidden;
|
||||||
|
if (!_peer->isUser() || _peer->asUser()->contact < 1) {
|
||||||
|
MTP::send(MTPmessages_HideReportSpam(_peer->input));
|
||||||
|
}
|
||||||
|
|
||||||
|
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
||||||
|
Local::writeReportSpamStatuses();
|
||||||
|
} else if (_reportSpamStatus == dbiprsShowButton) {
|
||||||
|
requestReportSpamSetting();
|
||||||
|
}
|
||||||
_reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent, _peer);
|
_reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent, _peer);
|
||||||
return;
|
return;
|
||||||
} else if (_peer->migrateFrom()) { // migrate report status
|
} else if (_peer->migrateFrom()) { // migrate report status
|
||||||
i = cReportSpamStatuses().constFind(_peer->migrateFrom()->id);
|
i = cReportSpamStatuses().constFind(_peer->migrateFrom()->id);
|
||||||
if (i != cReportSpamStatuses().cend()) {
|
if (i != cReportSpamStatuses().cend()) {
|
||||||
_reportSpamStatus = i.value();
|
_reportSpamStatus = i.value();
|
||||||
_reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent, _peer);
|
if (_reportSpamStatus == dbiprsNoButton) {
|
||||||
|
_reportSpamStatus = dbiprsHidden;
|
||||||
|
if (!_peer->isUser() || _peer->asUser()->contact < 1) {
|
||||||
|
MTP::send(MTPmessages_HideReportSpam(_peer->input));
|
||||||
|
}
|
||||||
|
} else if (_reportSpamStatus == dbiprsShowButton) {
|
||||||
|
requestReportSpamSetting();
|
||||||
|
}
|
||||||
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
||||||
Local::writeReportSpamStatuses();
|
Local::writeReportSpamStatuses();
|
||||||
|
|
||||||
|
_reportSpamPanel.setReported(_reportSpamStatus == dbiprsReportSent, _peer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cContactsReceived() || _firstLoadRequest) {
|
if (!cContactsReceived() || _firstLoadRequest) {
|
||||||
_reportSpamStatus = dbiprsUnknown;
|
_reportSpamStatus = dbiprsUnknown;
|
||||||
} else if (!_history->loadedAtTop() && (_history->blocks.size() < 2 || (_history->blocks.size() == 2 && _history->blocks.at(1)->items.size() < 2))) {
|
} else if (_peer->isUser() && _peer->asUser()->contact > 0) {
|
||||||
_reportSpamStatus = dbiprsUnknown;
|
_reportSpamStatus = dbiprsHidden;
|
||||||
} else if (_peer->isUser()) {
|
} else {
|
||||||
if (_peer->asUser()->contact > 0) {
|
_reportSpamStatus = dbiprsRequesting;
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
requestReportSpamSetting();
|
||||||
} else {
|
|
||||||
bool anyFound = false, outFound = false;
|
|
||||||
for (int32 i = 0, l = _history->blocks.size(); i < l; ++i) {
|
|
||||||
for (int32 j = 0, c = _history->blocks.at(i)->items.size(); j < c; ++j) {
|
|
||||||
anyFound = true;
|
|
||||||
if (_history->blocks.at(i)->items.at(j)->out()) {
|
|
||||||
outFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (anyFound) {
|
|
||||||
if (outFound) {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsShowButton;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsUnknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_peer->isChat()) {
|
|
||||||
if (_peer->asChat()->inviterForSpamReport > 0) {
|
|
||||||
UserData *user = App::userLoaded(_peer->asChat()->inviterForSpamReport);
|
|
||||||
if (user && user->contact > 0) {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsShowButton;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
}
|
|
||||||
} else if (_peer->isChannel()) {
|
|
||||||
if (_peer->migrateFrom() && _peer->migrateFrom()->isChat()) {
|
|
||||||
if (_peer->migrateFrom()->asChat()->inviterForSpamReport > 0) {
|
|
||||||
UserData *user = App::userLoaded(_peer->migrateFrom()->asChat()->inviterForSpamReport);
|
|
||||||
if (user && user->contact > 0) {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsShowButton;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
}
|
|
||||||
} else if (!_peer->asChannel()->inviter || _history->asChannelHistory()->maxReadMessageDate().isNull()) {
|
|
||||||
_reportSpamStatus = dbiprsUnknown;
|
|
||||||
} else if (_peer->asChannel()->inviter > 0) {
|
|
||||||
UserData *user = App::userLoaded(_peer->asChannel()->inviter);
|
|
||||||
if ((user && user->contact > 0) || (_peer->asChannel()->inviter == MTP::authedId()) || _history->asChannelHistory()->maxReadMessageDate() > _peer->asChannel()->inviteDate) {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsShowButton;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsNoButton) {
|
if (_reportSpamStatus == dbiprsHidden) {
|
||||||
_reportSpamPanel.setReported(false, _peer);
|
_reportSpamPanel.setReported(false, _peer);
|
||||||
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
||||||
Local::writeReportSpamStatuses();
|
Local::writeReportSpamStatuses();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::requestReportSpamSetting() {
|
||||||
|
if (_reportSpamSettingRequestId >= 0 || !_peer) return;
|
||||||
|
|
||||||
|
_reportSpamSettingRequestId = MTP::send(MTPmessages_GetPeerSettings(_peer->input), rpcDone(&HistoryWidget::reportSpamSettingDone), rpcFail(&HistoryWidget::reportSpamSettingFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::reportSpamSettingDone(const MTPPeerSettings &result, mtpRequestId req) {
|
||||||
|
if (req != _reportSpamSettingRequestId) return;
|
||||||
|
|
||||||
|
_reportSpamSettingRequestId = 0;
|
||||||
|
if (result.type() == mtpc_peerSettings) {
|
||||||
|
const MTPDpeerSettings &d(result.c_peerSettings());
|
||||||
|
DBIPeerReportSpamStatus status = d.is_report_spam() ? dbiprsShowButton : dbiprsHidden;
|
||||||
|
if (status != _reportSpamStatus) {
|
||||||
|
_reportSpamStatus = status;
|
||||||
|
_reportSpamPanel.setReported(false, _peer);
|
||||||
|
|
||||||
|
cRefReportSpamStatuses().insert(_peer->id, _reportSpamStatus);
|
||||||
|
Local::writeReportSpamStatuses();
|
||||||
|
|
||||||
|
updateControlsVisibility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryWidget::reportSpamSettingFail(const RPCError &error, mtpRequestId req) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
|
||||||
|
if (req == _reportSpamSettingRequestId) {
|
||||||
|
req = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateControlsVisibility() {
|
void HistoryWidget::updateControlsVisibility() {
|
||||||
_topShadow.setVisible(_peer ? true : false);
|
_topShadow.setVisible(_peer ? true : false);
|
||||||
if (!_history || _a_show.animating()) {
|
if (!_history || _a_show.animating()) {
|
||||||
|
@ -3886,10 +3915,18 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_cmdStart.hide();
|
_cmdStart.hide();
|
||||||
_attachType.hide();
|
_attachType.hide();
|
||||||
_emojiPan.hide();
|
_emojiPan.hide();
|
||||||
|
if (_pinnedBar) {
|
||||||
|
_pinnedBar->cancel.hide();
|
||||||
|
_pinnedBar->shadow.hide();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateToEndVisibility();
|
updateToEndVisibility();
|
||||||
|
if (_pinnedBar) {
|
||||||
|
_pinnedBar->cancel.show();
|
||||||
|
_pinnedBar->shadow.show();
|
||||||
|
}
|
||||||
if (_firstLoadRequest) {
|
if (_firstLoadRequest) {
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4091,7 +4128,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateMouseTracking() {
|
void HistoryWidget::updateMouseTracking() {
|
||||||
bool trackMouse = !_fieldBarCancel.isHidden() || (cHasAudioCapture() && _send.isHidden() && !_field.isHidden());
|
bool trackMouse = !_fieldBarCancel.isHidden() || _pinnedBar || (cHasAudioCapture() && _send.isHidden() && !_field.isHidden());
|
||||||
setMouseTracking(trackMouse);
|
setMouseTracking(trackMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4139,7 +4176,7 @@ void HistoryWidget::historyCleared(History *history) {
|
||||||
bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId) {
|
bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId) {
|
||||||
if (mtpIsFlood(error)) return false;
|
if (mtpIsFlood(error)) return false;
|
||||||
|
|
||||||
if (error.type() == qstr("CHANNEL_PRIVATE")) {
|
if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||||
PeerData *was = _peer;
|
PeerData *was = _peer;
|
||||||
Ui::showChatsList();
|
Ui::showChatsList();
|
||||||
Ui::showLayer(new InformBox(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
Ui::showLayer(new InformBox(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
||||||
|
@ -4735,7 +4772,7 @@ bool HistoryWidget::joinFail(const RPCError &error, mtpRequestId req) {
|
||||||
if (mtpIsFlood(error)) return false;
|
if (mtpIsFlood(error)) return false;
|
||||||
|
|
||||||
if (_unblockRequest == req) _unblockRequest = 0;
|
if (_unblockRequest == req) _unblockRequest = 0;
|
||||||
if (error.type() == qstr("CHANNEL_PRIVATE")) {
|
if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||||
Ui::showLayer(new InformBox(lang((_peer && _peer->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
Ui::showLayer(new InformBox(lang((_peer && _peer->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4874,6 +4911,10 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
|
||||||
_joinChannel.hide();
|
_joinChannel.hide();
|
||||||
_muteUnmute.hide();
|
_muteUnmute.hide();
|
||||||
_topShadow.hide();
|
_topShadow.hide();
|
||||||
|
if (_pinnedBar) {
|
||||||
|
_pinnedBar->shadow.hide();
|
||||||
|
_pinnedBar->cancel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
|
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
|
||||||
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
|
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
|
||||||
|
@ -5056,6 +5097,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
bool inRecord = _send.geometry().contains(pos);
|
bool inRecord = _send.geometry().contains(pos);
|
||||||
bool inField = pos.y() >= (_scroll.y() + _scroll.height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
|
bool inField = pos.y() >= (_scroll.y() + _scroll.height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
|
||||||
bool inReplyEdit = QRect(st::replySkip, _field.y() - st::sendPadding - st::replyHeight, width() - st::replySkip - _fieldBarCancel.width(), st::replyHeight).contains(pos) && (_editMsgId || replyToId());
|
bool inReplyEdit = QRect(st::replySkip, _field.y() - st::sendPadding - st::replyHeight, width() - st::replySkip - _fieldBarCancel.width(), st::replyHeight).contains(pos) && (_editMsgId || replyToId());
|
||||||
|
bool inPinnedMsg = QRect(0, 0, width(), st::replyHeight).contains(pos) && _pinnedBar;
|
||||||
bool startAnim = false;
|
bool startAnim = false;
|
||||||
if (inRecord != _inRecord) {
|
if (inRecord != _inRecord) {
|
||||||
_inRecord = inRecord;
|
_inRecord = inRecord;
|
||||||
|
@ -5075,6 +5117,10 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
_inReplyEdit = inReplyEdit;
|
_inReplyEdit = inReplyEdit;
|
||||||
setCursor(inReplyEdit ? style::cur_pointer : style::cur_default);
|
setCursor(inReplyEdit ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
|
if (inPinnedMsg != _inPinnedMsg) {
|
||||||
|
_inPinnedMsg = inPinnedMsg;
|
||||||
|
setCursor(inPinnedMsg ? style::cur_pointer : style::cur_default);
|
||||||
|
}
|
||||||
if (startAnim) _a_record.start();
|
if (startAnim) _a_record.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5587,7 +5633,26 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_peer->isChannel()) {
|
} else if (_peer->isChannel()) {
|
||||||
text = _peer->asChannel()->count ? lng_chat_status_members(lt_count, _peer->asChannel()->count) : lang(_peer->isMegagroup() ? lng_group_status : lng_channel_status);
|
if (_peer->isMegagroup() && _peer->asChannel()->count > 0 && _peer->asChannel()->count <= Global::ChatSizeMax()) {
|
||||||
|
if (_peer->asChannel()->mgInfo->lastParticipants.size() < _peer->asChannel()->count || _peer->asChannel()->lastParticipantsCountOutdated()) {
|
||||||
|
if (App::api()) App::api()->requestLastParticipants(_peer->asChannel());
|
||||||
|
}
|
||||||
|
int32 onlineCount = 0;
|
||||||
|
bool onlyMe = true;
|
||||||
|
for (MentionRows::const_iterator i = _peer->asChannel()->mgInfo->lastParticipants.cbegin(), e = _peer->asChannel()->mgInfo->lastParticipants.cend(); i != e; ++i) {
|
||||||
|
if ((*i)->onlineTill > t) {
|
||||||
|
++onlineCount;
|
||||||
|
if (onlyMe && (*i) != App::self()) onlyMe = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (onlineCount && !onlyMe) {
|
||||||
|
text = lng_chat_status_members_online(lt_count, _peer->asChannel()->count, lt_count_online, onlineCount);
|
||||||
|
} else {
|
||||||
|
text = lng_chat_status_members(lt_count, _peer->asChannel()->count);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text = _peer->asChannel()->count ? lng_chat_status_members(lt_count, _peer->asChannel()->count) : lang(_peer->isMegagroup() ? lng_group_status : lng_channel_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_titlePeerText != text) {
|
if (_titlePeerText != text) {
|
||||||
_titlePeerText = text;
|
_titlePeerText = text;
|
||||||
|
@ -6019,10 +6084,12 @@ bool HistoryWidget::reportSpamFail(const RPCError &error, mtpRequestId req) {
|
||||||
|
|
||||||
void HistoryWidget::onReportSpamHide() {
|
void HistoryWidget::onReportSpamHide() {
|
||||||
if (_peer) {
|
if (_peer) {
|
||||||
cRefReportSpamStatuses().insert(_peer->id, dbiprsNoButton);
|
cRefReportSpamStatuses().insert(_peer->id, dbiprsHidden);
|
||||||
Local::writeReportSpamStatuses();
|
Local::writeReportSpamStatuses();
|
||||||
|
|
||||||
|
MTP::send(MTPmessages_HideReportSpam(_peer->input));
|
||||||
}
|
}
|
||||||
_reportSpamStatus = dbiprsNoButton;
|
_reportSpamStatus = dbiprsHidden;
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6132,6 +6199,18 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
_field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding);
|
_field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding);
|
||||||
|
|
||||||
|
if (_pinnedBar) {
|
||||||
|
if (_scroll.y() != st::replyHeight) {
|
||||||
|
_scroll.move(0, st::replyHeight);
|
||||||
|
_attachMention.setBoundings(_scroll.geometry());
|
||||||
|
}
|
||||||
|
_pinnedBar->cancel.move(width() - _pinnedBar->cancel.width(), 0);
|
||||||
|
_pinnedBar->shadow.setGeometry(0, st::replyHeight, width(), st::lineWidth);
|
||||||
|
} else if (_scroll.y() != 0) {
|
||||||
|
_scroll.move(0, 0);
|
||||||
|
_attachMention.setBoundings(_scroll.geometry());
|
||||||
|
}
|
||||||
|
|
||||||
_attachDocument.move(0, height() - kbh - _attachDocument.height());
|
_attachDocument.move(0, height() - kbh - _attachDocument.height());
|
||||||
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
||||||
|
|
||||||
|
@ -6195,12 +6274,24 @@ void HistoryWidget::itemRemoved(HistoryItem *item) {
|
||||||
if (item == _replyReturn) {
|
if (item == _replyReturn) {
|
||||||
calcNextReplyReturn();
|
calcNextReplyReturn();
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
||||||
|
pinnedMsgVisibilityUpdated();
|
||||||
|
}
|
||||||
if (_kbReplyTo && item == _kbReplyTo) {
|
if (_kbReplyTo && item == _kbReplyTo) {
|
||||||
onKbToggle();
|
onKbToggle();
|
||||||
_kbReplyTo = 0;
|
_kbReplyTo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::itemEdited(HistoryItem *item) {
|
||||||
|
if (item == _replyEditMsg) {
|
||||||
|
updateReplyEditTexts(true);
|
||||||
|
}
|
||||||
|
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
||||||
|
updatePinnedBar(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateScrollColors() {
|
void HistoryWidget::updateScrollColors() {
|
||||||
if (!App::historyScrollBarColor()) return;
|
if (!App::historyScrollBarColor()) return;
|
||||||
_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
|
_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
|
||||||
|
@ -6231,6 +6322,9 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
|
||||||
newScrollHeight -= _kbScroll.height();
|
newScrollHeight -= _kbScroll.height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar) {
|
||||||
|
newScrollHeight -= st::replyHeight;
|
||||||
|
}
|
||||||
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
|
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
|
||||||
if (needResize) {
|
if (needResize) {
|
||||||
_scroll.resize(width(), newScrollHeight);
|
_scroll.resize(width(), newScrollHeight);
|
||||||
|
@ -6534,6 +6628,9 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
_a_record.start();
|
_a_record.start();
|
||||||
} else if (_inReplyEdit) {
|
} else if (_inReplyEdit) {
|
||||||
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
||||||
|
} else if (_inPinnedMsg) {
|
||||||
|
t_assert(_pinnedBar != nullptr);
|
||||||
|
Ui::showPeerHistory(_peer, _pinnedBar->msgId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6705,6 +6802,99 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
|
||||||
_field.setFocus();
|
_field.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HistoryWidget::PinnedBar::PinnedBar(MsgId msgId, HistoryWidget *parent)
|
||||||
|
: msgId(msgId)
|
||||||
|
, msg(0)
|
||||||
|
, cancel(parent, st::replyCancel)
|
||||||
|
, shadow(parent, st::shadowColor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::updatePinnedBar(bool force) {
|
||||||
|
if (!_pinnedBar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!force) {
|
||||||
|
if (_pinnedBar->msg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t_assert(_history != nullptr);
|
||||||
|
|
||||||
|
if (!_pinnedBar->msg) {
|
||||||
|
_pinnedBar->msg = App::histItemById(_history->channelId(), _pinnedBar->msgId);
|
||||||
|
}
|
||||||
|
if (_pinnedBar->msg) {
|
||||||
|
_pinnedBar->text.setText(st::msgFont, _pinnedBar->msg->inDialogsText(), _textDlgOptions);
|
||||||
|
update();
|
||||||
|
} else if (force) {
|
||||||
|
if (_peer && _peer->isMegagroup()) {
|
||||||
|
_peer->asChannel()->mgInfo->pinnedMsgId = 0;
|
||||||
|
}
|
||||||
|
delete _pinnedBar;
|
||||||
|
_pinnedBar = nullptr;
|
||||||
|
_inPinnedMsg = false;
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryWidget::pinnedMsgVisibilityUpdated() {
|
||||||
|
bool result = false;
|
||||||
|
MsgId pinnedMsgId = (_peer && _peer->isMegagroup()) ? _peer->asChannel()->mgInfo->pinnedMsgId : 0;
|
||||||
|
if (pinnedMsgId && !_peer->asChannel()->amCreator() && !_peer->asChannel()->amEditor()) {
|
||||||
|
Global::HiddenPinnedMessagesMap::const_iterator it = Global::HiddenPinnedMessages().constFind(_peer->id);
|
||||||
|
if (it != Global::HiddenPinnedMessages().cend()) {
|
||||||
|
if (it.value() == pinnedMsgId) {
|
||||||
|
pinnedMsgId = 0;
|
||||||
|
} else {
|
||||||
|
Global::RefHiddenPinnedMessages().remove(_peer->id);
|
||||||
|
Local::writeUserSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pinnedMsgId) {
|
||||||
|
if (!_pinnedBar) {
|
||||||
|
_pinnedBar = new PinnedBar(pinnedMsgId, this);
|
||||||
|
if (_a_show.animating()) {
|
||||||
|
_pinnedBar->cancel.hide();
|
||||||
|
_pinnedBar->shadow.hide();
|
||||||
|
} else {
|
||||||
|
_pinnedBar->cancel.show();
|
||||||
|
_pinnedBar->shadow.show();
|
||||||
|
}
|
||||||
|
connect(&_pinnedBar->cancel, SIGNAL(clicked()), this, SLOT(onPinnedHide()));
|
||||||
|
_reportSpamPanel.raise();
|
||||||
|
_sideShadow.raise();
|
||||||
|
_topShadow.raise();
|
||||||
|
updatePinnedBar();
|
||||||
|
result = true;
|
||||||
|
_scroll.scrollToY(_scroll.scrollTop() + st::replyHeight);
|
||||||
|
} else if (_pinnedBar->msgId != pinnedMsgId) {
|
||||||
|
_pinnedBar->msgId = pinnedMsgId;
|
||||||
|
_pinnedBar->msg = 0;
|
||||||
|
_pinnedBar->text.clean();
|
||||||
|
updatePinnedBar();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
if (!_pinnedBar->msg && App::api()) {
|
||||||
|
App::api()->requestMessageData(_peer->asChannel(), _pinnedBar->msgId, new ReplyEditMessageDataCallback());
|
||||||
|
}
|
||||||
|
} else if (_pinnedBar) {
|
||||||
|
delete _pinnedBar;
|
||||||
|
_pinnedBar = nullptr;
|
||||||
|
result = true;
|
||||||
|
_scroll.scrollToY(_scroll.scrollTop() - st::replyHeight);
|
||||||
|
resizeEvent(0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::ReplyEditMessageDataCallback::call(ChannelData *channel, MsgId msgId) const {
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->messageDataReceived(channel, msgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption) {
|
void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption) {
|
||||||
if (!_history || !doc || !canSendMessages(_peer)) return;
|
if (!_history || !doc || !canSendMessages(_peer)) return;
|
||||||
|
|
||||||
|
@ -6921,6 +7111,62 @@ void HistoryWidget::onEditMessage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onPinMessage() {
|
||||||
|
HistoryItem *to = App::contextItem();
|
||||||
|
if (!to || !to->canPin() || !_peer || !_peer->isMegagroup()) return;
|
||||||
|
|
||||||
|
Ui::showLayer(new PinMessageBox(_peer->asChannel(), to->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onUnpinMessage() {
|
||||||
|
if (!_peer || !_peer->isMegagroup()) return;
|
||||||
|
|
||||||
|
ConfirmBox *box = new ConfirmBox(lang(lng_pinned_unpin_sure), lang(lng_pinned_unpin));
|
||||||
|
connect(box, SIGNAL(confirmed()), this, SLOT(onUnpinMessageSure()));
|
||||||
|
Ui::showLayer(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onUnpinMessageSure() {
|
||||||
|
if (!_peer || !_peer->isMegagroup()) return;
|
||||||
|
|
||||||
|
_peer->asChannel()->mgInfo->pinnedMsgId = 0;
|
||||||
|
if (pinnedMsgVisibilityUpdated()) {
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::hideLayer();
|
||||||
|
MTP::send(MTPchannels_UpdatePinnedMessage(MTP_int(0), _peer->asChannel()->inputChannel, MTP_int(0)), rpcDone(&HistoryWidget::unpinDone));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::unpinDone(const MTPUpdates &updates) {
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onPinnedHide() {
|
||||||
|
if (!_peer || !_peer->isMegagroup()) return;
|
||||||
|
if (!_peer->asChannel()->mgInfo->pinnedMsgId) {
|
||||||
|
if (pinnedMsgVisibilityUpdated()) {
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_peer->asChannel()->amCreator() || _peer->asChannel()->amEditor()) {
|
||||||
|
onUnpinMessage();
|
||||||
|
} else {
|
||||||
|
Global::RefHiddenPinnedMessages().insert(_peer->id, _peer->asChannel()->mgInfo->pinnedMsgId);
|
||||||
|
Local::writeUserSettings();
|
||||||
|
if (pinnedMsgVisibilityUpdated()) {
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::onCopyPostLink() {
|
void HistoryWidget::onCopyPostLink() {
|
||||||
HistoryItem *to = App::contextItem();
|
HistoryItem *to = App::contextItem();
|
||||||
if (!to || !to->hasDirectLink()) return;
|
if (!to || !to->hasDirectLink()) return;
|
||||||
|
@ -6990,7 +7236,11 @@ void HistoryWidget::cancelEdit() {
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 old = _textUpdateEventsFlags;
|
||||||
|
_textUpdateEventsFlags = 0;
|
||||||
onTextChange();
|
onTextChange();
|
||||||
|
_textUpdateEventsFlags = old;
|
||||||
|
|
||||||
updateBotKeyboard();
|
updateBotKeyboard();
|
||||||
updateFieldPlaceholder();
|
updateFieldPlaceholder();
|
||||||
|
|
||||||
|
@ -7206,6 +7456,10 @@ void HistoryWidget::peerUpdated(PeerData *data) {
|
||||||
QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount()));
|
QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool resize = false;
|
||||||
|
if (pinnedMsgVisibilityUpdated()) {
|
||||||
|
resize = true;
|
||||||
|
}
|
||||||
updateListSize();
|
updateListSize();
|
||||||
if (_peer->isChannel()) updateReportSpamStatus();
|
if (_peer->isChannel()) updateReportSpamStatus();
|
||||||
if (App::api()) {
|
if (App::api()) {
|
||||||
|
@ -7218,7 +7472,9 @@ void HistoryWidget::peerUpdated(PeerData *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_a_show.animating()) {
|
if (!_a_show.animating()) {
|
||||||
bool resize = (_unblock.isHidden() == isBlocked() || (!isBlocked() && _joinChannel.isHidden() == isJoinChannel()));
|
if (_unblock.isHidden() == isBlocked() || (!isBlocked() && _joinChannel.isHidden() == isJoinChannel())) {
|
||||||
|
resize = true;
|
||||||
|
}
|
||||||
bool newCanSendMessages = canSendMessages(_peer);
|
bool newCanSendMessages = canSendMessages(_peer);
|
||||||
if (newCanSendMessages != _canSendMessages) {
|
if (newCanSendMessages != _canSendMessages) {
|
||||||
_canSendMessages = newCanSendMessages;
|
_canSendMessages = newCanSendMessages;
|
||||||
|
@ -7228,7 +7484,10 @@ void HistoryWidget::peerUpdated(PeerData *data) {
|
||||||
resize = true;
|
resize = true;
|
||||||
}
|
}
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
if (resize) resizeEvent(0);
|
if (resize) {
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
App::main()->updateOnlineDisplay();
|
App::main()->updateOnlineDisplay();
|
||||||
}
|
}
|
||||||
|
@ -7364,11 +7623,25 @@ void HistoryWidget::updateTopBarSelection() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateReplyEditTexts(bool force) {
|
void HistoryWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||||
if (_replyEditMsg || (!_editMsgId && !_replyToId)) {
|
if (!_peer || _peer->asChannel() != channel || !msgId) return;
|
||||||
return;
|
if (_editMsgId == msgId || _replyToId == msgId) {
|
||||||
|
updateReplyEditTexts(true);
|
||||||
|
}
|
||||||
|
if (_pinnedBar && _pinnedBar->msgId == msgId) {
|
||||||
|
updatePinnedBar(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::updateReplyEditTexts(bool force) {
|
||||||
|
if (!force) {
|
||||||
|
if (_replyEditMsg || (!_editMsgId && !_replyToId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_replyEditMsg) {
|
||||||
|
_replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId);
|
||||||
}
|
}
|
||||||
_replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId);
|
|
||||||
if (_replyEditMsg) {
|
if (_replyEditMsg) {
|
||||||
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
|
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
|
||||||
|
|
||||||
|
@ -7537,6 +7810,40 @@ void HistoryWidget::drawRecording(Painter &p) {
|
||||||
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachPhoto.y() + st::recordTextTop + st::recordFont->ascent, lang(lng_record_cancel));
|
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachPhoto.y() + st::recordTextTop + st::recordFont->ascent, lang(lng_record_cancel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||||
|
t_assert(_pinnedBar != nullptr);
|
||||||
|
|
||||||
|
Text *from = 0, *text = 0;
|
||||||
|
bool serviceColor = false, hasForward = readyToForward();
|
||||||
|
ImagePtr preview;
|
||||||
|
p.fillRect(0, 0, width(), st::replyHeight, st::taMsgField.bgColor);
|
||||||
|
|
||||||
|
QRect rbar(rtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), width()));
|
||||||
|
p.fillRect(rbar, st::msgInReplyBarColor);
|
||||||
|
|
||||||
|
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
|
if (_pinnedBar->msg) {
|
||||||
|
if (_pinnedBar->msg->getMedia() && _pinnedBar->msg->getMedia()->hasReplyPreview()) {
|
||||||
|
ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview();
|
||||||
|
if (!replyPreview->isNull()) {
|
||||||
|
QRect to(left, st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
||||||
|
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
|
||||||
|
}
|
||||||
|
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||||
|
}
|
||||||
|
p.setPen(st::replyColor);
|
||||||
|
p.setFont(st::msgServiceNameFont);
|
||||||
|
p.drawText(left, st::msgReplyPadding.top() + st::msgServiceNameFont->ascent, lang(lng_pinned_message));
|
||||||
|
|
||||||
|
p.setPen((((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::msgInDateFg : st::msgColor)->p);
|
||||||
|
_pinnedBar->text.drawElided(p, left, st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - left -_fieldBarCancel.width() - st::msgReplyPadding.right());
|
||||||
|
} else {
|
||||||
|
p.setFont(st::msgDateFont);
|
||||||
|
p.setPen(st::msgInDateFg);
|
||||||
|
p.drawText(left, st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - left - _pinnedBar->cancel.width() - st::msgReplyPadding.right()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::paintEvent(QPaintEvent *e) {
|
void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (!App::main() || (App::wnd() && App::wnd()->contentOverlapped(this, e))) return;
|
if (!App::main() || (App::wnd() && App::wnd()->contentOverlapped(this, e))) return;
|
||||||
|
|
||||||
|
@ -7596,6 +7903,9 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (_recording) drawRecording(p);
|
if (_recording) drawRecording(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar && !_pinnedBar->cancel.isHidden()) {
|
||||||
|
drawPinnedBar(p);
|
||||||
|
}
|
||||||
if (_scroll.isHidden()) {
|
if (_scroll.isHidden()) {
|
||||||
QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - _field.height() - 2 * st::sendPadding - st::msgDogImg.pxHeight()) * 4) / 9);
|
QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - _field.height() - 2 * st::sendPadding - st::msgDogImg.pxHeight()) * 4) / 9);
|
||||||
p.drawPixmap(dogPos, *cChatDogImage());
|
p.drawPixmap(dogPos, *cChatDogImage());
|
||||||
|
@ -7704,5 +8014,6 @@ bool HistoryWidget::touchScroll(const QPoint &delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryWidget::~HistoryWidget() {
|
HistoryWidget::~HistoryWidget() {
|
||||||
delete _list;
|
deleteAndMark(_pinnedBar);
|
||||||
|
deleteAndMark(_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -513,11 +513,12 @@ public:
|
||||||
|
|
||||||
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
||||||
void itemRemoved(HistoryItem *item);
|
void itemRemoved(HistoryItem *item);
|
||||||
|
void itemEdited(HistoryItem *item);
|
||||||
|
|
||||||
void updateScrollColors();
|
void updateScrollColors();
|
||||||
|
|
||||||
MsgId replyToId() const;
|
MsgId replyToId() const;
|
||||||
void updateReplyEditTexts(bool force = false);
|
void messageDataReceived(ChannelData *channel, MsgId msgId);
|
||||||
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
|
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
|
||||||
void cancelReply(bool lastKeyboardUsed = false);
|
void cancelReply(bool lastKeyboardUsed = false);
|
||||||
void cancelEdit();
|
void cancelEdit();
|
||||||
|
@ -612,6 +613,10 @@ public slots:
|
||||||
void onCancel();
|
void onCancel();
|
||||||
void onReplyToMessage();
|
void onReplyToMessage();
|
||||||
void onEditMessage();
|
void onEditMessage();
|
||||||
|
void onPinMessage();
|
||||||
|
void onUnpinMessage();
|
||||||
|
void onUnpinMessageSure();
|
||||||
|
void onPinnedHide();
|
||||||
void onCopyPostLink();
|
void onCopyPostLink();
|
||||||
void onFieldBarCancel();
|
void onFieldBarCancel();
|
||||||
|
|
||||||
|
@ -717,6 +722,26 @@ private:
|
||||||
Text _replyEditMsgText;
|
Text _replyEditMsgText;
|
||||||
|
|
||||||
IconedButton _fieldBarCancel;
|
IconedButton _fieldBarCancel;
|
||||||
|
void updateReplyEditTexts(bool force = false);
|
||||||
|
|
||||||
|
struct PinnedBar {
|
||||||
|
PinnedBar(MsgId msgId, HistoryWidget *parent);
|
||||||
|
|
||||||
|
MsgId msgId;
|
||||||
|
HistoryItem *msg;
|
||||||
|
Text text;
|
||||||
|
IconedButton cancel;
|
||||||
|
PlainShadow shadow;
|
||||||
|
};
|
||||||
|
PinnedBar *_pinnedBar;
|
||||||
|
void updatePinnedBar(bool force = false);
|
||||||
|
bool pinnedMsgVisibilityUpdated();
|
||||||
|
void unpinDone(const MTPUpdates &updates);
|
||||||
|
|
||||||
|
class ReplyEditMessageDataCallback : public SharedCallback2<void, ChannelData*, MsgId> {
|
||||||
|
public:
|
||||||
|
void call(ChannelData *channel, MsgId msgId) const override;
|
||||||
|
};
|
||||||
|
|
||||||
void sendExistingDocument(DocumentData *doc, const QString &caption);
|
void sendExistingDocument(DocumentData *doc, const QString &caption);
|
||||||
void sendExistingPhoto(PhotoData *photo, const QString &caption);
|
void sendExistingPhoto(PhotoData *photo, const QString &caption);
|
||||||
|
@ -724,6 +749,7 @@ private:
|
||||||
void drawField(Painter &p);
|
void drawField(Painter &p);
|
||||||
void drawRecordButton(Painter &p);
|
void drawRecordButton(Painter &p);
|
||||||
void drawRecording(Painter &p);
|
void drawRecording(Painter &p);
|
||||||
|
void drawPinnedBar(Painter &p);
|
||||||
|
|
||||||
void updateMouseTracking();
|
void updateMouseTracking();
|
||||||
|
|
||||||
|
@ -733,7 +759,12 @@ private:
|
||||||
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
|
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
|
||||||
|
|
||||||
DBIPeerReportSpamStatus _reportSpamStatus;
|
DBIPeerReportSpamStatus _reportSpamStatus;
|
||||||
|
mtpRequestId _reportSpamSettingRequestId;
|
||||||
|
static const mtpRequestId ReportSpamRequestNeeded = -1;
|
||||||
void updateReportSpamStatus();
|
void updateReportSpamStatus();
|
||||||
|
void requestReportSpamSetting();
|
||||||
|
void reportSpamSettingDone(const MTPPeerSettings &result, mtpRequestId req);
|
||||||
|
bool reportSpamSettingFail(const RPCError &error, mtpRequestId req);
|
||||||
|
|
||||||
QString _previewLinks;
|
QString _previewLinks;
|
||||||
WebPageData *_previewData;
|
WebPageData *_previewData;
|
||||||
|
@ -839,7 +870,7 @@ private:
|
||||||
bool _cmdStartShown;
|
bool _cmdStartShown;
|
||||||
MessageField _field;
|
MessageField _field;
|
||||||
Animation _a_record, _a_recording;
|
Animation _a_record, _a_recording;
|
||||||
bool _recording, _inRecord, _inField, _inReplyEdit;
|
bool _recording, _inRecord, _inField, _inReplyEdit, _inPinnedMsg;
|
||||||
anim::ivalue a_recordingLevel;
|
anim::ivalue a_recordingLevel;
|
||||||
int32 _recordingSamples;
|
int32 _recordingSamples;
|
||||||
anim::fvalue a_recordOver, a_recordDown;
|
anim::fvalue a_recordOver, a_recordDown;
|
||||||
|
|
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "Neuer Text..";
|
"lng_edit_message_text" = "Neuer Text..";
|
||||||
"lng_deleted" = "Gelöschter Kontakt";
|
"lng_deleted" = "Gelöschter Kontakt";
|
||||||
"lng_deleted_message" = "Gelöschte Nachricht";
|
"lng_deleted_message" = "Gelöschte Nachricht";
|
||||||
|
"lng_pinned_message" = "Angeheftete Nachricht";
|
||||||
|
"lng_pinned_unpin_sure" = "Angeheftete Nachricht entfernen?";
|
||||||
|
"lng_pinned_pin_sure" = "Möchtest du diese Nachricht anheften?";
|
||||||
|
"lng_pinned_pin" = "Anheften";
|
||||||
|
"lng_pinned_unpin" = "Entfernen";
|
||||||
|
"lng_pinned_notify" = "Alle benachrichtigen";
|
||||||
|
|
||||||
"lng_intro" = "Willkommen beim [a href=\"https://telegram.org/\"]offiziellen Desktop Messenger[/a].\n[b]Schnell[/b] und [b]sicher[/b] chatten leicht gemacht.";
|
"lng_intro" = "Willkommen beim [a href=\"https://telegram.org/\"]offiziellen Desktop Messenger[/a].\n[b]Schnell[/b] und [b]sicher[/b] chatten leicht gemacht.";
|
||||||
"lng_start_msgs" = "JETZT STARTEN";
|
"lng_start_msgs" = "JETZT STARTEN";
|
||||||
|
@ -410,7 +416,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_edit_contact" = "Bearbeiten";
|
"lng_profile_edit_contact" = "Bearbeiten";
|
||||||
"lng_profile_enable_notifications" = "Benachrichtigungen";
|
"lng_profile_enable_notifications" = "Benachrichtigungen";
|
||||||
"lng_profile_clear_history" = "Chatverlauf löschen";
|
"lng_profile_clear_history" = "Chatverlauf löschen";
|
||||||
"lng_profile_delete_conversation" = "Chat entfernen";
|
"lng_profile_delete_conversation" = "Chat löschen";
|
||||||
"lng_profile_clear_and_exit" = "Löschen und verlassen";
|
"lng_profile_clear_and_exit" = "Löschen und verlassen";
|
||||||
"lng_profile_leave_channel" = "Kanal verlassen";
|
"lng_profile_leave_channel" = "Kanal verlassen";
|
||||||
"lng_profile_delete_channel" = "Kanal löschen";
|
"lng_profile_delete_channel" = "Kanal löschen";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Neues Mitglied";
|
"lng_profile_add_participant" = "Neues Mitglied";
|
||||||
"lng_profile_delete_and_exit" = "Verlassen";
|
"lng_profile_delete_and_exit" = "Verlassen";
|
||||||
"lng_profile_kick" = "Entfernen";
|
"lng_profile_kick" = "Entfernen";
|
||||||
|
"lng_profile_admin" = "Admin";
|
||||||
"lng_profile_sure_kick" = "{user} aus der Gruppe entfernen?";
|
"lng_profile_sure_kick" = "{user} aus der Gruppe entfernen?";
|
||||||
"lng_profile_sure_kick_channel" = "{user} aus dem Kanal entfernen?";
|
"lng_profile_sure_kick_channel" = "{user} aus dem Kanal entfernen?";
|
||||||
"lng_profile_sure_kick_admin" = "{user} als Administrator entfernen?";
|
"lng_profile_sure_kick_admin" = "{user} als Administrator entfernen?";
|
||||||
|
@ -469,13 +476,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Weiter";
|
"lng_create_group_next" = "Weiter";
|
||||||
"lng_create_group_create" = "Erstellen";
|
"lng_create_group_create" = "Erstellen";
|
||||||
"lng_create_group_title" = "Neue Gruppe erstellen";
|
"lng_create_group_title" = "Neue Gruppe erstellen";
|
||||||
"lng_create_group_about" = "{count:_not_used|# Mitglied|# Mitglieder} passen in jede Gruppe, \npraktisch für eine kleinere Gemeinschaft.";
|
"lng_create_group_about" = "{count:_not_used|# Mitglied|# Mitglieder} passen in jede Gruppe, praktisch für eine kleinere Gemeinschaft.";
|
||||||
"lng_create_channel_title" = "Neuen Kanal erstellen";
|
"lng_create_channel_title" = "Neuen Kanal erstellen";
|
||||||
"lng_create_channel_about" = "In einen Kanal passen unbegrenzt viele Leute, also ideal für ein großes Publikum.";
|
"lng_create_channel_about" = "In einen Kanal passen unbegrenzt viele Leute, also ideal für ein großes Publikum.";
|
||||||
"lng_create_public_channel_title" = "Öffentlicher Kanal";
|
"lng_create_public_channel_title" = "Öffentlicher Kanal";
|
||||||
"lng_create_public_channel_about" = "Jeder kann deinen Kanal finden und beitreten";
|
"lng_create_public_channel_about" = "Jeder kann deinen Kanal finden und beitreten";
|
||||||
"lng_create_private_channel_title" = "Privater Kanal";
|
"lng_create_private_channel_title" = "Privater Kanal";
|
||||||
"lng_create_private_channel_about" = "Man kann nur per Einladungslink deinem Kanal beitreten";
|
"lng_create_private_channel_about" = "Man kann nur per Einladungslink deinem Kanal beitreten";
|
||||||
|
"lng_create_public_group_title" = "Öffentliche Gruppe";
|
||||||
|
"lng_create_public_group_about" = "Öffentliche Gruppen kann jeder über die Suche finden, gesamter Chatverlauf ist für alle einsehbar und jeder kann der Gruppe beitreten";
|
||||||
|
"lng_create_private_group_title" = "Private Gruppe";
|
||||||
|
"lng_create_private_group_about" = "Nur eingeladene Nutzer können die Gruppe betreten und den gesamten Chatverlauf einsehen";
|
||||||
"lng_create_channel_comments" = "Kommentare aktivieren";
|
"lng_create_channel_comments" = "Kommentare aktivieren";
|
||||||
"lng_create_channel_comments_about" = "Wenn du Kommentare aktivierst, können sich alle an der Diskussion beteiligen";
|
"lng_create_channel_comments_about" = "Wenn du Kommentare aktivierst, können sich alle an der Diskussion beteiligen";
|
||||||
"lng_create_group_skip" = "Überspringen";
|
"lng_create_group_skip" = "Überspringen";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} hat die Gruppe «{title}» erstellt";
|
"lng_action_created_chat" = "{from} hat die Gruppe «{title}» erstellt";
|
||||||
"lng_action_created_channel" = "Kanal «{title}» erstellt";
|
"lng_action_created_channel" = "Kanal «{title}» erstellt";
|
||||||
"lng_action_group_migrate" = "Gruppe wurde in eine Supergruppe geändert";
|
"lng_action_group_migrate" = "Gruppe wurde in eine Supergruppe geändert";
|
||||||
|
"lng_action_pinned_message" = "{from} hat «{text}» angeheftet";
|
||||||
|
"lng_action_pinned_media" = "{from} hat {media} angeheftet";
|
||||||
|
"lng_action_pinned_media_photo" = "ein Bild";
|
||||||
|
"lng_action_pinned_media_video" = "ein Video";
|
||||||
|
"lng_action_pinned_media_audio" = "ein Audio";
|
||||||
|
"lng_action_pinned_media_voice" = "eine Sprachnachricht";
|
||||||
|
"lng_action_pinned_media_file" = "eine Datei";
|
||||||
|
"lng_action_pinned_media_gif" = "ein GIF";
|
||||||
|
"lng_action_pinned_media_contact" = "einen Kontakt";
|
||||||
|
"lng_action_pinned_media_location" = "einen Standort";
|
||||||
|
"lng_action_pinned_media_sticker" = "einen Sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "Limit von {count:_not_used_|# Mitglied|# Mitgliedern} erreicht";
|
"lng_profile_migrate_reached" = "Limit von {count:_not_used_|# Mitglied|# Mitgliedern} erreicht";
|
||||||
"lng_profile_migrate_about" = "Für weitere Funktionen und um das Limit aufzuheben in Supergruppe ändern:";
|
"lng_profile_migrate_about" = "Für weitere Funktionen und um das Limit aufzuheben in Supergruppe ändern:";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— Mitteilungen sind standardmäßig stumm";
|
"lng_profile_migrate_feature4" = "— Mitteilungen sind standardmäßig stumm";
|
||||||
"lng_profile_migrate_button" = "In Supergruppe ändern";
|
"lng_profile_migrate_button" = "In Supergruppe ändern";
|
||||||
"lng_profile_migrate_sure" = "Wirklich diese Gruppe in eine Supergruppe ändern? Das kann nicht rückgängig gemacht werden.";
|
"lng_profile_migrate_sure" = "Wirklich diese Gruppe in eine Supergruppe ändern? Das kann nicht rückgängig gemacht werden.";
|
||||||
|
"lng_profile_convert_button" = "In Supergruppe ändern";
|
||||||
|
"lng_profile_convert_title" = "In Supergruppe ändern";
|
||||||
|
"lng_profile_convert_about" = "Supergruppen:";
|
||||||
|
"lng_profile_convert_feature1" = "— Neue Mitglieder sehen gesamten Verlauf";
|
||||||
|
"lng_profile_convert_feature2" = "— Nachrichten werden bei allen gelöscht";
|
||||||
|
"lng_profile_convert_feature3" = "— Jeder kann eigene Nachrichten bearbeiten";
|
||||||
|
"lng_profile_convert_feature4" = "— Gründer kann Gruppe öffentlich machen";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Wichtig:{bold_end} Die Änderung in eine Supergruppe kann nicht rückgängig gemacht werden.";
|
||||||
|
"lng_profile_convert_confirm" = "Ändern";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "Du kannst nach der Änderung der Gruppe in eine Supergruppe bis zu {count:_not_used_|# Mitglied|# Mitglieder} hinzufügen.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# Kommentar|# Kommentare} »";
|
"lng_channel_comments_count" = "{count:_not_used_|# Kommentar|# Kommentare} »";
|
||||||
"lng_channel_hide_comments" = "Kommentare verstecken";
|
"lng_channel_hide_comments" = "Kommentare verstecken";
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (Sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (Sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Nutzer sperren";
|
||||||
|
"lng_delete_all_from" = "Alles von diesem Nutzer löschen";
|
||||||
"lng_report_spam" = "Spam melden";
|
"lng_report_spam" = "Spam melden";
|
||||||
"lng_report_spam_hide" = "Schließen";
|
"lng_report_spam_hide" = "Schließen";
|
||||||
"lng_report_spam_thanks" = "Danke!";
|
"lng_report_spam_thanks" = "Danke!";
|
||||||
|
@ -717,7 +751,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_view_channel" = "Kanalinfo anzeigen";
|
"lng_context_view_channel" = "Kanalinfo anzeigen";
|
||||||
|
|
||||||
"lng_context_copy_link" = "Link kopieren";
|
"lng_context_copy_link" = "Link kopieren";
|
||||||
"lng_context_copy_post_link" = "Link kopieren";
|
"lng_context_copy_post_link" = "Nachrichtenlink kopieren";
|
||||||
"lng_context_copy_email" = "E-Mail-Adresse kopieren";
|
"lng_context_copy_email" = "E-Mail-Adresse kopieren";
|
||||||
"lng_context_copy_hashtag" = "Hashtag kopieren";
|
"lng_context_copy_hashtag" = "Hashtag kopieren";
|
||||||
"lng_context_copy_mention" = "Benutzername kopieren";
|
"lng_context_copy_mention" = "Benutzername kopieren";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Nachricht weiterleiten";
|
"lng_context_forward_msg" = "Nachricht weiterleiten";
|
||||||
"lng_context_delete_msg" = "Nachricht löschen";
|
"lng_context_delete_msg" = "Nachricht löschen";
|
||||||
"lng_context_select_msg" = "Nachricht auswählen";
|
"lng_context_select_msg" = "Nachricht auswählen";
|
||||||
|
"lng_context_pin_msg" = "Nachricht anheften";
|
||||||
|
"lng_context_unpin_msg" = "Nachricht entfernen";
|
||||||
"lng_context_cancel_upload" = "Upload abbrechen";
|
"lng_context_cancel_upload" = "Upload abbrechen";
|
||||||
"lng_context_copy_selected" = "Text kopieren";
|
"lng_context_copy_selected" = "Text kopieren";
|
||||||
"lng_context_forward_selected" = "Auswahl weiterleiten";
|
"lng_context_forward_selected" = "Auswahl weiterleiten";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
||||||
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||||
"lng_new_version_text" = "— Bearbeite deine Nachrichten in Kanälen und Supergruppen.\n— Teile direkt Links zu einzelnen Kanal-Nachrichten über das Teilen-Symbol neben der Nachricht.\n— Unterschreibe Nachrichten in Kanälen - so kann jeder sehen, welcher Admin die Nachricht geschrieben hat.\n— Sende 'lautlose Nachrichten' in Kanälen. Klasse, wenn man mal wieder mitten in der Nacht eine Nachricht senden muss.";
|
"lng_new_version_text" = "ÖFFENTLICHE GRUPPEN, NACHRICHTEN ANHEFTEN, 5000 MITGLIEDER\n\n— Gruppen dürfen nun 5.000 Mitglieder haben (zuvor waren es 1.000)\n— Jede Gruppe - egal wie groß - kann ab sofort in eine Supergruppe geändert werden\n\nNeue Werkzeuge für Supergruppen-Admins:\n\n— Mache deine Gruppe öffentlich: Jeder kann den Inhalt einsehen und sie betreten\n— Hefte Nachrichten an: Perfekt um Gruppenmitglieder über Neuigkeiten zu informieren\n— Lösche mehrere Nachrichten, melde sie aufgrund von Spam, blockiere Mitglieder oder entferne alle Nachrichten von bestimmten Nutzern\n\nMehr Infos zum neuen Update:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "Nuevo texto...";
|
"lng_edit_message_text" = "Nuevo texto...";
|
||||||
"lng_deleted" = "Desconocido";
|
"lng_deleted" = "Desconocido";
|
||||||
"lng_deleted_message" = "Mensaje eliminado";
|
"lng_deleted_message" = "Mensaje eliminado";
|
||||||
|
"lng_pinned_message" = "Mensaje anclado";
|
||||||
|
"lng_pinned_unpin_sure" = "¿Quieres desanclar este mensaje?";
|
||||||
|
"lng_pinned_pin_sure" = "¿Quieres anclar este mensaje?";
|
||||||
|
"lng_pinned_pin" = "Anclar";
|
||||||
|
"lng_pinned_unpin" = "Desanclar";
|
||||||
|
"lng_pinned_notify" = "Notificar a todos los miembros";
|
||||||
|
|
||||||
"lng_intro" = "La app oficial para PC de [a href=\"https://telegram.org/\"]Telegram[/a].\nEs [b]rápida[/b] y [b]segura[/b].";
|
"lng_intro" = "La app oficial para PC de [a href=\"https://telegram.org/\"]Telegram[/a].\nEs [b]rápida[/b] y [b]segura[/b].";
|
||||||
"lng_start_msgs" = "EMPEZAR A CONVERSAR";
|
"lng_start_msgs" = "EMPEZAR A CONVERSAR";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Añadir miembros";
|
"lng_profile_add_participant" = "Añadir miembros";
|
||||||
"lng_profile_delete_and_exit" = "Dejar grupo";
|
"lng_profile_delete_and_exit" = "Dejar grupo";
|
||||||
"lng_profile_kick" = "Eliminar";
|
"lng_profile_kick" = "Eliminar";
|
||||||
|
"lng_profile_admin" = "administrador";
|
||||||
"lng_profile_sure_kick" = "¿Eliminar a {user} del grupo?";
|
"lng_profile_sure_kick" = "¿Eliminar a {user} del grupo?";
|
||||||
"lng_profile_sure_kick_channel" = "¿Eliminar a {user} del canal?";
|
"lng_profile_sure_kick_channel" = "¿Eliminar a {user} del canal?";
|
||||||
"lng_profile_sure_kick_admin" = "¿Eliminar a {user} de los administradores?";
|
"lng_profile_sure_kick_admin" = "¿Eliminar a {user} de los administradores?";
|
||||||
|
@ -469,13 +476,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Siguiente";
|
"lng_create_group_next" = "Siguiente";
|
||||||
"lng_create_group_create" = "Crear";
|
"lng_create_group_create" = "Crear";
|
||||||
"lng_create_group_title" = "Nuevo grupo";
|
"lng_create_group_title" = "Nuevo grupo";
|
||||||
"lng_create_group_about" = "Los grupos son ideales para las comunidades\nmás pequeñas, de hasta {count:_not_used|# miembro|# miembros}";
|
"lng_create_group_about" = "Los grupos son ideales para las comunidades limitadas. Pueden tener hasta {count:_not_used|# miembro|# miembros}";
|
||||||
"lng_create_channel_title" = "Nuevo canal";
|
"lng_create_channel_title" = "Nuevo canal";
|
||||||
"lng_create_channel_about" = "Los canales permiten difundir tus mensajes a audiencias ilimitadas";
|
"lng_create_channel_about" = "Los canales permiten difundir tus mensajes a audiencias ilimitadas";
|
||||||
"lng_create_public_channel_title" = "Canal público";
|
"lng_create_public_channel_title" = "Canal público";
|
||||||
"lng_create_public_channel_about" = "Cualquiera puede encontrar el canal en la búsqueda y unirse";
|
"lng_create_public_channel_about" = "Cualquiera puede encontrar el canal en la búsqueda y unirse";
|
||||||
"lng_create_private_channel_title" = "Canal privado";
|
"lng_create_private_channel_title" = "Canal privado";
|
||||||
"lng_create_private_channel_about" = "Sólo las personas con el enlace de invitación especial podrán unirse";
|
"lng_create_private_channel_about" = "Sólo las personas con el enlace de invitación especial podrán unirse";
|
||||||
|
"lng_create_public_group_title" = "Grupo público";
|
||||||
|
"lng_create_public_group_about" = "Cualquiera puede encontrar el grupo en la búsqueda y unirse. El historial del chat está disponible para todos";
|
||||||
|
"lng_create_private_group_title" = "Grupo privado";
|
||||||
|
"lng_create_private_group_about" = "Las personas pueden unirse sólo si son invitadas o tienen un enlace de invitación";
|
||||||
"lng_create_channel_comments" = "Activar comentarios";
|
"lng_create_channel_comments" = "Activar comentarios";
|
||||||
"lng_create_channel_comments_about" = "Si activas los comentarios, las personas podrán hablar de tus mensajes en el canal";
|
"lng_create_channel_comments_about" = "Si activas los comentarios, las personas podrán hablar de tus mensajes en el canal";
|
||||||
"lng_create_group_skip" = "Omitir";
|
"lng_create_group_skip" = "Omitir";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} creó el grupo «{title}»";
|
"lng_action_created_chat" = "{from} creó el grupo «{title}»";
|
||||||
"lng_action_created_channel" = "Se creó el canal «{title}»";
|
"lng_action_created_channel" = "Se creó el canal «{title}»";
|
||||||
"lng_action_group_migrate" = "Este grupo fue convertido en un supergrupo";
|
"lng_action_group_migrate" = "Este grupo fue convertido en un supergrupo";
|
||||||
|
"lng_action_pinned_message" = "{from} ancló «{text}»";
|
||||||
|
"lng_action_pinned_media" = "{from} ancló {media}";
|
||||||
|
"lng_action_pinned_media_photo" = "una foto";
|
||||||
|
"lng_action_pinned_media_video" = "un vídeo";
|
||||||
|
"lng_action_pinned_media_audio" = "un audio";
|
||||||
|
"lng_action_pinned_media_voice" = "un mensaje de voz";
|
||||||
|
"lng_action_pinned_media_file" = "un archivo";
|
||||||
|
"lng_action_pinned_media_gif" = "un GIF";
|
||||||
|
"lng_action_pinned_media_contact" = "un contacto";
|
||||||
|
"lng_action_pinned_media_location" = "una ubicación";
|
||||||
|
"lng_action_pinned_media_sticker" = "un sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "Límite de {count:_not_used_|# miembro|# miembros} alcanzado";
|
"lng_profile_migrate_reached" = "Límite de {count:_not_used_|# miembro|# miembros} alcanzado";
|
||||||
"lng_profile_migrate_about" = "Para superar el límite y tener características adicionales, conviértelo en un supergrupo:";
|
"lng_profile_migrate_about" = "Para superar el límite y tener características adicionales, conviértelo en un supergrupo:";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "– Notificaciones silenciadas por defecto";
|
"lng_profile_migrate_feature4" = "– Notificaciones silenciadas por defecto";
|
||||||
"lng_profile_migrate_button" = "Convertir en supergrupo";
|
"lng_profile_migrate_button" = "Convertir en supergrupo";
|
||||||
"lng_profile_migrate_sure" = "¿Quieres convertir este grupo en un supergrupo? No puedes deshacer esta acción.";
|
"lng_profile_migrate_sure" = "¿Quieres convertir este grupo en un supergrupo? No puedes deshacer esta acción.";
|
||||||
|
"lng_profile_convert_button" = "Convertir en supergrupo";
|
||||||
|
"lng_profile_convert_title" = "Convertir en supergrupo";
|
||||||
|
"lng_profile_convert_about" = "En los supergrupos:";
|
||||||
|
"lng_profile_convert_feature1" = "— Los nuevos miembros ven todo el historial";
|
||||||
|
"lng_profile_convert_feature2" = "— Los mensajes son eliminados para todos";
|
||||||
|
"lng_profile_convert_feature3" = "— Un miembro puede editar sus mensajes";
|
||||||
|
"lng_profile_convert_feature4" = "— El creador puede generar un enlace público";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Importante:{bold_end} Esta acción no se puede deshacer";
|
||||||
|
"lng_profile_convert_confirm" = "Convertir";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "Podrás añadir hasta {count:_not_used_|# miembro|# miembros} una vez que conviertas tu grupo en un supergrupo.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# comentario|# comentarios}";
|
"lng_channel_comments_count" = "{count:_not_used_|# comentario|# comentarios}";
|
||||||
"lng_channel_hide_comments" = "Ocultar comentarios";
|
"lng_channel_hide_comments" = "Ocultar comentarios";
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Suspender usuario";
|
||||||
|
"lng_delete_all_from" = "Eliminar todo lo de este usuario";
|
||||||
"lng_report_spam" = "Reportar spam";
|
"lng_report_spam" = "Reportar spam";
|
||||||
"lng_report_spam_hide" = "Ocultar";
|
"lng_report_spam_hide" = "Ocultar";
|
||||||
"lng_report_spam_thanks" = "¡Gracias por tu reporte!";
|
"lng_report_spam_thanks" = "¡Gracias por tu reporte!";
|
||||||
|
@ -717,7 +751,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_view_channel" = "Ver información";
|
"lng_context_view_channel" = "Ver información";
|
||||||
|
|
||||||
"lng_context_copy_link" = "Copiar enlace";
|
"lng_context_copy_link" = "Copiar enlace";
|
||||||
"lng_context_copy_post_link" = "Copiar enlace";
|
"lng_context_copy_post_link" = "Copiar enlace de la publicación";
|
||||||
"lng_context_copy_email" = "Copiar dirección de correo electrónico";
|
"lng_context_copy_email" = "Copiar dirección de correo electrónico";
|
||||||
"lng_context_copy_hashtag" = "Copiar hashtag";
|
"lng_context_copy_hashtag" = "Copiar hashtag";
|
||||||
"lng_context_copy_mention" = "Copiar alias";
|
"lng_context_copy_mention" = "Copiar alias";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Reenviar mensaje";
|
"lng_context_forward_msg" = "Reenviar mensaje";
|
||||||
"lng_context_delete_msg" = "Eliminar mensaje";
|
"lng_context_delete_msg" = "Eliminar mensaje";
|
||||||
"lng_context_select_msg" = "Seleccionar mensaje";
|
"lng_context_select_msg" = "Seleccionar mensaje";
|
||||||
|
"lng_context_pin_msg" = "Anclar mensaje";
|
||||||
|
"lng_context_unpin_msg" = "Desanclar mensaje";
|
||||||
"lng_context_cancel_upload" = "Cancelar envío";
|
"lng_context_cancel_upload" = "Cancelar envío";
|
||||||
"lng_context_copy_selected" = "Copiar el texto seleccionado";
|
"lng_context_copy_selected" = "Copiar el texto seleccionado";
|
||||||
"lng_context_forward_selected" = "Reenviar lo seleccionado";
|
"lng_context_forward_selected" = "Reenviar lo seleccionado";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
||||||
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
||||||
"lng_new_version_text" = "— Edita tus mensajes en canales y supergrupos.\n— Comparte enlaces a publicaciones específicas en canales, a través del menú contextual de la publicación. \n— Añade firmas de los administradores a los mensajes en canales.\n— Envía mensajes silenciosos en canales, que no serán notificados a los miembros. Es útil para publicaciones que no son urgentes o en medio de la noche.";
|
"lng_new_version_text" = "GRUPOS PÚBLICOS, PUBLICACIONES ANCLADAS, 5000 MIEMBROS\n\n— Los grupos ahora pueden tener hasta 5000 miembros (antes eran 1000)\n— Los grupos de cualquier tamaño pueden ser convertidos en supergrupos\n\nNuevas herramientas para los administradores de supergrupos:\n\n— Haz público tu grupo, generando un enlace público. Cualquiera podrá ver el chat y unirse.\n— Ancla mensajes, para mantener visible lo importante, y notifica a todos los miembros.\n— Elige varios mensajes para eliminar, reportar como spam, bloquear usuarios o quitar todos los mensajes de un usuario en particular.\n\nMás sobre esta actualización:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "Nuovo testo messaggio..";
|
"lng_edit_message_text" = "Nuovo testo messaggio..";
|
||||||
"lng_deleted" = "Sconosciuto";
|
"lng_deleted" = "Sconosciuto";
|
||||||
"lng_deleted_message" = "Messaggio eliminato";
|
"lng_deleted_message" = "Messaggio eliminato";
|
||||||
|
"lng_pinned_message" = "Messaggio fissato";
|
||||||
|
"lng_pinned_unpin_sure" = "Vuoi togliere questo messaggio?";
|
||||||
|
"lng_pinned_pin_sure" = "Vuoi fissare questo messaggio?";
|
||||||
|
"lng_pinned_pin" = "Fissa";
|
||||||
|
"lng_pinned_unpin" = "Stacca";
|
||||||
|
"lng_pinned_notify" = "Notifica tutti i membri";
|
||||||
|
|
||||||
"lng_intro" = "Benvenuti nell'app desktop ufficiale di [a href=\"https://telegram.org/\"]Telegram[/a].\nÈ [b]veloce[/b] e [b]sicura[/b].";
|
"lng_intro" = "Benvenuti nell'app desktop ufficiale di [a href=\"https://telegram.org/\"]Telegram[/a].\nÈ [b]veloce[/b] e [b]sicura[/b].";
|
||||||
"lng_start_msgs" = "INIZIA A MESSAGGIARE";
|
"lng_start_msgs" = "INIZIA A MESSAGGIARE";
|
||||||
|
@ -259,9 +265,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_replace_emojis" = "Riconosci emoji";
|
"lng_settings_replace_emojis" = "Riconosci emoji";
|
||||||
"lng_settings_view_emojis" = "Visualizza lista";
|
"lng_settings_view_emojis" = "Visualizza lista";
|
||||||
"lng_settings_emoji_list" = "Emoji supportate";
|
"lng_settings_emoji_list" = "Emoji supportate";
|
||||||
"lng_settings_send_enter" = "Spedisci con Invio";
|
"lng_settings_send_enter" = "Invia con tasto invio";
|
||||||
"lng_settings_send_ctrlenter" = "Spedisci con Ctrl+Invio";
|
"lng_settings_send_ctrlenter" = "Invia con Ctrl+Invio";
|
||||||
"lng_settings_send_cmdenter" = "Spedisci con Cmd+Invio";
|
"lng_settings_send_cmdenter" = "Invia con Cmd+Invio";
|
||||||
|
|
||||||
"lng_settings_section_background" = "Sfondo chat";
|
"lng_settings_section_background" = "Sfondo chat";
|
||||||
"lng_settings_bg_from_gallery" = "Scegli dalla galleria";
|
"lng_settings_bg_from_gallery" = "Scegli dalla galleria";
|
||||||
|
@ -373,10 +379,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_reset_button" = "Chiudi";
|
"lng_settings_reset_button" = "Chiudi";
|
||||||
"lng_settings_reset_done" = "Altre sessioni terminate";
|
"lng_settings_reset_done" = "Altre sessioni terminate";
|
||||||
"lng_settings_ask_question" = "Fai una domanda";
|
"lng_settings_ask_question" = "Fai una domanda";
|
||||||
"lng_settings_ask_sure" = "Per favore, considera che il supporto su Telegram è offerto da volontari. Proveremo a risponderti il più velocemente possibile, ma potrebbe volerci un po' di tempo.\n\nDai un'occhiata alle FAQ di Telegram: potrai trovare importanti suggerimenti riguardo alcune problematiche e risposte alla maggior parte delle domande.";
|
"lng_settings_ask_sure" = "Per favore nota che il supporto di Telegram è fornito da volontari. Proviamo a rispondere quanto prima, ma potrebbe volerci del tempo.\n\nDai un'occhiata alle domande frequenti su Telegram: potrai trovare importanti suggerimenti riguardo alcune problematiche e risposte alla maggior parte delle domande.";
|
||||||
"lng_settings_faq_button" = "Vai alle FAQ";
|
"lng_settings_faq_button" = "Domande frequenti";
|
||||||
"lng_settings_ask_ok" = "Chiedi";
|
"lng_settings_ask_ok" = "Chiedi";
|
||||||
"lng_settings_faq" = "FAQ di Telegram";
|
"lng_settings_faq" = "Domande frequenti";
|
||||||
"lng_settings_logout" = "Disconnetti";
|
"lng_settings_logout" = "Disconnetti";
|
||||||
"lng_sure_logout" = "Sicuro di volerti disconnettere?";
|
"lng_sure_logout" = "Sicuro di volerti disconnettere?";
|
||||||
|
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Aggiungi membri";
|
"lng_profile_add_participant" = "Aggiungi membri";
|
||||||
"lng_profile_delete_and_exit" = "Esci";
|
"lng_profile_delete_and_exit" = "Esci";
|
||||||
"lng_profile_kick" = "Rimuovi";
|
"lng_profile_kick" = "Rimuovi";
|
||||||
|
"lng_profile_admin" = "amministratore";
|
||||||
"lng_profile_sure_kick" = "Rimuovere {user} dal gruppo?";
|
"lng_profile_sure_kick" = "Rimuovere {user} dal gruppo?";
|
||||||
"lng_profile_sure_kick_channel" = "Rimuovere {user} dal canale?";
|
"lng_profile_sure_kick_channel" = "Rimuovere {user} dal canale?";
|
||||||
"lng_profile_sure_kick_admin" = "Rimuovere {user} dagli amministratori?";
|
"lng_profile_sure_kick_admin" = "Rimuovere {user} dagli amministratori?";
|
||||||
|
@ -460,22 +467,26 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_chat_all_members_admins" = "Tutti sono amministratori";
|
"lng_chat_all_members_admins" = "Tutti sono amministratori";
|
||||||
"lng_chat_about_all_admins" = "Tutti i membri possono aggiungere nuovi membri, modificare nome e foto del gruppo.";
|
"lng_chat_about_all_admins" = "Tutti i membri possono aggiungere nuovi membri, modificare nome e foto del gruppo.";
|
||||||
"lng_chat_about_admins" = "Solo gli amministratori possono aggiungere e rimuovere membri e modificare nome e foto del gruppo.";
|
"lng_chat_about_admins" = "Gli amministratori possono aggiungere e rimuovere membri e modificare nome e foto del gruppo.";
|
||||||
|
|
||||||
"lng_participant_filter" = "Cerca";
|
"lng_participant_filter" = "Cerca";
|
||||||
"lng_participant_invite" = "Invita";
|
"lng_participant_invite" = "Invita";
|
||||||
"lng_participant_invite_sorry" = "Spiacenti, puoi aggiungere solo {count:_not_used|il primo membro|i primi # membri} a un canale.\n\nDa adesso, le persone potranno unirsi tramite il tuo link di invito.";
|
"lng_participant_invite_sorry" = "Spiacenti, puoi aggiungere solo {count:_not_used|il primo membro|i primi # membri} a un canale.\n\nDa adesso, le persone potranno unirsi con il tuo link di invito.";
|
||||||
"lng_create_group_back" = "Indietro";
|
"lng_create_group_back" = "Indietro";
|
||||||
"lng_create_group_next" = "Avanti";
|
"lng_create_group_next" = "Avanti";
|
||||||
"lng_create_group_create" = "Crea";
|
"lng_create_group_create" = "Crea";
|
||||||
"lng_create_group_title" = "Nuovo gruppo";
|
"lng_create_group_title" = "Nuovo gruppo";
|
||||||
"lng_create_group_about" = "I gruppi sono ideali per le piccole community,\npossono avere fino a {count:_not_used|# membro|# membri}";
|
"lng_create_group_about" = "I gruppi sono ideali per le community limitate,\npossono avere fino a {count:_not_used|# membro|# membri}";
|
||||||
"lng_create_channel_title" = "Nuovo canale";
|
"lng_create_channel_title" = "Nuovo canale";
|
||||||
"lng_create_channel_about" = "I canali sono uno strumento per diffondere i tuoi messaggi a un pubblico illimitato";
|
"lng_create_channel_about" = "I canali sono uno strumento per diffondere i tuoi messaggi a un pubblico illimitato";
|
||||||
"lng_create_public_channel_title" = "Canale pubblico";
|
"lng_create_public_channel_title" = "Canale pubblico";
|
||||||
"lng_create_public_channel_about" = "Chiunque può cercare il canale nella ricerca e unirsi";
|
"lng_create_public_channel_about" = "Chiunque può cercare il canale nella ricerca e unirsi";
|
||||||
"lng_create_private_channel_title" = "Canale privato";
|
"lng_create_private_channel_title" = "Canale privato";
|
||||||
"lng_create_private_channel_about" = "Solo le persone con uno speciale link di invito potranno unirsi";
|
"lng_create_private_channel_about" = "Solo le persone con uno speciale link di invito potranno unirsi";
|
||||||
|
"lng_create_public_group_title" = "Gruppo pubblico";
|
||||||
|
"lng_create_public_group_about" = "Chiunque può trovare il gruppo nella ricerca e unirsi, la cronologia è disponibile per tutti";
|
||||||
|
"lng_create_private_group_title" = "Gruppo privato";
|
||||||
|
"lng_create_private_group_about" = "Le persone si possono unire solo se invitate o con un link di invito";
|
||||||
"lng_create_channel_comments" = "Attiva i commenti";
|
"lng_create_channel_comments" = "Attiva i commenti";
|
||||||
"lng_create_channel_comments_about" = "Se attivi i commenti, i membri potranno discutere quello che pubblichi nel canale.";
|
"lng_create_channel_comments_about" = "Se attivi i commenti, i membri potranno discutere quello che pubblichi nel canale.";
|
||||||
"lng_create_group_skip" = "Salta";
|
"lng_create_group_skip" = "Salta";
|
||||||
|
@ -491,8 +502,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_channel_crop" = "Seleziona un riquadro per la foto del canale";
|
"lng_create_channel_crop" = "Seleziona un riquadro per la foto del canale";
|
||||||
|
|
||||||
"lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi.";
|
"lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi.";
|
||||||
"lng_failed_add_not_mutual" = "Spiacenti, se una persona lascia un gruppo, solo un contatto in comune può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
|
"lng_failed_add_not_mutual" = "Spiacenti, se una persona lascia un gruppo, solo un contatto reciproco può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
|
||||||
"lng_failed_add_not_mutual_channel" = "Spiacenti, se una persona lascia un canale, solo un contatto in comune può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
|
"lng_failed_add_not_mutual_channel" = "Spiacenti, se una persona lascia un canale, solo un contatto reciproco può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
|
||||||
|
|
||||||
"lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?";
|
"lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?";
|
||||||
"lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata.";
|
"lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata.";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} ha creato il gruppo «{title}»";
|
"lng_action_created_chat" = "{from} ha creato il gruppo «{title}»";
|
||||||
"lng_action_created_channel" = "Canale «{title}» creato";
|
"lng_action_created_channel" = "Canale «{title}» creato";
|
||||||
"lng_action_group_migrate" = "Il gruppo è stato aggiornato a supergruppo";
|
"lng_action_group_migrate" = "Il gruppo è stato aggiornato a supergruppo";
|
||||||
|
"lng_action_pinned_message" = "{from} ha fissato «{text}»";
|
||||||
|
"lng_action_pinned_media" = "{from} ha fissato {media}";
|
||||||
|
"lng_action_pinned_media_photo" = "una foto";
|
||||||
|
"lng_action_pinned_media_video" = "un video";
|
||||||
|
"lng_action_pinned_media_audio" = "un file audio";
|
||||||
|
"lng_action_pinned_media_voice" = "un messaggio vocale";
|
||||||
|
"lng_action_pinned_media_file" = "un file";
|
||||||
|
"lng_action_pinned_media_gif" = "una GIF";
|
||||||
|
"lng_action_pinned_media_contact" = "un contatto";
|
||||||
|
"lng_action_pinned_media_location" = "una posizione";
|
||||||
|
"lng_action_pinned_media_sticker" = "uno sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "Limite di {count:_not_used_|# membro|# membri} raggiunto";
|
"lng_profile_migrate_reached" = "Limite di {count:_not_used_|# membro|# membri} raggiunto";
|
||||||
"lng_profile_migrate_about" = "Se vuoi superare questo limite, puoi aggiornare il gruppo a supergruppo. Nei supergruppi:";
|
"lng_profile_migrate_about" = "Se vuoi superare questo limite, puoi aggiornare il gruppo a supergruppo. Nei supergruppi:";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— Le notifiche sono silenziate di default";
|
"lng_profile_migrate_feature4" = "— Le notifiche sono silenziate di default";
|
||||||
"lng_profile_migrate_button" = "Aggiorna a supergruppo";
|
"lng_profile_migrate_button" = "Aggiorna a supergruppo";
|
||||||
"lng_profile_migrate_sure" = "Sicuro di voler aggiornare questo gruppo a supergruppo? Questa opzione non può essere annullata.";
|
"lng_profile_migrate_sure" = "Sicuro di voler aggiornare questo gruppo a supergruppo? Questa opzione non può essere annullata.";
|
||||||
|
"lng_profile_convert_button" = "Converti in supergruppo";
|
||||||
|
"lng_profile_convert_title" = "Converti in supergruppo";
|
||||||
|
"lng_profile_convert_about" = "Nei supergruppi:";
|
||||||
|
"lng_profile_convert_feature1" = "— I nuovi membri vedono tutta la cronologia";
|
||||||
|
"lng_profile_convert_feature2" = "— I messaggi eliminati scompaiono per tutti";
|
||||||
|
"lng_profile_convert_feature3" = "— I membri possono modificare i loro messaggi";
|
||||||
|
"lng_profile_convert_feature4" = "— Il creatore può creare un link pubblico per il gruppo";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Nota:{bold_end} Questa azione non può essere annullata";
|
||||||
|
"lng_profile_convert_confirm" = "Converti";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "Sarai in grado di aggiungere fino a {count:_not_used_|# membro|# membri} dopo aver aggiornato a supergruppo.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# commento|# commenti}";
|
"lng_channel_comments_count" = "{count:_not_used_|# commento|# commenti}";
|
||||||
"lng_channel_hide_comments" = "Nascondi commenti";
|
"lng_channel_hide_comments" = "Nascondi commenti";
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Rimuovi utente";
|
||||||
|
"lng_delete_all_from" = "Elimina tutto da questo utente";
|
||||||
"lng_report_spam" = "Segnala spam";
|
"lng_report_spam" = "Segnala spam";
|
||||||
"lng_report_spam_hide" = "Nascondi";
|
"lng_report_spam_hide" = "Nascondi";
|
||||||
"lng_report_spam_thanks" = "Grazie per la tua segnalazione!";
|
"lng_report_spam_thanks" = "Grazie per la tua segnalazione!";
|
||||||
|
@ -644,9 +678,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_report_spam_sure_group" = "Sei sicuro di voler segnalare dello spam in questo gruppo?";
|
"lng_report_spam_sure_group" = "Sei sicuro di voler segnalare dello spam in questo gruppo?";
|
||||||
"lng_report_spam_sure_channel" = "Sei sicuro di voler segnalare dello spam in questo canale?";
|
"lng_report_spam_sure_channel" = "Sei sicuro di voler segnalare dello spam in questo canale?";
|
||||||
"lng_report_spam_ok" = "Segnala";
|
"lng_report_spam_ok" = "Segnala";
|
||||||
"lng_cant_send_to_not_contact" = "Spiacenti, ma al momento puoi scrivere\nsolo a contatti in comune. {more_info}";
|
"lng_cant_send_to_not_contact" = "Spiacenti, ma al momento puoi scrivere\nsolo ai contatti reciproci. {more_info}";
|
||||||
"lng_cant_invite_not_contact" = "Spiacenti, ma al momento puoi aggiungere\nai gruppi solo contatti in comune. {more_info}";
|
"lng_cant_invite_not_contact" = "Spiacenti, ma al momento puoi aggiungere\nai gruppi solo contatti reciproci. {more_info}";
|
||||||
"lng_cant_invite_not_contact_channel" = "Spiacenti, ma al momento puoi aggiungere\nai canali solo contatti in comune. {more_info}";
|
"lng_cant_invite_not_contact_channel" = "Spiacenti, ma al momento puoi aggiungere\nai canali solo contatti reciproci. {more_info}";
|
||||||
"lng_cant_more_info" = "Più info »";
|
"lng_cant_more_info" = "Più info »";
|
||||||
"lng_cant_invite_privacy" = "Spiacenti, non puoi aggiungere questo utente al gruppo a causa delle sue impostazioni di privacy.";
|
"lng_cant_invite_privacy" = "Spiacenti, non puoi aggiungere questo utente al gruppo a causa delle sue impostazioni di privacy.";
|
||||||
"lng_cant_invite_privacy_channel" = "Spiacenti, non puoi aggiungere questo utente al canale a causa delle sue impostazioni di privacy.";
|
"lng_cant_invite_privacy_channel" = "Spiacenti, non puoi aggiungere questo utente al canale a causa delle sue impostazioni di privacy.";
|
||||||
|
@ -654,11 +688,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_send_button" = "Invia";
|
"lng_send_button" = "Invia";
|
||||||
"lng_message_ph" = "Scrivi un messaggio..";
|
"lng_message_ph" = "Scrivi un messaggio..";
|
||||||
"lng_comment_ph" = "Scrivi un commento..";
|
"lng_comment_ph" = "Scrivi un commento..";
|
||||||
"lng_broadcast_ph" = "Diffondi un messaggio..";
|
"lng_broadcast_ph" = "Pubblica un post..";
|
||||||
"lng_broadcast_silent_ph" = "Broadcast silenzioso..";
|
"lng_broadcast_silent_ph" = "Post silenzioso..";
|
||||||
"lng_record_cancel" = "Rilascia fuori da qui per annullare";
|
"lng_record_cancel" = "Rilascia fuori da qui per annullare";
|
||||||
"lng_will_be_notified" = "I membri saranno notificati quando pubblichi";
|
"lng_will_be_notified" = "I post saranno notificati ai membri";
|
||||||
"lng_wont_be_notified" = "I membri non saranno notificati quando pubblichi";
|
"lng_wont_be_notified" = "I post non saranno notificati ai membri";
|
||||||
"lng_empty_history" = "";
|
"lng_empty_history" = "";
|
||||||
"lng_willbe_history" = "Seleziona una chat per iniziare a messaggiare";
|
"lng_willbe_history" = "Seleziona una chat per iniziare a messaggiare";
|
||||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Inoltra messaggio";
|
"lng_context_forward_msg" = "Inoltra messaggio";
|
||||||
"lng_context_delete_msg" = "Elimina messaggio";
|
"lng_context_delete_msg" = "Elimina messaggio";
|
||||||
"lng_context_select_msg" = "Seleziona messaggio";
|
"lng_context_select_msg" = "Seleziona messaggio";
|
||||||
|
"lng_context_pin_msg" = "Fissa messaggio";
|
||||||
|
"lng_context_unpin_msg" = "Togli messaggio";
|
||||||
"lng_context_cancel_upload" = "Annulla caricamento";
|
"lng_context_cancel_upload" = "Annulla caricamento";
|
||||||
"lng_context_copy_selected" = "Copia testo selezionato";
|
"lng_context_copy_selected" = "Copia testo selezionato";
|
||||||
"lng_context_forward_selected" = "Inoltra selezione";
|
"lng_context_forward_selected" = "Inoltra selezione";
|
||||||
|
@ -785,7 +821,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_add_contact" = "Crea";
|
"lng_add_contact" = "Crea";
|
||||||
"lng_add_contact_button" = "Nuovo contatto";
|
"lng_add_contact_button" = "Nuovo contatto";
|
||||||
"lng_contacts_header" = "Contatti";
|
"lng_contacts_header" = "Contatti";
|
||||||
"lng_contact_not_joined" = "Sfortunatamente {name} non si è ancora unito a Telegram, ma puoi inviargli un invito.\n\nTi notificheremo non appena qualcuno dei tuoi contatti si unirà a Telegram.";
|
"lng_contact_not_joined" = "Sfortunatamente {name} non si è ancora unito a Telegram, ma puoi invitarlo.\n\nTi notificheremo per ogni tuo contatto che si unisce a Telegram.";
|
||||||
"lng_try_other_contact" = "Prova un altro";
|
"lng_try_other_contact" = "Prova un altro";
|
||||||
"lng_create_group_link" = "Link";
|
"lng_create_group_link" = "Link";
|
||||||
"lng_create_group_invite_link" = "Link di invito";
|
"lng_create_group_invite_link" = "Link di invito";
|
||||||
|
@ -814,7 +850,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_about_version" = "versione {version}";
|
"lng_about_version" = "versione {version}";
|
||||||
"lng_about_text_1" = "App ufficiale basata sulle [a href=\"https://core.telegram.org/api\"]API di Telegram[/a]\nper velocità e sicurezza";
|
"lng_about_text_1" = "App ufficiale basata sulle [a href=\"https://core.telegram.org/api\"]API di Telegram[/a]\nper velocità e sicurezza";
|
||||||
"lng_about_text_2" = "Questo software è sotto licenza [a href=\"https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\"]GNU GPL[/a] versione 3.\nIl source code è disponibile su [a href=\"https://github.com/telegramdesktop/tdesktop\"]GitHub[/a].";
|
"lng_about_text_2" = "Questo software è sotto licenza [a href=\"https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\"]GNU GPL[/a] versione 3.\nIl source code è disponibile su [a href=\"https://github.com/telegramdesktop/tdesktop\"]GitHub[/a].";
|
||||||
"lng_about_text_3" = "Visita le {faq_open}FAQ di Telegram{faq_close} per maggiori info.";
|
"lng_about_text_3" = "Visita le {faq_open}domande frequenti{faq_close} per maggiori info.";
|
||||||
"lng_about_done" = "Fatto";
|
"lng_about_done" = "Fatto";
|
||||||
|
|
||||||
"lng_search_found_results" = "{count:Nessun messaggio trovato|# messaggio trovato|# messaggi trovati}";
|
"lng_search_found_results" = "{count:Nessun messaggio trovato|# messaggio trovato|# messaggi trovati}";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
||||||
"lng_new_version_minor" = "— Risoluzione di problemi e altri miglioramenti minori";
|
"lng_new_version_minor" = "— Risoluzione di problemi e altri miglioramenti minori";
|
||||||
"lng_new_version_text" = "— Modifica i tuoi messaggi nei canali e nei supergruppi.\n— Condividi link per post specifici nei canali con il menu contestuale dei post.\n— Aggiungi le firme per i messaggi degli amministratori nei canali.\n— Invia messaggi silenziosi nei canali che non notificheranno i membri.\nUtile per i post non urgenti o fatti di notte.";
|
"lng_new_version_text" = "GRUPPI PUBBLICI, POST FISSATI, 5000 MEMBRI\n\n— I gruppi possono ora avere fino a 5000 membri (dai precedenti 1000)\n— Puoi convertire qualsiasi gruppo in supergruppo\n\nNuovi strumenti per gli amministratori dei supergruppi:\n\n— Rendi pubblico il tuo gruppo inserendo un link - chiunque sarà in grado di vedere la chat e unirsi\n— Fissa i messaggi per rendere gli aggiornamenti importanti visibili\n— Seleziona diversi messaggi per eliminarli, segnalarli, bloccare utenti ed eliminare i loro messaggi\n\nPiù info su questo aggiornamento:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "새로운 메시지 내용.";
|
"lng_edit_message_text" = "새로운 메시지 내용.";
|
||||||
"lng_deleted" = "알 수 없음";
|
"lng_deleted" = "알 수 없음";
|
||||||
"lng_deleted_message" = "삭제된 메시지";
|
"lng_deleted_message" = "삭제된 메시지";
|
||||||
|
"lng_pinned_message" = "고정된 메시지";
|
||||||
|
"lng_pinned_unpin_sure" = "메시지를 고정 해제하시겠습니까?";
|
||||||
|
"lng_pinned_pin_sure" = "메시지를 고정 하시겠습니까?";
|
||||||
|
"lng_pinned_pin" = "고정";
|
||||||
|
"lng_pinned_unpin" = "고정해제";
|
||||||
|
"lng_pinned_notify" = "모두알림";
|
||||||
|
|
||||||
"lng_intro" = "[a href=\"https://telegram.org/\"]텔레그램[/a] PC 공식버전에 오신 것을 환영합니다.\n[b]안전[/b]하고 [b]신속[/b]합니다.";
|
"lng_intro" = "[a href=\"https://telegram.org/\"]텔레그램[/a] PC 공식버전에 오신 것을 환영합니다.\n[b]안전[/b]하고 [b]신속[/b]합니다.";
|
||||||
"lng_start_msgs" = "시작하기";
|
"lng_start_msgs" = "시작하기";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "구성원 추가";
|
"lng_profile_add_participant" = "구성원 추가";
|
||||||
"lng_profile_delete_and_exit" = "나가기";
|
"lng_profile_delete_and_exit" = "나가기";
|
||||||
"lng_profile_kick" = "삭제";
|
"lng_profile_kick" = "삭제";
|
||||||
|
"lng_profile_admin" = "관리자";
|
||||||
"lng_profile_sure_kick" = "{user}를 추방하시겠습니까?";
|
"lng_profile_sure_kick" = "{user}를 추방하시겠습니까?";
|
||||||
"lng_profile_sure_kick_channel" = "{user}를 추방하시겠습니까?";
|
"lng_profile_sure_kick_channel" = "{user}를 추방하시겠습니까?";
|
||||||
"lng_profile_sure_kick_admin" = "{user}를 관리자에서 제외 하시겠습니까?";
|
"lng_profile_sure_kick_admin" = "{user}를 관리자에서 제외 하시겠습니까?";
|
||||||
|
@ -469,13 +476,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "다음";
|
"lng_create_group_next" = "다음";
|
||||||
"lng_create_group_create" = "만들기";
|
"lng_create_group_create" = "만들기";
|
||||||
"lng_create_group_title" = "새로운 그룹";
|
"lng_create_group_title" = "새로운 그룹";
|
||||||
"lng_create_group_about" = "작은 커뮤니티에게는 {count:_not_used|# 구성원|# 구성원}명까지 한계인 그룹대화가 적합합니다.";
|
"lng_create_group_about" = "그룹방은 제한된 커뮤니티에 적합하며,\n{count:_not_used|# member|# members} 명까지 구성이 가능합니다.";
|
||||||
"lng_create_channel_title" = "새로운 채널";
|
"lng_create_channel_title" = "새로운 채널";
|
||||||
"lng_create_channel_about" = "채널은 제한이 없는 구성원들에게 메시지를 전달하는 툴입니다.";
|
"lng_create_channel_about" = "채널은 제한이 없는 구성원들에게 메시지를 전달하는 툴입니다.";
|
||||||
"lng_create_public_channel_title" = "공개 채널";
|
"lng_create_public_channel_title" = "공개 채널";
|
||||||
"lng_create_public_channel_about" = "누구나 채널을 검색하고 입장할 수 있습니다.";
|
"lng_create_public_channel_about" = "누구나 채널을 검색하고 입장할 수 있습니다.";
|
||||||
"lng_create_private_channel_title" = "비공개 채널";
|
"lng_create_private_channel_title" = "비공개 채널";
|
||||||
"lng_create_private_channel_about" = "초대 링크를 통해서만 입장이 가능합니다.";
|
"lng_create_private_channel_about" = "초대 링크를 통해서만 입장이 가능합니다.";
|
||||||
|
"lng_create_public_group_title" = "공개그룹";
|
||||||
|
"lng_create_public_group_about" = "누구나 그룹을 검색 및 참여가 가능하며, 채팅 히스토리가 공개됩니다.";
|
||||||
|
"lng_create_private_group_title" = "비공개그룹";
|
||||||
|
"lng_create_private_group_about" = "초대 및 초대링크를 통하여 참여 가능합니다.";
|
||||||
"lng_create_channel_comments" = "코멘트 허용";
|
"lng_create_channel_comments" = "코멘트 허용";
|
||||||
"lng_create_channel_comments_about" = "코멘트가 허용되면, 구성원들이 글에 대하여 토론이 가능합니다.";
|
"lng_create_channel_comments_about" = "코멘트가 허용되면, 구성원들이 글에 대하여 토론이 가능합니다.";
|
||||||
"lng_create_group_skip" = "건너뛰기";
|
"lng_create_group_skip" = "건너뛰기";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} 님이 그룹 «{title}» 을 생성하셨습니다.";
|
"lng_action_created_chat" = "{from} 님이 그룹 «{title}» 을 생성하셨습니다.";
|
||||||
"lng_action_created_channel" = "채널명 «{title}» 생성됨";
|
"lng_action_created_channel" = "채널명 «{title}» 생성됨";
|
||||||
"lng_action_group_migrate" = "이 그룹방은 슈퍼그룹방으로 변환되었습니다";
|
"lng_action_group_migrate" = "이 그룹방은 슈퍼그룹방으로 변환되었습니다";
|
||||||
|
"lng_action_pinned_message" = "{from} 님이 «{text}» 를 고정함";
|
||||||
|
"lng_action_pinned_media" = "{from} 님이 {media} 를 고정함";
|
||||||
|
"lng_action_pinned_media_photo" = "사진";
|
||||||
|
"lng_action_pinned_media_video" = "비디오 파일";
|
||||||
|
"lng_action_pinned_media_audio" = "오디오 파일";
|
||||||
|
"lng_action_pinned_media_voice" = "음성 메시지";
|
||||||
|
"lng_action_pinned_media_file" = "파일";
|
||||||
|
"lng_action_pinned_media_gif" = "GIF 파일";
|
||||||
|
"lng_action_pinned_media_contact" = "연락처 정보";
|
||||||
|
"lng_action_pinned_media_location" = "위치 마크";
|
||||||
|
"lng_action_pinned_media_sticker" = "스티커";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# 명|# 명} 한계치에 도달 되었습니다.";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# 명|# 명} 한계치에 도달 되었습니다.";
|
||||||
"lng_profile_migrate_about" = "최대허용치를 초과하시고 싶으실 경우, 슈퍼그룹방으로 업그레이드해주세요. 슈퍼그룹방은 :";
|
"lng_profile_migrate_about" = "최대허용치를 초과하시고 싶으실 경우, 슈퍼그룹방으로 업그레이드해주세요. 슈퍼그룹방은 :";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— 기본값으로 알림이 무음으로 처리됩니다";
|
"lng_profile_migrate_feature4" = "— 기본값으로 알림이 무음으로 처리됩니다";
|
||||||
"lng_profile_migrate_button" = "슈퍼그룹방으로 업그레이드하기";
|
"lng_profile_migrate_button" = "슈퍼그룹방으로 업그레이드하기";
|
||||||
"lng_profile_migrate_sure" = "정말로 그룹방을 슈퍼그룹방으로 변환하시겠습니까? 이 작업은 취소가 불가능합니다.";
|
"lng_profile_migrate_sure" = "정말로 그룹방을 슈퍼그룹방으로 변환하시겠습니까? 이 작업은 취소가 불가능합니다.";
|
||||||
|
"lng_profile_convert_button" = "슈퍼그룹으로 전환";
|
||||||
|
"lng_profile_convert_title" = "슈퍼그룹으로 전환";
|
||||||
|
"lng_profile_convert_about" = "슈퍼그룹:";
|
||||||
|
"lng_profile_convert_feature1" = "— 모든 구성원이 이전 대화 내용 조회";
|
||||||
|
"lng_profile_convert_feature2" = "— 메시지 삭제시 모두에게 삭제";
|
||||||
|
"lng_profile_convert_feature3" = "— 개인 메시지 수정 가능";
|
||||||
|
"lng_profile_convert_feature4" = "— 방 생성자가 그룹 공개링크 생성가능";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}주위:{bold_end} 이 작업은 되돌릴 수 없습니다.";
|
||||||
|
"lng_profile_convert_confirm" = "변환";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "그룹에서 슈퍼그룹으로 업그레이드시 {count:_not_used_|# 명|# 명} 까지 추가 가능합니다.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# 코멘트|# 코멘트}";
|
"lng_channel_comments_count" = "{count:_not_used_|# 코멘트|# 코멘트}";
|
||||||
"lng_channel_hide_comments" = "코멘트 숨기기";
|
"lng_channel_hide_comments" = "코멘트 숨기기";
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "스티커";
|
"lng_in_dlg_sticker" = "스티커";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (스티커)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (스티커)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "차단하기";
|
||||||
|
"lng_delete_all_from" = "모두에게 메시지 삭제";
|
||||||
"lng_report_spam" = "스팸 신고";
|
"lng_report_spam" = "스팸 신고";
|
||||||
"lng_report_spam_hide" = "숨기기";
|
"lng_report_spam_hide" = "숨기기";
|
||||||
"lng_report_spam_thanks" = "신고해주셔서 감사합니다!";
|
"lng_report_spam_thanks" = "신고해주셔서 감사합니다!";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "메시지 전달";
|
"lng_context_forward_msg" = "메시지 전달";
|
||||||
"lng_context_delete_msg" = "메시지 삭제";
|
"lng_context_delete_msg" = "메시지 삭제";
|
||||||
"lng_context_select_msg" = "메시지 선택";
|
"lng_context_select_msg" = "메시지 선택";
|
||||||
|
"lng_context_pin_msg" = "메시지 고정";
|
||||||
|
"lng_context_unpin_msg" = "메시지 고정해제";
|
||||||
"lng_context_cancel_upload" = "업로드 취소";
|
"lng_context_cancel_upload" = "업로드 취소";
|
||||||
"lng_context_copy_selected" = "선택한 메시지 복사";
|
"lng_context_copy_selected" = "선택한 메시지 복사";
|
||||||
"lng_context_forward_selected" = "선택된 메시지 전달";
|
"lng_context_forward_selected" = "선택된 메시지 전달";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||||
"lng_new_version_text" = "— 채널과 슈퍼그룹에 메시지 수정\n— 메시지 작성란에서 특정 메시지 링크 공유\n— 채널 메시지에 관리자 서명 추가\n— 알림이 가지 않은 채널 메시지 작성. 급하지 않거나 늦은 시간 메시지등에 활용";
|
"lng_new_version_text" = "공개 그룹, 메시지 고정, 5,000명\n\n— 그룹은 5,000명까지 가능 (기존 1,000명)\n— 모든 그룹은 구성원 크기에 상관 없이 슈퍼그룹으로 변환 가능\n\n슈퍼그룹 관리기능 추가:\n\n— 공개링크를 생성하여 그룹공개 가능 - 누구나 참여하여 대화가능\n— 메시지를 고정하여 중요한 내용을 표시하고 모두에게 알림\n— 여러 메시지를 선택하여 삭제, 스팸신고, 차단 혹은 특정 유저에게 메시지 삭제 가능\n\n자세한 사항:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||||
|
|
||||||
|
|
|
@ -111,13 +111,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_status_connecting" = "verbinden";
|
"lng_status_connecting" = "verbinden";
|
||||||
|
|
||||||
"lng_chat_status_unaccessible" = "groep is ontoegankelijk";
|
"lng_chat_status_unaccessible" = "groep is ontoegankelijk";
|
||||||
"lng_chat_status_members" = "{count:geen deelnemers|# deelnemer|# deelnemers}";
|
"lng_chat_status_members" = "{count:geen leden|# lid|# leden}";
|
||||||
"lng_chat_status_members_online" = "{count:_not_used_|# deelnemer|# deelnemers}, {count_online:_not_used_|# online|# online}";
|
"lng_chat_status_members_online" = "{count:_not_used_|# lid|# leden}, {count_online:_not_used_|# online|# online}";
|
||||||
|
|
||||||
"lng_channel_status" = "kanaal";
|
"lng_channel_status" = "kanaal";
|
||||||
"lng_group_status" = "groep";
|
"lng_group_status" = "groep";
|
||||||
|
|
||||||
"lng_channel_members_link" = "{count:_not_used_|# deelnemer|# deelnemers} »";
|
"lng_channel_members_link" = "{count:_not_used_|# lid|# leden} »";
|
||||||
"lng_channel_admins_link" = "{count:Beheerders wijzigen|# beheerders|# beheerders} »";
|
"lng_channel_admins_link" = "{count:Beheerders wijzigen|# beheerders|# beheerders} »";
|
||||||
|
|
||||||
"lng_server_error" = "Interne serverfout.";
|
"lng_server_error" = "Interne serverfout.";
|
||||||
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "Nieuw bericht...";
|
"lng_edit_message_text" = "Nieuw bericht...";
|
||||||
"lng_deleted" = "Onbekend";
|
"lng_deleted" = "Onbekend";
|
||||||
"lng_deleted_message" = "Verwijderd bericht";
|
"lng_deleted_message" = "Verwijderd bericht";
|
||||||
|
"lng_pinned_message" = "Vastgezet bericht";
|
||||||
|
"lng_pinned_unpin_sure" = "Wil je dit bericht losmaken?";
|
||||||
|
"lng_pinned_pin_sure" = "Wil je dit bericht vastzetten?";
|
||||||
|
"lng_pinned_pin" = "Vastzetten";
|
||||||
|
"lng_pinned_unpin" = "Losmaken";
|
||||||
|
"lng_pinned_notify" = "Leden informeren";
|
||||||
|
|
||||||
"lng_intro" = "Welkom bij de officiële [a href=\"https://telegram.org/\"]Telegram[/a] desktop-app.\n[b]Snel[/b] en [b]veilig[/b].";
|
"lng_intro" = "Welkom bij de officiële [a href=\"https://telegram.org/\"]Telegram[/a] desktop-app.\n[b]Snel[/b] en [b]veilig[/b].";
|
||||||
"lng_start_msgs" = "BEGIN MET CHATTEN";
|
"lng_start_msgs" = "BEGIN MET CHATTEN";
|
||||||
|
@ -402,7 +408,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_bot_help" = "Help";
|
"lng_profile_bot_help" = "Help";
|
||||||
"lng_profile_create_public_link" = "Publieke link maken";
|
"lng_profile_create_public_link" = "Publieke link maken";
|
||||||
"lng_profile_edit_public_link" = "Publieke link wijzigen";
|
"lng_profile_edit_public_link" = "Publieke link wijzigen";
|
||||||
"lng_profile_participants_section" = "Deelnemers";
|
"lng_profile_participants_section" = "Leden";
|
||||||
"lng_profile_info" = "Contactinformatie";
|
"lng_profile_info" = "Contactinformatie";
|
||||||
"lng_profile_group_info" = "Groepsinformatie";
|
"lng_profile_group_info" = "Groepsinformatie";
|
||||||
"lng_profile_channel_info" = "Kanaalinformatie";
|
"lng_profile_channel_info" = "Kanaalinformatie";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Lid toevoegen";
|
"lng_profile_add_participant" = "Lid toevoegen";
|
||||||
"lng_profile_delete_and_exit" = "Verlaat";
|
"lng_profile_delete_and_exit" = "Verlaat";
|
||||||
"lng_profile_kick" = "Verwijder";
|
"lng_profile_kick" = "Verwijder";
|
||||||
|
"lng_profile_admin" = "beheerder";
|
||||||
"lng_profile_sure_kick" = "{user} uit de groep verwijderen?";
|
"lng_profile_sure_kick" = "{user} uit de groep verwijderen?";
|
||||||
"lng_profile_sure_kick_channel" = "{user} uit het kanaal verwijderen?";
|
"lng_profile_sure_kick_channel" = "{user} uit het kanaal verwijderen?";
|
||||||
"lng_profile_sure_kick_admin" = "{user} ontslaan als beheerder?";
|
"lng_profile_sure_kick_admin" = "{user} ontslaan als beheerder?";
|
||||||
|
@ -450,34 +457,38 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_copy_phone" = "Telefoonnummer kopiëren";
|
"lng_profile_copy_phone" = "Telefoonnummer kopiëren";
|
||||||
|
|
||||||
"lng_channel_add_admins" = "Beheerder toevoegen";
|
"lng_channel_add_admins" = "Beheerder toevoegen";
|
||||||
"lng_channel_add_members" = "Deelnemers toevoegen";
|
"lng_channel_add_members" = "Leden toevoegen";
|
||||||
"lng_channel_members" = "Deelnemers";
|
"lng_channel_members" = "Leden";
|
||||||
"lng_channel_only_last_shown" = "De laatste {count:_not_used_|# deelnemer|# deelnemers} worden hier weergegeven";
|
"lng_channel_only_last_shown" = "De laatste {count:_not_used_|# lid|# leden} worden hier weergegeven";
|
||||||
"lng_channel_admins" = "Beheerders";
|
"lng_channel_admins" = "Beheerders";
|
||||||
"lng_channel_add_admin" = "Beheerder toevoegen";
|
"lng_channel_add_admin" = "Beheerder toevoegen";
|
||||||
"lng_channel_admin_sure" = "{user} aan beheerders toevoegen?";
|
"lng_channel_admin_sure" = "{user} aan beheerders toevoegen?";
|
||||||
"lng_channel_admins_too_much" = "Je hebt het maximum aantal beheerders voor deze groep bereikt, Verwijder er eerst één.";
|
"lng_channel_admins_too_much" = "Je hebt het maximum aantal beheerders voor deze groep bereikt, Verwijder er eerst één.";
|
||||||
|
|
||||||
"lng_chat_all_members_admins" = "Iedereen is beheerder";
|
"lng_chat_all_members_admins" = "Iedereen is beheerder";
|
||||||
"lng_chat_about_all_admins" = "Iedereen mag deelnemers toevoegen en de groepsfoto of naam wijzigen.";
|
"lng_chat_about_all_admins" = "Iedereen mag leden toevoegen en de groepsfoto of naam wijzigen.";
|
||||||
"lng_chat_about_admins" = "Beheerders mogen deelnemers beheren en de groepsfoto of naam wijzigen.";
|
"lng_chat_about_admins" = "Beheerders mogen leden beheren en de groepsfoto of naam wijzigen.";
|
||||||
|
|
||||||
"lng_participant_filter" = "Zoeken";
|
"lng_participant_filter" = "Zoeken";
|
||||||
"lng_participant_invite" = "Uitnodigen";
|
"lng_participant_invite" = "Uitnodigen";
|
||||||
"lng_participant_invite_sorry" = "De eerste {count:_not_used|# deelnemer|# deelnemers} kun je persoonlijk uitnodigen.\n\nVanaf nu kunnen mensen via de uitnodigingslink deelnemen.";
|
"lng_participant_invite_sorry" = "De eerste {count:_not_used|# lid|# leden} kun je persoonlijk uitnodigen.\n\nVanaf nu kunnen mensen lid worden via de uitnodigingslink.";
|
||||||
"lng_create_group_back" = "Vorige";
|
"lng_create_group_back" = "Vorige";
|
||||||
"lng_create_group_next" = "Volgende";
|
"lng_create_group_next" = "Volgende";
|
||||||
"lng_create_group_create" = "Maak";
|
"lng_create_group_create" = "Maak";
|
||||||
"lng_create_group_title" = "Nieuwe groep";
|
"lng_create_group_title" = "Nieuwe groep";
|
||||||
"lng_create_group_about" = "Groepen zijn voor kleinere gemeenschappen,\nmet maximaal {count:_not_used|# deelnemer|# deelnemers}";
|
"lng_create_group_about" = "Groepen zijn voor beperkte gemeenschappen,\nmet maximaal {count:_not_used|# lid|# leden}";
|
||||||
"lng_create_channel_title" = "Nieuw kanaal";
|
"lng_create_channel_title" = "Nieuw kanaal";
|
||||||
"lng_create_channel_about" = "Kanalen kennen geen limiet en zijn geschikt om een groot publiek te bereiken";
|
"lng_create_channel_about" = "Kanalen kennen geen limiet en zijn geschikt om een groot publiek te bereiken";
|
||||||
"lng_create_public_channel_title" = "Publiek kanaal";
|
"lng_create_public_channel_title" = "Publiek kanaal";
|
||||||
"lng_create_public_channel_about" = "Iedereen kan je kanaal vinden en deelnemen";
|
"lng_create_public_channel_about" = "Iedereen kan je kanaal vinden en er lid van worden";
|
||||||
"lng_create_private_channel_title" = "Privé-kanaal";
|
"lng_create_private_channel_title" = "Privé-kanaal";
|
||||||
"lng_create_private_channel_about" = "Deelnemen kan alleen via de uitnodigingslink";
|
"lng_create_private_channel_about" = "Lid worden kan alleen per uitnodigingslink";
|
||||||
|
"lng_create_public_group_title" = "Publieke groep";
|
||||||
|
"lng_create_public_group_about" = "Iedereen kan de groep vinden, er lid van worden en de geschiedenis zien";
|
||||||
|
"lng_create_private_group_title" = "Privé-groep";
|
||||||
|
"lng_create_private_group_about" = "Lid worden kan alleen op uitnodiging of via uitnodigingslink";
|
||||||
"lng_create_channel_comments" = "Reacties inschakelen";
|
"lng_create_channel_comments" = "Reacties inschakelen";
|
||||||
"lng_create_channel_comments_about" = "Als je reacties inschakelt kunnen deelnemers reageren op je bericht in het kanaal.";
|
"lng_create_channel_comments_about" = "Als je reacties inschakelt kunnen leden reageren op je bericht in het kanaal.";
|
||||||
"lng_create_group_skip" = "Overslaan";
|
"lng_create_group_skip" = "Overslaan";
|
||||||
|
|
||||||
"lng_create_channel_link_invalid" = "Deze naam is ongeldig.";
|
"lng_create_channel_link_invalid" = "Deze naam is ongeldig.";
|
||||||
|
@ -495,13 +506,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_failed_add_not_mutual_channel" = "Iemand die het kanaal verlaat kan alleen door een wederzijds contact worden toegevoegd (opgeslagen nummers)";
|
"lng_failed_add_not_mutual_channel" = "Iemand die het kanaal verlaat kan alleen door een wederzijds contact worden toegevoegd (opgeslagen nummers)";
|
||||||
|
|
||||||
"lng_sure_delete_contact" = "{contact} echt verwijderen uit contacten?";
|
"lng_sure_delete_contact" = "{contact} echt verwijderen uit contacten?";
|
||||||
"lng_sure_delete_history" = "Geschiedenis met {contact} echt wissen? \n\nDeze actie kan niet ongedaan worden gemaakt.";
|
"lng_sure_delete_history" = "Geschiedenis met {contact} echt wissen? \n\nJe kunt dit niet ongedaan maken.";
|
||||||
"lng_sure_delete_group_history" = "Echt de geschiedenis van \"{group}\" wissen?\n\nHerstellen is niet mogelijk. ";
|
"lng_sure_delete_group_history" = "Echt de geschiedenis van \"{group}\" wissen?\n\nJe kunt dit niet ongedaan maken.";
|
||||||
"lng_sure_delete_and_exit" = "Wil je de groep \"{group}\" verlaten en de geschiedenis wissen?\n\nDeze actie kan niet ongedaan worden gemaakt.";
|
"lng_sure_delete_and_exit" = "Wil je de groep \"{group}\" verlaten en de geschiedenis wissen?\n\nJe kunt dit niet ongedaan maken.";
|
||||||
"lng_sure_leave_channel" = "Kanaal echt verlaten?";
|
"lng_sure_leave_channel" = "Kanaal echt verlaten?";
|
||||||
"lng_sure_delete_channel" = "Kanaal echt verwijderen? Berichten worden gewist en alle deelnemers verwijderd.";
|
"lng_sure_delete_channel" = "Kanaal echt verwijderen? Berichten worden gewist en alle leden verwijderd.";
|
||||||
"lng_sure_leave_group" = "Groep echt verlaten?\nDit kan niet ongedaan worden gemaakt.";
|
"lng_sure_leave_group" = "Groep echt verlaten?\nJe kunt dit niet ongedaan maken.";
|
||||||
"lng_sure_delete_group" = "Groep echt verwijderen? Berichten worden gewist en alle deelnemers verwijderd.";
|
"lng_sure_delete_group" = "Groep echt verwijderen? Berichten worden gewist en alle leden verwijderd.";
|
||||||
|
|
||||||
"lng_message_empty" = "Leeg bericht";
|
"lng_message_empty" = "Leeg bericht";
|
||||||
"lng_message_unsupported" = "Dit bericht wordt niet ondersteund door jouw versie van Telegram Desktop. Werk bij naar de laatste versie via de instellingen of installeer vanuit {link}";
|
"lng_message_unsupported" = "Dit bericht wordt niet ondersteund door jouw versie van Telegram Desktop. Werk bij naar de laatste versie via de instellingen of installeer vanuit {link}";
|
||||||
|
@ -511,13 +522,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_add_users_and_one" = "{accumulated}, {user}";
|
"lng_action_add_users_and_one" = "{accumulated}, {user}";
|
||||||
"lng_action_add_users_and_last" = "{accumulated} en {user}";
|
"lng_action_add_users_and_last" = "{accumulated} en {user}";
|
||||||
"lng_action_add_you" = "{from} heeft je toegevoegd aan dit kanaal";
|
"lng_action_add_you" = "{from} heeft je toegevoegd aan dit kanaal";
|
||||||
"lng_action_you_joined" = "Je neemt deel aan het kanaal";
|
"lng_action_you_joined" = "Je bent nu lid van dit kanaal";
|
||||||
"lng_action_add_you_group" = "{from} heeft je toegevoegd aan deze groep";
|
"lng_action_add_you_group" = "{from} heeft je toegevoegd aan deze groep";
|
||||||
"lng_action_you_joined_group" = "Je neemt deel aan de groep";
|
"lng_action_you_joined_group" = "Je bent nu lid van deze groep";
|
||||||
"lng_action_kick_user" = "{from} heeft {user} verwijderd";
|
"lng_action_kick_user" = "{from} heeft {user} verwijderd";
|
||||||
"lng_action_user_left" = "{from} heeft de groep verlaten";
|
"lng_action_user_left" = "{from} heeft de groep verlaten";
|
||||||
"lng_action_user_joined" = "{from} neemt deel aan de groep";
|
"lng_action_user_joined" = "{from} is nu lid van de groep";
|
||||||
"lng_action_user_joined_by_link" = "{from} neemt deel aan de groep via uitnodigingslink";
|
"lng_action_user_joined_by_link" = "{from} is nu lid van de groep via uitnodigingslink";
|
||||||
"lng_action_user_registered" = "{from} heeft nu Telegram";
|
"lng_action_user_registered" = "{from} heeft nu Telegram";
|
||||||
"lng_action_removed_photo" = "{from} heeft de groepsafbeelding verwijderd";
|
"lng_action_removed_photo" = "{from} heeft de groepsafbeelding verwijderd";
|
||||||
"lng_action_removed_photo_channel" = "Kanaalfoto verwijderd";
|
"lng_action_removed_photo_channel" = "Kanaalfoto verwijderd";
|
||||||
|
@ -528,15 +539,36 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} heeft de groep \"{title}\" gemaakt";
|
"lng_action_created_chat" = "{from} heeft de groep \"{title}\" gemaakt";
|
||||||
"lng_action_created_channel" = "Het kanaal \"{title}\" is gemaakt";
|
"lng_action_created_channel" = "Het kanaal \"{title}\" is gemaakt";
|
||||||
"lng_action_group_migrate" = "De groep is opgewaardeerd naar een supergroep";
|
"lng_action_group_migrate" = "De groep is opgewaardeerd naar een supergroep";
|
||||||
|
"lng_action_pinned_message" = "{from} heeft «{text}» vastgezet";
|
||||||
|
"lng_action_pinned_media" = "{from} heeft {media} vastgezet";
|
||||||
|
"lng_action_pinned_media_photo" = "een foto";
|
||||||
|
"lng_action_pinned_media_video" = "een video";
|
||||||
|
"lng_action_pinned_media_audio" = "een audiobestand";
|
||||||
|
"lng_action_pinned_media_voice" = "een spraakbericht";
|
||||||
|
"lng_action_pinned_media_file" = "een bestand";
|
||||||
|
"lng_action_pinned_media_gif" = "een GIF";
|
||||||
|
"lng_action_pinned_media_contact" = "een contact";
|
||||||
|
"lng_action_pinned_media_location" = "een locatie";
|
||||||
|
"lng_action_pinned_media_sticker" = "een sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# deelnemer |# deelnemers} limiet bereikt";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# lid |# leden} limiet bereikt";
|
||||||
"lng_profile_migrate_about" = "Wil je extra functies en een hogere limiet? Waardeer op naar een supergroep:";
|
"lng_profile_migrate_about" = "Wil je extra functies en een hogere limiet? Waardeer op naar een supergroep:";
|
||||||
"lng_profile_migrate_feature1" = "— Supergroepen hebben tot {count:_not_used_|# lid|# leden}";
|
"lng_profile_migrate_feature1" = "— Supergroepen hebben tot {count:_not_used_|# lid|# leden}";
|
||||||
"lng_profile_migrate_feature2" = "— Nieuwe leden zien de hele geschiedenis";
|
"lng_profile_migrate_feature2" = "— Nieuwe leden zien de hele geschiedenis";
|
||||||
"lng_profile_migrate_feature3" = "— Beheerder wist berichten voor iedereen";
|
"lng_profile_migrate_feature3" = "— Beheerder wist berichten voor iedereen";
|
||||||
"lng_profile_migrate_feature4" = "— Meldingen staan standaard uit";
|
"lng_profile_migrate_feature4" = "— Meldingen staan standaard uit";
|
||||||
"lng_profile_migrate_button" = "Opwaarderen naar supergroep.";
|
"lng_profile_migrate_button" = "Opwaarderen naar supergroep.";
|
||||||
"lng_profile_migrate_sure" = "Groep echt omzetten naar supergroep? Dit kan niet ongedaan worden gemaakt.";
|
"lng_profile_migrate_sure" = "Groep echt omzetten naar supergroep? Je kunt dit niet ongedaan maken.";
|
||||||
|
"lng_profile_convert_button" = "Opwaarderen naar supergroep";
|
||||||
|
"lng_profile_convert_title" = "Opwaarderen naar supergroep";
|
||||||
|
"lng_profile_convert_about" = "supergroepen:";
|
||||||
|
"lng_profile_convert_feature1" = "— Nieuwe leden zien de hele geschiedenis";
|
||||||
|
"lng_profile_convert_feature2" = "— Gewiste berichten gelden voor alle leden";
|
||||||
|
"lng_profile_convert_feature3" = "— Leden kunnen eigen berichten bewerken";
|
||||||
|
"lng_profile_convert_feature4" = "— Maker kan een publieke groepslink instellen";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Let op:{bold_end} Je kunt dit niet ongedaan maken.";
|
||||||
|
"lng_profile_convert_confirm" = "Opwaarderen";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "Waardeer op naar een supergroep om tot {count:_not_used_|# lid|# leden} toe te voegen";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# reactie|# reacties}";
|
"lng_channel_comments_count" = "{count:_not_used_|# reactie|# reacties}";
|
||||||
"lng_channel_hide_comments" = "Reacties verbergen";
|
"lng_channel_hide_comments" = "Reacties verbergen";
|
||||||
|
@ -547,17 +579,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_channels_too_much_public" = "Het maximale aantal publieke kanalen is bereikt.\n\nMaak een privé-kanaal \nof verwijder eerst een publiek kanaal.";
|
"lng_channels_too_much_public" = "Het maximale aantal publieke kanalen is bereikt.\n\nMaak een privé-kanaal \nof verwijder eerst een publiek kanaal.";
|
||||||
|
|
||||||
"lng_group_invite_bad_link" = "Deze uitnodigingslink is defect of verlopen.";
|
"lng_group_invite_bad_link" = "Deze uitnodigingslink is defect of verlopen.";
|
||||||
"lng_group_invite_want_join" = "Wil je deelnemen aan de groep \"{title}\"?";
|
"lng_group_invite_want_join" = "Wil je lid worden van de groep \"{title}\"?";
|
||||||
"lng_group_invite_want_join_channel" = "Wil je deelnemen aan het kanaal \"{title}\"?";
|
"lng_group_invite_want_join_channel" = "Wil je lid worden van het kanaal \"{title}\"?";
|
||||||
"lng_group_invite_join" = "Deelnemen";
|
"lng_group_invite_join" = "Lid worden";
|
||||||
|
|
||||||
"lng_group_invite_link" = "Uitnodigingslink:";
|
"lng_group_invite_link" = "Uitnodigingslink:";
|
||||||
"lng_group_invite_create" = "Uitnodigingslink maken";
|
"lng_group_invite_create" = "Uitnodigingslink maken";
|
||||||
"lng_group_invite_about" = "Gebruikers kunnen aan je groep \ndeelnemen met deze link.";
|
"lng_group_invite_about" = "Gebruikers kunnen lid worden\nvan je groep via deze link.";
|
||||||
"lng_group_invite_create_new" = "Intrekken";
|
"lng_group_invite_create_new" = "Intrekken";
|
||||||
"lng_group_invite_about_new" = "Je uitnodigingslink zal inactief worden\neen nieuwe link zal worden gegenereerd.";
|
"lng_group_invite_about_new" = "Je uitnodigingslink zal inactief worden\neen nieuwe link zal worden gegenereerd.";
|
||||||
"lng_group_invite_copied" = "Link gekopieerd naar klembord.";
|
"lng_group_invite_copied" = "Link gekopieerd naar klembord.";
|
||||||
"lng_group_invite_no_room" = "De deelnemerslimiet van de groep is bereikt.";
|
"lng_group_invite_no_room" = "De ledenlimiet van de groep is bereikt.";
|
||||||
|
|
||||||
"lng_channel_public_link_copied" = "Link gekopieerd naar klembord";
|
"lng_channel_public_link_copied" = "Link gekopieerd naar klembord";
|
||||||
|
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Blacklist gebruiker";
|
||||||
|
"lng_delete_all_from" = "Verwijder alles van gebruiker";
|
||||||
"lng_report_spam" = "Spam melden";
|
"lng_report_spam" = "Spam melden";
|
||||||
"lng_report_spam_hide" = "Verbergen";
|
"lng_report_spam_hide" = "Verbergen";
|
||||||
"lng_report_spam_thanks" = "Bedankt!";
|
"lng_report_spam_thanks" = "Bedankt!";
|
||||||
|
@ -657,15 +691,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_broadcast_ph" = "Massabericht";
|
"lng_broadcast_ph" = "Massabericht";
|
||||||
"lng_broadcast_silent_ph" = "Stil massabericht..";
|
"lng_broadcast_silent_ph" = "Stil massabericht..";
|
||||||
"lng_record_cancel" = "Annuleren: uit het vak loslaten";
|
"lng_record_cancel" = "Annuleren: uit het vak loslaten";
|
||||||
"lng_will_be_notified" = "Berichtgeving voor deelnemers";
|
"lng_will_be_notified" = "Berichtgeving voor leden";
|
||||||
"lng_wont_be_notified" = "Geen berichtgeving voor deelnemers";
|
"lng_wont_be_notified" = "Geen berichtgeving voor leden";
|
||||||
"lng_empty_history" = "";
|
"lng_empty_history" = "";
|
||||||
"lng_willbe_history" = "Kies een chat om te beginnen";
|
"lng_willbe_history" = "Kies een chat om te beginnen";
|
||||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||||
"lng_from_you" = "Jij";
|
"lng_from_you" = "Jij";
|
||||||
"lng_bot_description" = "Wat kan deze bot? ";
|
"lng_bot_description" = "Wat kan deze bot? ";
|
||||||
"lng_unblock_button" = "Deblokkeer";
|
"lng_unblock_button" = "Deblokkeer";
|
||||||
"lng_channel_join" = "Deelnemen";
|
"lng_channel_join" = "Lid worden";
|
||||||
"lng_channel_mute" = "Geluid uit";
|
"lng_channel_mute" = "Geluid uit";
|
||||||
"lng_channel_unmute" = "Geluid aan";
|
"lng_channel_unmute" = "Geluid aan";
|
||||||
|
|
||||||
|
@ -677,7 +711,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_bot_no_groups" = "Je hebt geen groepen";
|
"lng_bot_no_groups" = "Je hebt geen groepen";
|
||||||
"lng_bot_groups_not_found" = "Geen groepen gevonden";
|
"lng_bot_groups_not_found" = "Geen groepen gevonden";
|
||||||
"lng_bot_sure_invite" = "De bot toevoegen aan \"{group}\"?";
|
"lng_bot_sure_invite" = "De bot toevoegen aan \"{group}\"?";
|
||||||
"lng_bot_already_in_group" = "De bot neemt al deel aan de groep.";
|
"lng_bot_already_in_group" = "Deze bot is al een groepslid.";
|
||||||
|
|
||||||
"lng_typing" = "aan het typen";
|
"lng_typing" = "aan het typen";
|
||||||
"lng_user_typing" = "{user} is aan het typen";
|
"lng_user_typing" = "{user} is aan het typen";
|
||||||
|
@ -717,7 +751,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_view_channel" = "Kanaalinformatie weergeven";
|
"lng_context_view_channel" = "Kanaalinformatie weergeven";
|
||||||
|
|
||||||
"lng_context_copy_link" = "Link kopiëren";
|
"lng_context_copy_link" = "Link kopiëren";
|
||||||
"lng_context_copy_post_link" = "Link kopiëren";
|
"lng_context_copy_post_link" = "Berichtlink kopiëren";
|
||||||
"lng_context_copy_email" = "E-mailadres kopiëren";
|
"lng_context_copy_email" = "E-mailadres kopiëren";
|
||||||
"lng_context_copy_hashtag" = "Hashtag kopiëren";
|
"lng_context_copy_hashtag" = "Hashtag kopiëren";
|
||||||
"lng_context_copy_mention" = "Gebruikersnaam kopiëren";
|
"lng_context_copy_mention" = "Gebruikersnaam kopiëren";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Bericht doorsturen";
|
"lng_context_forward_msg" = "Bericht doorsturen";
|
||||||
"lng_context_delete_msg" = "Bericht verwijderen";
|
"lng_context_delete_msg" = "Bericht verwijderen";
|
||||||
"lng_context_select_msg" = "Bericht kiezen";
|
"lng_context_select_msg" = "Bericht kiezen";
|
||||||
|
"lng_context_pin_msg" = "Bericht vastzetten";
|
||||||
|
"lng_context_unpin_msg" = "Bericht losmaken";
|
||||||
"lng_context_cancel_upload" = "Upload annuleren";
|
"lng_context_cancel_upload" = "Upload annuleren";
|
||||||
"lng_context_copy_selected" = "Tekstselectie kopiëren";
|
"lng_context_copy_selected" = "Tekstselectie kopiëren";
|
||||||
"lng_context_forward_selected" = "Selectie doorsturen";
|
"lng_context_forward_selected" = "Selectie doorsturen";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
||||||
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||||
"lng_new_version_text" = "— Bewerk nu je berichten in kanalen en supergroepen.\n— Deel links naar specifieke berichten in kanalen via het contextmenu.\n— Onderteken berichten in kanalen.\n— Stuur 'stille berichten' in kanalen. Ideaal voor als je toch echt iets moet sturen in het holst van de nacht.";
|
"lng_new_version_text" = "PUBLIEKE GROEPEN, BERICHTEN VASTZETTEN, 5000 LEDEN\n\n— Ledenlimiet voor iedere groepsvorm opgehoogd naar 5000 (voorheen 1000).\n— Iedere groep met een willekeurig aantal leden kan nu worden opgewaardeerd naar een supergroep.\n\nNieuwe functies voor beheerders van supergroepen:\n\n— Maak je groep openbaar door een publieke link in te stellen - iedereen kan de chat zien en er lid van worden.\n— Zet berichten vast om belangrijke informatie weer te geven en alle leden te informeren.\n— Selecteer berichten om te verwijderen, ze als spam te melden, gebruikers te blokkeren of om alle berichten van bepaalde gebruikers ineens te verwijderen.\n\nMeer informatie over deze update:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_message_text" = "Nova mensagem...";
|
"lng_edit_message_text" = "Nova mensagem...";
|
||||||
"lng_deleted" = "Desconhecido";
|
"lng_deleted" = "Desconhecido";
|
||||||
"lng_deleted_message" = "Mensagem apagada";
|
"lng_deleted_message" = "Mensagem apagada";
|
||||||
|
"lng_pinned_message" = "Mensagem fixada";
|
||||||
|
"lng_pinned_unpin_sure" = "Você gostaria de desafixar essa mensagem?";
|
||||||
|
"lng_pinned_pin_sure" = "Você gostaria de fixar essa mensagem?";
|
||||||
|
"lng_pinned_pin" = "Fixar";
|
||||||
|
"lng_pinned_unpin" = "Desafixar";
|
||||||
|
"lng_pinned_notify" = "Notificar todos os membros";
|
||||||
|
|
||||||
"lng_intro" = "Bem vindo ao cliente oficial do [a href=\"https://telegram.org/\"]Telegram[/a].\nÉ [b]rápido[/b] e [b]seguro[/b].";
|
"lng_intro" = "Bem vindo ao cliente oficial do [a href=\"https://telegram.org/\"]Telegram[/a].\nÉ [b]rápido[/b] e [b]seguro[/b].";
|
||||||
"lng_start_msgs" = "COMECE A CONVERSAR";
|
"lng_start_msgs" = "COMECE A CONVERSAR";
|
||||||
|
@ -429,6 +435,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Adicionar Membros";
|
"lng_profile_add_participant" = "Adicionar Membros";
|
||||||
"lng_profile_delete_and_exit" = "Sair";
|
"lng_profile_delete_and_exit" = "Sair";
|
||||||
"lng_profile_kick" = "Remover";
|
"lng_profile_kick" = "Remover";
|
||||||
|
"lng_profile_admin" = "administrador";
|
||||||
"lng_profile_sure_kick" = "Remover {user} do grupo?";
|
"lng_profile_sure_kick" = "Remover {user} do grupo?";
|
||||||
"lng_profile_sure_kick_channel" = "Remover {user} do canal?";
|
"lng_profile_sure_kick_channel" = "Remover {user} do canal?";
|
||||||
"lng_profile_sure_kick_admin" = "Remover {user} dos administradores?";
|
"lng_profile_sure_kick_admin" = "Remover {user} dos administradores?";
|
||||||
|
@ -469,13 +476,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Próximo";
|
"lng_create_group_next" = "Próximo";
|
||||||
"lng_create_group_create" = "Criar";
|
"lng_create_group_create" = "Criar";
|
||||||
"lng_create_group_title" = "Novo Grupo";
|
"lng_create_group_title" = "Novo Grupo";
|
||||||
"lng_create_group_about" = "Grupos são ideais para comunidades menores,\ncom até {count:_not_used|# membro|# membros}";
|
"lng_create_group_about" = "Grupos são ideais para comunidades limitadas,\neles podem conter até {count:_not_used|# membro|# membros}";
|
||||||
"lng_create_channel_title" = "Novo Canal";
|
"lng_create_channel_title" = "Novo Canal";
|
||||||
"lng_create_channel_about" = "Canais são uma ferramenta para transmitir suas mensagens para audiências ilimitadas";
|
"lng_create_channel_about" = "Canais são uma ferramenta para transmitir suas mensagens para audiências ilimitadas";
|
||||||
"lng_create_public_channel_title" = "Canal Público";
|
"lng_create_public_channel_title" = "Canal Público";
|
||||||
"lng_create_public_channel_about" = "Qualquer um pode encontrar o canal na busca e entrar";
|
"lng_create_public_channel_about" = "Qualquer um pode encontrar o canal na busca e entrar";
|
||||||
"lng_create_private_channel_title" = "Canal privado";
|
"lng_create_private_channel_title" = "Canal privado";
|
||||||
"lng_create_private_channel_about" = "Somente pessoas com um link especial de convite poderão entrar";
|
"lng_create_private_channel_about" = "Somente pessoas com um link especial de convite poderão entrar";
|
||||||
|
"lng_create_public_group_title" = "Grupo Público";
|
||||||
|
"lng_create_public_group_about" = "Qualquer um pode encontrar o grupo pela busca e entrar, todo o histórico estará disponível";
|
||||||
|
"lng_create_private_group_title" = "Grupo Privado";
|
||||||
|
"lng_create_private_group_about" = "Somente pessoas convidadas ou com link de convite podem entrar";
|
||||||
"lng_create_channel_comments" = "Habilitar Comentários";
|
"lng_create_channel_comments" = "Habilitar Comentários";
|
||||||
"lng_create_channel_comments_about" = "Se você habilitar comentários, membros poderão discutir seus posts no canal";
|
"lng_create_channel_comments_about" = "Se você habilitar comentários, membros poderão discutir seus posts no canal";
|
||||||
"lng_create_group_skip" = "Pular";
|
"lng_create_group_skip" = "Pular";
|
||||||
|
@ -528,6 +539,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} criou o grupo «{title}»";
|
"lng_action_created_chat" = "{from} criou o grupo «{title}»";
|
||||||
"lng_action_created_channel" = "Canal «{title}» criado";
|
"lng_action_created_channel" = "Canal «{title}» criado";
|
||||||
"lng_action_group_migrate" = "O grupo foi atualizado para um supergrupo";
|
"lng_action_group_migrate" = "O grupo foi atualizado para um supergrupo";
|
||||||
|
"lng_action_pinned_message" = "{from} fixou «{text}»";
|
||||||
|
"lng_action_pinned_media" = "{from} fixou {media}";
|
||||||
|
"lng_action_pinned_media_photo" = "uma foto";
|
||||||
|
"lng_action_pinned_media_video" = "um vídeo";
|
||||||
|
"lng_action_pinned_media_audio" = "um áudio";
|
||||||
|
"lng_action_pinned_media_voice" = "uma mensagem de voz";
|
||||||
|
"lng_action_pinned_media_file" = "um arquivo";
|
||||||
|
"lng_action_pinned_media_gif" = "um GIF";
|
||||||
|
"lng_action_pinned_media_contact" = "um contato";
|
||||||
|
"lng_action_pinned_media_location" = "uma localização";
|
||||||
|
"lng_action_pinned_media_sticker" = "um sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# membro|# membros} limite alcançado";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# membro|# membros} limite alcançado";
|
||||||
"lng_profile_migrate_about" = "Se você deseja ir além do limite, pode converter seu grupo em um supergrupo. Nos supergrupos:";
|
"lng_profile_migrate_about" = "Se você deseja ir além do limite, pode converter seu grupo em um supergrupo. Nos supergrupos:";
|
||||||
|
@ -537,6 +559,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— Notificações silenciadas por padrão";
|
"lng_profile_migrate_feature4" = "— Notificações silenciadas por padrão";
|
||||||
"lng_profile_migrate_button" = "Atualizar para supergrupo";
|
"lng_profile_migrate_button" = "Atualizar para supergrupo";
|
||||||
"lng_profile_migrate_sure" = "Tem certeza que deseja converter esse grupo para um supergrupo? Essa ação não pode ser desfeita.";
|
"lng_profile_migrate_sure" = "Tem certeza que deseja converter esse grupo para um supergrupo? Essa ação não pode ser desfeita.";
|
||||||
|
"lng_profile_convert_button" = "Converter a Supergrupo";
|
||||||
|
"lng_profile_convert_title" = "Converter a Supergrupo";
|
||||||
|
"lng_profile_convert_about" = "Em supergrupos:";
|
||||||
|
"lng_profile_convert_feature1" = "— Novos membros podem ver todo o histórico";
|
||||||
|
"lng_profile_convert_feature2" = "— Mensagens apagadas desaparecerão para todos";
|
||||||
|
"lng_profile_convert_feature3" = "— Membros podem editar as próprias mensagens";
|
||||||
|
"lng_profile_convert_feature4" = "— Criador pode definir um link público para o grupo";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Nota:{bold_end} Essa ação não pode ser desfeita";
|
||||||
|
"lng_profile_convert_confirm" = "Converter";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "Você pode adicionar até {count:_not_used_|# membro|# membros} depois de atualizar seu grupo para um supergrupo.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# comentário|# comentários}";
|
"lng_channel_comments_count" = "{count:_not_used_|# comentário|# comentários}";
|
||||||
"lng_channel_hide_comments" = "Ocultar Comentários";
|
"lng_channel_hide_comments" = "Ocultar Comentários";
|
||||||
|
@ -563,8 +595,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_forwarded" = "Encaminhado de {user}";
|
"lng_forwarded" = "Encaminhado de {user}";
|
||||||
"lng_forwarded_channel" = "Encaminhado de {channel}";
|
"lng_forwarded_channel" = "Encaminhado de {channel}";
|
||||||
"lng_forwarded_via" = "Encaminhado de {user} via {online_bot}";
|
"lng_forwarded_via" = "Encaminhado de {user} via {inline_bot}";
|
||||||
"lng_forwarded_channel_via" = "Encaminhado de {channel} via {online_bot}";
|
"lng_forwarded_channel_via" = "Encaminhado de {channel} via {inline_bot}";
|
||||||
"lng_forwarded_signed" = "{channel} ({user})";
|
"lng_forwarded_signed" = "{channel} ({user})";
|
||||||
"lng_in_reply_to" = "Em resposta a";
|
"lng_in_reply_to" = "Em resposta a";
|
||||||
|
|
||||||
|
@ -637,6 +669,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Banir Usuário";
|
||||||
|
"lng_delete_all_from" = "Apagar tudo deste usuário";
|
||||||
"lng_report_spam" = "Reportar Spam";
|
"lng_report_spam" = "Reportar Spam";
|
||||||
"lng_report_spam_hide" = "Ocultar";
|
"lng_report_spam_hide" = "Ocultar";
|
||||||
"lng_report_spam_thanks" = "Obrigado por reportar!";
|
"lng_report_spam_thanks" = "Obrigado por reportar!";
|
||||||
|
@ -745,6 +779,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_msg" = "Encaminhar Mensagem";
|
"lng_context_forward_msg" = "Encaminhar Mensagem";
|
||||||
"lng_context_delete_msg" = "Apagar Mensagem";
|
"lng_context_delete_msg" = "Apagar Mensagem";
|
||||||
"lng_context_select_msg" = "Selecionar Mensagem";
|
"lng_context_select_msg" = "Selecionar Mensagem";
|
||||||
|
"lng_context_pin_msg" = "Fixar Mensagem";
|
||||||
|
"lng_context_unpin_msg" = "Desafixar Mensagem";
|
||||||
"lng_context_cancel_upload" = "Cancelar Envio";
|
"lng_context_cancel_upload" = "Cancelar Envio";
|
||||||
"lng_context_copy_selected" = "Copiar Texto Selecionado";
|
"lng_context_copy_selected" = "Copiar Texto Selecionado";
|
||||||
"lng_context_forward_selected" = "Encaminhar Selecionado";
|
"lng_context_forward_selected" = "Encaminhar Selecionado";
|
||||||
|
@ -844,7 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
||||||
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
|
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
|
||||||
"lng_new_version_text" = "— Edite suas mensagens em canais e supergrupos.\n— Compartilhe links para postagens específicas nos canais pelo menu de contexto do post.\n— Adicione assinaturas de administradores nas mensagens dos canais.\n— Envie mensagens silenciosas em canais, que não notificarão os membros. Útil para mensagens não urgentes ou enviadas tarde da noite.";
|
"lng_new_version_text" = "GRUPOS PÚBLICOS, POSTS FIXADOS, 5.000 MEMBROS\n\n— Grupos agora podem ter até 5.000 membros (mais que 1.000)\n— Grupos de qualquer tamanho podem ser convertidos a supergrupos\n\nNovas ferramentas para administradores dos supergrupos:\n\n— Torne seu grupo público configurando um link público - qualquer um poderá ver a conversa e entrar nela\n— Fixe mensagens para manter as atualizações mais importantes visíveis e notificar todos os membros\n— Selecione várias mensagens para apagar, reporte por spam, bloqueie usuários ou remova todas as mensagens de certos usuários\n\nMais sobre essa atualização:\n{link}";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||||
|
|
||||||
|
|
|
@ -556,6 +556,69 @@ namespace {
|
||||||
lskSavedGifs = 0x0f, // no data
|
lskSavedGifs = 0x0f, // no data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
dbiKey = 0x00,
|
||||||
|
dbiUser = 0x01,
|
||||||
|
dbiDcOptionOld = 0x02,
|
||||||
|
dbiChatSizeMax = 0x03,
|
||||||
|
dbiMutePeer = 0x04,
|
||||||
|
dbiSendKey = 0x05,
|
||||||
|
dbiAutoStart = 0x06,
|
||||||
|
dbiStartMinimized = 0x07,
|
||||||
|
dbiSoundNotify = 0x08,
|
||||||
|
dbiWorkMode = 0x09,
|
||||||
|
dbiSeenTrayTooltip = 0x0a,
|
||||||
|
dbiDesktopNotify = 0x0b,
|
||||||
|
dbiAutoUpdate = 0x0c,
|
||||||
|
dbiLastUpdateCheck = 0x0d,
|
||||||
|
dbiWindowPosition = 0x0e,
|
||||||
|
dbiConnectionType = 0x0f,
|
||||||
|
// 0x10 reserved
|
||||||
|
dbiDefaultAttach = 0x11,
|
||||||
|
dbiCatsAndDogs = 0x12,
|
||||||
|
dbiReplaceEmojis = 0x13,
|
||||||
|
dbiAskDownloadPath = 0x14,
|
||||||
|
dbiDownloadPathOld = 0x15,
|
||||||
|
dbiScale = 0x16,
|
||||||
|
dbiEmojiTabOld = 0x17,
|
||||||
|
dbiRecentEmojisOld = 0x18,
|
||||||
|
dbiLoggedPhoneNumber = 0x19,
|
||||||
|
dbiMutedPeers = 0x1a,
|
||||||
|
// 0x1b reserved
|
||||||
|
dbiNotifyView = 0x1c,
|
||||||
|
dbiSendToMenu = 0x1d,
|
||||||
|
dbiCompressPastedImage = 0x1e,
|
||||||
|
dbiLang = 0x1f,
|
||||||
|
dbiLangFile = 0x20,
|
||||||
|
dbiTileBackground = 0x21,
|
||||||
|
dbiAutoLock = 0x22,
|
||||||
|
dbiDialogLastPath = 0x23,
|
||||||
|
dbiRecentEmojis = 0x24,
|
||||||
|
dbiEmojiVariants = 0x25,
|
||||||
|
dbiRecentStickers = 0x26,
|
||||||
|
dbiDcOption = 0x27,
|
||||||
|
dbiTryIPv6 = 0x28,
|
||||||
|
dbiSongVolume = 0x29,
|
||||||
|
dbiWindowsNotifications = 0x30,
|
||||||
|
dbiIncludeMuted = 0x31,
|
||||||
|
dbiMegagroupSizeMax = 0x32,
|
||||||
|
dbiDownloadPath = 0x33,
|
||||||
|
dbiAutoDownload = 0x34,
|
||||||
|
dbiSavedGifsLimit = 0x35,
|
||||||
|
dbiShowingSavedGifs = 0x36,
|
||||||
|
dbiAutoPlay = 0x37,
|
||||||
|
dbiAdaptiveForWide = 0x38,
|
||||||
|
dbiHiddenPinnedMessages = 0x39,
|
||||||
|
|
||||||
|
dbiEncryptedWithSalt = 333,
|
||||||
|
dbiEncrypted = 444,
|
||||||
|
|
||||||
|
// 500-600 reserved
|
||||||
|
|
||||||
|
dbiVersion = 666,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef QMap<PeerId, FileKey> DraftsMap;
|
typedef QMap<PeerId, FileKey> DraftsMap;
|
||||||
DraftsMap _draftsMap, _draftCursorsMap;
|
DraftsMap _draftsMap, _draftCursorsMap;
|
||||||
typedef QMap<PeerId, bool> DraftsNotReadMap;
|
typedef QMap<PeerId, bool> DraftsNotReadMap;
|
||||||
|
@ -1266,6 +1329,15 @@ namespace {
|
||||||
cSetEmojiVariants(v);
|
cSetEmojiVariants(v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
|
case dbiHiddenPinnedMessages: {
|
||||||
|
Global::HiddenPinnedMessagesMap v;
|
||||||
|
stream >> v;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
Global::SetHiddenPinnedMessages(v);
|
||||||
|
} break;
|
||||||
|
|
||||||
case dbiDialogLastPath: {
|
case dbiDialogLastPath: {
|
||||||
QString path;
|
QString path;
|
||||||
stream >> path;
|
stream >> path;
|
||||||
|
@ -1510,6 +1582,9 @@ namespace {
|
||||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||||
size += sizeof(quint32) + _stringSize(cDialogLastPath());
|
size += sizeof(quint32) + _stringSize(cDialogLastPath());
|
||||||
size += sizeof(quint32) + 3 * sizeof(qint32);
|
size += sizeof(quint32) + 3 * sizeof(qint32);
|
||||||
|
if (!Global::HiddenPinnedMessages().isEmpty()) {
|
||||||
|
size += sizeof(quint32) + sizeof(qint32) + Global::HiddenPinnedMessages().size() * (sizeof(PeerId) + sizeof(MsgId));
|
||||||
|
}
|
||||||
|
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter);
|
data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter);
|
||||||
|
@ -1553,6 +1628,9 @@ namespace {
|
||||||
}
|
}
|
||||||
data.stream << quint32(dbiRecentStickers) << v;
|
data.stream << quint32(dbiRecentStickers) << v;
|
||||||
}
|
}
|
||||||
|
if (!Global::HiddenPinnedMessages().isEmpty()) {
|
||||||
|
data.stream << quint32(dbiHiddenPinnedMessages) << Global::HiddenPinnedMessages();
|
||||||
|
}
|
||||||
|
|
||||||
FileWriteDescriptor file(_userSettingsKey);
|
FileWriteDescriptor file(_userSettingsKey);
|
||||||
file.writeEncrypted(data);
|
file.writeEncrypted(data);
|
||||||
|
|
|
@ -607,7 +607,7 @@ void _moveOldDataFiles(const QString &wasDir) {
|
||||||
namespace SignalHandlers {
|
namespace SignalHandlers {
|
||||||
|
|
||||||
QString CrashDumpPath;
|
QString CrashDumpPath;
|
||||||
FILE *CrashDumpFile = 0;
|
FILE *CrashDumpFile = nullptr;
|
||||||
int CrashDumpFileNo = 0;
|
int CrashDumpFileNo = 0;
|
||||||
char LaunchedDateTimeStr[32] = { 0 };
|
char LaunchedDateTimeStr[32] = { 0 };
|
||||||
char LaunchedBinaryName[256] = { 0 };
|
char LaunchedBinaryName[256] = { 0 };
|
||||||
|
@ -739,8 +739,8 @@ namespace SignalHandlers {
|
||||||
if (!LoggingCrashHeaderWritten) {
|
if (!LoggingCrashHeaderWritten) {
|
||||||
LoggingCrashHeaderWritten = true;
|
LoggingCrashHeaderWritten = true;
|
||||||
const AnnotationsMap c_ProcessAnnotations(ProcessAnnotations);
|
const AnnotationsMap c_ProcessAnnotations(ProcessAnnotations);
|
||||||
for (AnnotationsMap::const_iterator i = c_ProcessAnnotations.begin(), e = c_ProcessAnnotations.end(); i != e; ++i) {
|
for (const auto &i : c_ProcessAnnotations) {
|
||||||
dump() << i->first.c_str() << ": " << i->second.c_str() << "\n";
|
dump() << i.first.c_str() << ": " << i.second.c_str() << "\n";
|
||||||
}
|
}
|
||||||
psWriteDump();
|
psWriteDump();
|
||||||
dump() << "\n";
|
dump() << "\n";
|
||||||
|
@ -835,6 +835,7 @@ namespace SignalHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetSignalHandlers = true;
|
bool SetSignalHandlers = true;
|
||||||
|
bool CrashLogged = false;
|
||||||
#if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD
|
#if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD
|
||||||
google_breakpad::ExceptionHandler* BreakpadExceptionHandler = 0;
|
google_breakpad::ExceptionHandler* BreakpadExceptionHandler = 0;
|
||||||
|
|
||||||
|
@ -846,6 +847,9 @@ namespace SignalHandlers {
|
||||||
bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success)
|
bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
if (CrashLogged) return success;
|
||||||
|
CrashLogged = true;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
BreakpadDumpPathW = _minidump_id;
|
BreakpadDumpPathW = _minidump_id;
|
||||||
Handler(-1);
|
Handler(-1);
|
||||||
|
@ -938,9 +942,9 @@ namespace SignalHandlers {
|
||||||
if (FILE *f = fopen(QFile::encodeName(CrashDumpPath).constData(), "rb")) {
|
if (FILE *f = fopen(QFile::encodeName(CrashDumpPath).constData(), "rb")) {
|
||||||
#endif
|
#endif
|
||||||
QByteArray lastdump;
|
QByteArray lastdump;
|
||||||
char buffer[64 * 1024] = { 0 };
|
char buffer[256 * 1024] = { 0 };
|
||||||
int32 read = 0;
|
int32 read = fread(buffer, 1, 256 * 1024, f);
|
||||||
while ((read = fread(buffer, 1, 64 * 1024, f)) > 0) {
|
if (read > 0) {
|
||||||
lastdump.append(buffer, read);
|
lastdump.append(buffer, read);
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -999,6 +1003,8 @@ namespace SignalHandlers {
|
||||||
FinishBreakpad();
|
FinishBreakpad();
|
||||||
if (CrashDumpFile) {
|
if (CrashDumpFile) {
|
||||||
fclose(CrashDumpFile);
|
fclose(CrashDumpFile);
|
||||||
|
CrashDumpFile = nullptr;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
_wunlink(CrashDumpPath.toStdWString().c_str());
|
_wunlink(CrashDumpPath.toStdWString().c_str());
|
||||||
#else
|
#else
|
||||||
|
@ -1007,4 +1013,12 @@ namespace SignalHandlers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSelfUsername(const QString &username) {
|
||||||
|
if (username.trimmed().isEmpty()) {
|
||||||
|
ProcessAnnotations.erase("Username");
|
||||||
|
} else {
|
||||||
|
ProcessAnnotations["Username"] = username.toUtf8().constData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,4 +107,6 @@ namespace SignalHandlers {
|
||||||
Status restart(); // can be only CantOpen or Started
|
Status restart(); // can be only CantOpen or Started
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
|
void setSelfUsername(const QString &username);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,6 +431,7 @@ MainWidget::MainWidget(Window *window) : TWidget(window)
|
||||||
connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
|
connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
|
||||||
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||||
connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeByPts()));
|
connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeByPts()));
|
||||||
|
connect(&_byMinChannelTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||||
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeAfterFail()));
|
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeAfterFail()));
|
||||||
connect(_api, SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
connect(_api, SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
||||||
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
||||||
|
@ -907,6 +908,14 @@ void MainWidget::forwardLayer(int32 forwardSelected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::deleteLayer(int32 selectedCount) {
|
void MainWidget::deleteLayer(int32 selectedCount) {
|
||||||
|
if (selectedCount == -1 && !overview) {
|
||||||
|
if (auto item = App::contextItem()) {
|
||||||
|
if (item->suggestBanReportDeleteAll()) {
|
||||||
|
Ui::showLayer(new RichDeleteMessageBox(item->history()->peer->asChannel(), item->from()->asUser(), item->id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
QString str((selectedCount < 0) ? lang(selectedCount < -1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, selectedCount));
|
QString str((selectedCount < 0) ? lang(selectedCount < -1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, selectedCount));
|
||||||
QString btn(lang((selectedCount < -1) ? lng_selected_upload_stop : lng_box_delete)), cancel(lang((selectedCount < -1) ? lng_continue : lng_cancel));
|
QString btn(lang((selectedCount < -1) ? lng_selected_upload_stop : lng_box_delete)), cancel(lang((selectedCount < -1) ? lng_continue : lng_cancel));
|
||||||
ConfirmBox *box = new ConfirmBox(str, btn, st::defaultBoxButton, cancel);
|
ConfirmBox *box = new ConfirmBox(str, btn, st::defaultBoxButton, cancel);
|
||||||
|
@ -982,9 +991,16 @@ void MainWidget::deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updat
|
||||||
|
|
||||||
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||||
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
||||||
if (ptsUpdated(d.vpts.v, d.vpts_count.v)) {
|
if (peer && peer->isChannel()) {
|
||||||
ptsApplySkippedUpdates();
|
if (peer->asChannel()->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
App::emitPeerUpdated();
|
peer->asChannel()->ptsApplySkippedUpdates();
|
||||||
|
App::emitPeerUpdated();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ptsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
|
ptsApplySkippedUpdates();
|
||||||
|
App::emitPeerUpdated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 offset = d.voffset.v;
|
int32 offset = d.voffset.v;
|
||||||
|
@ -1047,6 +1063,45 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::deleteAllFromUser(ChannelData *channel, UserData *from) {
|
||||||
|
t_assert(channel != nullptr && from != nullptr);
|
||||||
|
|
||||||
|
QVector<MsgId> toDestroy;
|
||||||
|
if (auto history = App::historyLoaded(channel->id)) {
|
||||||
|
for (auto i = history->blocks.cbegin(), e = history->blocks.cend(); i != e; ++i) {
|
||||||
|
for (auto j = (*i)->items.cbegin(), n = (*i)->items.cend(); j != n; ++j) {
|
||||||
|
if ((*j)->from() == from && (*j)->type() == HistoryItemMsg && (*j)->canDelete()) {
|
||||||
|
toDestroy.push_back((*j)->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto i = toDestroy.cbegin(), e = toDestroy.cend(); i != e; ++i) {
|
||||||
|
if (auto item = App::histItemById(peerToChannel(channel->id), *i)) {
|
||||||
|
item->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MTP::send(MTPchannels_DeleteUserHistory(channel->inputChannel, from->inputUser), rpcDone(&MainWidget::deleteAllFromUserPart, { channel, from }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::deleteAllFromUserPart(DeleteAllFromUserParams params, const MTPmessages_AffectedHistory &result) {
|
||||||
|
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
||||||
|
if (params.channel->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
|
params.channel->ptsApplySkippedUpdates();
|
||||||
|
App::emitPeerUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 offset = d.voffset.v;
|
||||||
|
if (!MTP::authedId()) return;
|
||||||
|
if (offset > 0) {
|
||||||
|
MTP::send(MTPchannels_DeleteUserHistory(params.channel->inputChannel, params.from->inputUser), rpcDone(&MainWidget::deleteAllFromUserPart, params));
|
||||||
|
} else if (auto h = App::historyLoaded(params.channel)) {
|
||||||
|
if (!h->lastMsg) {
|
||||||
|
checkPeerHistory(params.channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::clearHistory(PeerData *peer) {
|
void MainWidget::clearHistory(PeerData *peer) {
|
||||||
if (History *h = App::historyLoaded(peer->id)) {
|
if (History *h = App::historyLoaded(peer->id)) {
|
||||||
if (h->lastMsg) {
|
if (h->lastMsg) {
|
||||||
|
@ -1510,7 +1565,6 @@ void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::itemRemoved(HistoryItem *item) {
|
void MainWidget::itemRemoved(HistoryItem *item) {
|
||||||
api()->itemRemoved(item);
|
|
||||||
dialogs.itemRemoved(item);
|
dialogs.itemRemoved(item);
|
||||||
if (history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) {
|
if (history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) {
|
||||||
history.itemRemoved(item);
|
history.itemRemoved(item);
|
||||||
|
@ -1533,6 +1587,12 @@ void MainWidget::itemRemoved(HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::itemEdited(HistoryItem *item) {
|
||||||
|
if (history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) {
|
||||||
|
history.itemEdited(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MainWidget::overviewFailed(PeerData *peer, const RPCError &error, mtpRequestId req) {
|
bool MainWidget::overviewFailed(PeerData *peer, const RPCError &error, mtpRequestId req) {
|
||||||
if (mtpIsFlood(error)) return false;
|
if (mtpIsFlood(error)) return false;
|
||||||
|
|
||||||
|
@ -2056,8 +2116,8 @@ ApiWrap *MainWidget::api() {
|
||||||
return _api;
|
return _api;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateReplyTo() {
|
void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||||
history.updateReplyEditTexts(true);
|
history.messageDataReceived(channel, msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateBotKeyboard(History *h) {
|
void MainWidget::updateBotKeyboard(History *h) {
|
||||||
|
@ -2901,8 +2961,12 @@ bool MainWidget::updateFail(const RPCError &e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
||||||
if (pts) _ptsWaiter.init(pts);
|
if (pts) {
|
||||||
if (updDate < date) updDate = date;
|
_ptsWaiter.init(pts);
|
||||||
|
}
|
||||||
|
if (updDate < date && !_byMinChannelTimer.isActive()) {
|
||||||
|
updDate = date;
|
||||||
|
}
|
||||||
if (qts && updQts < qts) {
|
if (qts && updQts < qts) {
|
||||||
updQts = qts;
|
updQts = qts;
|
||||||
}
|
}
|
||||||
|
@ -4493,7 +4557,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
case mtpc_updateNewChannelMessage: {
|
case mtpc_updateNewChannelMessage: {
|
||||||
const MTPDupdateNewChannelMessage &d(update.c_updateNewChannelMessage());
|
const MTPDupdateNewChannelMessage &d(update.c_updateNewChannelMessage());
|
||||||
ChannelData *channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage)));
|
ChannelData *channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage)));
|
||||||
|
if (!channel && !_ptsWaiter.requesting()) {
|
||||||
|
MTP_LOG(0, ("getDifference { good - after no channel in updateNewChannelMessage }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||||
|
if (!_byMinChannelTimer.isActive()) { // getDifference after timeout
|
||||||
|
_byMinChannelTimer.start(WaitForSkippedTimeout);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (channel && !_handlingChannelDifference) {
|
if (channel && !_handlingChannelDifference) {
|
||||||
if (channel->ptsRequesting()) { // skip global updates while getting channel difference
|
if (channel->ptsRequesting()) { // skip global updates while getting channel difference
|
||||||
return;
|
return;
|
||||||
|
@ -4542,6 +4612,19 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case mtpc_updateChannelPinnedMessage: {
|
||||||
|
const MTPDupdateChannelPinnedMessage &d(update.c_updateChannelPinnedMessage());
|
||||||
|
|
||||||
|
if (ChannelData *channel = App::channelLoaded(d.vchannel_id.v)) {
|
||||||
|
if (channel->isMegagroup()) {
|
||||||
|
channel->mgInfo->pinnedMsgId = d.vid.v;
|
||||||
|
if (App::api()) {
|
||||||
|
emit App::api()->fullPeerUpdated(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case mtpc_updateReadChannelInbox: {
|
case mtpc_updateReadChannelInbox: {
|
||||||
const MTPDupdateReadChannelInbox &d(update.c_updateReadChannelInbox());
|
const MTPDupdateReadChannelInbox &d(update.c_updateReadChannelInbox());
|
||||||
ChannelData *channel = App::channelLoaded(d.vchannel_id.v);
|
ChannelData *channel = App::channelLoaded(d.vchannel_id.v);
|
||||||
|
@ -4578,7 +4661,9 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
case mtpc_updateChannelTooLong: {
|
case mtpc_updateChannelTooLong: {
|
||||||
const MTPDupdateChannelTooLong &d(update.c_updateChannelTooLong());
|
const MTPDupdateChannelTooLong &d(update.c_updateChannelTooLong());
|
||||||
if (ChannelData *channel = App::channelLoaded(d.vchannel_id.v)) {
|
if (ChannelData *channel = App::channelLoaded(d.vchannel_id.v)) {
|
||||||
getChannelDifference(channel);
|
if (!d.has_pts() || channel->pts() < d.vpts.v) {
|
||||||
|
getChannelDifference(channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -306,11 +306,11 @@ public:
|
||||||
|
|
||||||
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
||||||
void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
|
void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
|
||||||
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
|
||||||
void deleteMessages(PeerData *peer, const QVector<MTPint> &ids);
|
void deleteMessages(PeerData *peer, const QVector<MTPint> &ids);
|
||||||
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
||||||
void deleteConversation(PeerData *peer, bool deleteHistory = true);
|
void deleteConversation(PeerData *peer, bool deleteHistory = true);
|
||||||
void clearHistory(PeerData *peer);
|
void clearHistory(PeerData *peer);
|
||||||
|
void deleteAllFromUser(ChannelData *channel, UserData *from);
|
||||||
|
|
||||||
void addParticipants(PeerData *chatOrChannel, const QVector<UserData*> &users);
|
void addParticipants(PeerData *chatOrChannel, const QVector<UserData*> &users);
|
||||||
bool addParticipantFail(UserData *user, const RPCError &e);
|
bool addParticipantFail(UserData *user, const RPCError &e);
|
||||||
|
@ -348,6 +348,7 @@ public:
|
||||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||||
void itemRemoved(HistoryItem *item);
|
void itemRemoved(HistoryItem *item);
|
||||||
|
void itemEdited(HistoryItem *item);
|
||||||
|
|
||||||
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
||||||
void peerUsernameChanged(PeerData *peer);
|
void peerUsernameChanged(PeerData *peer);
|
||||||
|
@ -373,7 +374,7 @@ public:
|
||||||
ImagePtr newBackgroundThumb();
|
ImagePtr newBackgroundThumb();
|
||||||
|
|
||||||
ApiWrap *api();
|
ApiWrap *api();
|
||||||
void updateReplyTo();
|
void messageDataReceived(ChannelData *channel, MsgId msgId);
|
||||||
void updateBotKeyboard(History *h);
|
void updateBotKeyboard(History *h);
|
||||||
|
|
||||||
void pushReplyReturn(HistoryItem *item);
|
void pushReplyReturn(HistoryItem *item);
|
||||||
|
@ -561,6 +562,13 @@ private:
|
||||||
void feedUpdateVector(const MTPVector<MTPUpdate> &updates, bool skipMessageIds = false);
|
void feedUpdateVector(const MTPVector<MTPUpdate> &updates, bool skipMessageIds = false);
|
||||||
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
|
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
|
||||||
|
|
||||||
|
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
||||||
|
struct DeleteAllFromUserParams {
|
||||||
|
ChannelData *channel;
|
||||||
|
UserData *from;
|
||||||
|
};
|
||||||
|
void deleteAllFromUserPart(DeleteAllFromUserParams params, const MTPmessages_AffectedHistory &result);
|
||||||
|
|
||||||
void updateReceived(const mtpPrime *from, const mtpPrime *end);
|
void updateReceived(const mtpPrime *from, const mtpPrime *end);
|
||||||
bool updateFail(const RPCError &e);
|
bool updateFail(const RPCError &e);
|
||||||
|
|
||||||
|
@ -624,6 +632,8 @@ private:
|
||||||
QMap<int32, MTPUpdates> _bySeqUpdates;
|
QMap<int32, MTPUpdates> _bySeqUpdates;
|
||||||
SingleTimer _bySeqTimer;
|
SingleTimer _bySeqTimer;
|
||||||
|
|
||||||
|
SingleTimer _byMinChannelTimer;
|
||||||
|
|
||||||
mtpRequestId _onlineRequest;
|
mtpRequestId _onlineRequest;
|
||||||
SingleTimer _onlineTimer, _onlineUpdater, _idleFinishTimer;
|
SingleTimer _onlineTimer, _onlineUpdater, _idleFinishTimer;
|
||||||
bool _lastWasOnline;
|
bool _lastWasOnline;
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ void MTProtoConnectionPrivate::createConn(bool createIPv4, bool createIPv6) {
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
||||||
if (conn) {
|
if (conn) {
|
||||||
MTPabstractConnection *toDisconnect = 0;
|
MTPabstractConnection *toDisconnect = nullptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&stateConnMutex);
|
QWriteLocker lock(&stateConnMutex);
|
||||||
|
@ -1305,7 +1305,7 @@ void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
||||||
disconnect(*conn, SIGNAL(error(bool)), 0, 0);
|
disconnect(*conn, SIGNAL(error(bool)), 0, 0);
|
||||||
disconnect(*conn, SIGNAL(receivedData()), 0, 0);
|
disconnect(*conn, SIGNAL(receivedData()), 0, 0);
|
||||||
disconnect(*conn, SIGNAL(receivedSome()), 0, 0);
|
disconnect(*conn, SIGNAL(receivedSome()), 0, 0);
|
||||||
*conn = 0;
|
*conn = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (toDisconnect) {
|
if (toDisconnect) {
|
||||||
|
@ -1315,7 +1315,7 @@ void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
||||||
} else {
|
} else {
|
||||||
destroyConn(&_conn4);
|
destroyConn(&_conn4);
|
||||||
destroyConn(&_conn6);
|
destroyConn(&_conn6);
|
||||||
_conn = 0;
|
_conn = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,9 +1324,9 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
|
||||||
, _needSessionReset(false)
|
, _needSessionReset(false)
|
||||||
, dc(_dc)
|
, dc(_dc)
|
||||||
, _owner(owner)
|
, _owner(owner)
|
||||||
, _conn(0)
|
, _conn(nullptr)
|
||||||
, _conn4(0)
|
, _conn4(nullptr)
|
||||||
, _conn6(0)
|
, _conn6(nullptr)
|
||||||
, retryTimeout(1)
|
, retryTimeout(1)
|
||||||
, oldConnection(true)
|
, oldConnection(true)
|
||||||
, _waitForReceived(MTPMinReceiveDelay)
|
, _waitForReceived(MTPMinReceiveDelay)
|
||||||
|
@ -2072,17 +2072,17 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
||||||
if (!noIPv6) DEBUG_LOG(("MTP Info: creating IPv6 connection to [%1]:%2 (tcp) and [%3]:%4 (http)..").arg(ip[IPv6address][TcpProtocol].c_str()).arg(port[IPv6address][TcpProtocol]).arg(ip[IPv4address][HttpProtocol].c_str()).arg(port[IPv4address][HttpProtocol]));
|
if (!noIPv6) DEBUG_LOG(("MTP Info: creating IPv6 connection to [%1]:%2 (tcp) and [%3]:%4 (http)..").arg(ip[IPv6address][TcpProtocol].c_str()).arg(port[IPv6address][TcpProtocol]).arg(ip[IPv4address][HttpProtocol].c_str()).arg(port[IPv4address][HttpProtocol]));
|
||||||
|
|
||||||
_waitForConnectedTimer.start(_waitForConnected);
|
_waitForConnectedTimer.start(_waitForConnected);
|
||||||
if (_conn4) {
|
if (auto conn = _conn4) {
|
||||||
connect(_conn4, SIGNAL(connected()), this, SLOT(onConnected4()));
|
connect(conn, SIGNAL(connected()), this, SLOT(onConnected4()));
|
||||||
connect(_conn4, SIGNAL(disconnected()), this, SLOT(onDisconnected4()));
|
connect(conn, SIGNAL(disconnected()), this, SLOT(onDisconnected4()));
|
||||||
_conn4->connectTcp(ip[IPv4address][TcpProtocol].c_str(), port[IPv4address][TcpProtocol], flags[IPv4address][TcpProtocol]);
|
conn->connectTcp(ip[IPv4address][TcpProtocol].c_str(), port[IPv4address][TcpProtocol], flags[IPv4address][TcpProtocol]);
|
||||||
_conn4->connectHttp(ip[IPv4address][HttpProtocol].c_str(), port[IPv4address][HttpProtocol], flags[IPv4address][HttpProtocol]);
|
conn->connectHttp(ip[IPv4address][HttpProtocol].c_str(), port[IPv4address][HttpProtocol], flags[IPv4address][HttpProtocol]);
|
||||||
}
|
}
|
||||||
if (_conn6) {
|
if (auto conn = _conn6) {
|
||||||
connect(_conn6, SIGNAL(connected()), this, SLOT(onConnected6()));
|
connect(conn, SIGNAL(connected()), this, SLOT(onConnected6()));
|
||||||
connect(_conn6, SIGNAL(disconnected()), this, SLOT(onDisconnected6()));
|
connect(conn, SIGNAL(disconnected()), this, SLOT(onDisconnected6()));
|
||||||
_conn6->connectTcp(ip[IPv6address][TcpProtocol].c_str(), port[IPv6address][TcpProtocol], flags[IPv6address][TcpProtocol]);
|
conn->connectTcp(ip[IPv6address][TcpProtocol].c_str(), port[IPv6address][TcpProtocol], flags[IPv6address][TcpProtocol]);
|
||||||
_conn6->connectHttp(ip[IPv6address][HttpProtocol].c_str(), port[IPv6address][HttpProtocol], flags[IPv6address][HttpProtocol]);
|
conn->connectHttp(ip[IPv6address][HttpProtocol].c_str(), port[IPv6address][HttpProtocol], flags[IPv6address][HttpProtocol]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||||
mtpTypeId(mtpc_invokeWithLayer18),
|
mtpTypeId(mtpc_invokeWithLayer18),
|
||||||
};
|
};
|
||||||
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||||
static const mtpPrime mtpCurrentLayer = 48;
|
static const mtpPrime mtpCurrentLayer = 49;
|
||||||
|
|
||||||
template <typename bareT>
|
template <typename bareT>
|
||||||
class MTPBoxed : public bareT {
|
class MTPBoxed : public bareT {
|
||||||
|
|
|
@ -1157,14 +1157,15 @@ void _serialize_channel(MTPStringLogger &to, int32 stage, int32 lev, Types &type
|
||||||
case 9: to.add(" restricted: "); ++stages.back(); if (flag & MTPDchannel::flag_restricted) { to.add("YES [ BY BIT 9 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
case 9: to.add(" restricted: "); ++stages.back(); if (flag & MTPDchannel::flag_restricted) { to.add("YES [ BY BIT 9 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||||
case 10: to.add(" democracy: "); ++stages.back(); if (flag & MTPDchannel::flag_democracy) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break;
|
case 10: to.add(" democracy: "); ++stages.back(); if (flag & MTPDchannel::flag_democracy) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break;
|
||||||
case 11: to.add(" signatures: "); ++stages.back(); if (flag & MTPDchannel::flag_signatures) { to.add("YES [ BY BIT 11 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break;
|
case 11: to.add(" signatures: "); ++stages.back(); if (flag & MTPDchannel::flag_signatures) { to.add("YES [ BY BIT 11 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 11 IN FIELD flags ]"); } break;
|
||||||
case 12: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 12: to.add(" min: "); ++stages.back(); if (flag & MTPDchannel::flag_min) { to.add("YES [ BY BIT 12 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 12 IN FIELD flags ]"); } break;
|
||||||
case 13: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 13: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 14: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 14: to.add(" access_hash: "); ++stages.back(); if (flag & MTPDchannel::flag_access_hash) { types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 13 IN FIELD flags ]"); } break;
|
||||||
case 15: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
case 15: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 16: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 16: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||||
case 17: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 17: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 18: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 18: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 19: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
case 19: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 20: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1212,20 +1213,22 @@ void _serialize_channelFull(MTPStringLogger &to, int32 stage, int32 lev, Types &
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" can_view_participants: "); ++stages.back(); if (flag & MTPDchannelFull::flag_can_view_participants) { to.add("YES [ BY BIT 3 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
case 1: to.add(" can_view_participants: "); ++stages.back(); if (flag & MTPDchannelFull::flag_can_view_participants) { to.add("YES [ BY BIT 3 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||||
case 2: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" can_set_username: "); ++stages.back(); if (flag & MTPDchannelFull::flag_can_set_username) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||||
case 3: to.add(" about: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 3: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 4: to.add(" participants_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_participants_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
case 4: to.add(" about: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 5: to.add(" admins_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_admins_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
case 5: to.add(" participants_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_participants_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
case 6: to.add(" kicked_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_kicked_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
case 6: to.add(" admins_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_admins_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||||
case 7: to.add(" read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 7: to.add(" kicked_count: "); ++stages.back(); if (flag & MTPDchannelFull::flag_kicked_count) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||||
case 8: to.add(" unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 8: to.add(" read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 9: to.add(" unread_important_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 9: to.add(" unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 10: to.add(" chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 10: to.add(" unread_important_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 11: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 11: to.add(" chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 12: to.add(" exported_invite: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 12: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 13: to.add(" bot_info: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 13: to.add(" exported_invite: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 14: to.add(" migrated_from_chat_id: "); ++stages.back(); if (flag & MTPDchannelFull::flag_migrated_from_chat_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
case 14: to.add(" bot_info: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 15: to.add(" migrated_from_max_id: "); ++stages.back(); if (flag & MTPDchannelFull::flag_migrated_from_max_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
case 15: to.add(" migrated_from_chat_id: "); ++stages.back(); if (flag & MTPDchannelFull::flag_migrated_from_chat_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
||||||
|
case 16: to.add(" migrated_from_max_id: "); ++stages.back(); if (flag & MTPDchannelFull::flag_migrated_from_max_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
||||||
|
case 17: to.add(" pinned_msg_id: "); ++stages.back(); if (flag & MTPDchannelFull::flag_pinned_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1384,8 +1387,9 @@ void _serialize_messageService(MTPStringLogger &to, int32 stage, int32 lev, Type
|
||||||
case 7: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 7: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 8: to.add(" from_id: "); ++stages.back(); if (flag & MTPDmessageService::flag_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
case 8: to.add(" from_id: "); ++stages.back(); if (flag & MTPDmessageService::flag_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
||||||
case 9: to.add(" to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 9: to.add(" to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 10: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 10: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDmessageService::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||||
case 11: to.add(" action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 11: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 12: to.add(" action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1612,6 +1616,10 @@ void _serialize_messageActionChannelMigrateFrom(MTPStringLogger &to, int32 stage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_messageActionPinMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ messageActionPinMessage }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_dialog(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_dialog(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -1894,6 +1902,20 @@ void _serialize_peerNotifySettings(MTPStringLogger &to, int32 stage, int32 lev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_peerSettings(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ peerSettings");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" report_spam: "); ++stages.back(); if (flag & MTPDpeerSettings::flag_report_spam) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_wallPaper(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_wallPaper(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -1959,12 +1981,14 @@ void _serialize_userFull(MTPStringLogger &to, int32 stage, int32 lev, Types &typ
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" blocked: "); ++stages.back(); if (flag & MTPDuserFull::flag_blocked) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
case 2: to.add(" profile_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 3: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 3: to.add(" about: "); ++stages.back(); if (flag & MTPDuserFull::flag_about) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||||
case 4: to.add(" blocked: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 4: to.add(" link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 5: to.add(" bot_info: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 5: to.add(" profile_photo: "); ++stages.back(); if (flag & MTPDuserFull::flag_profile_photo) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||||
|
case 6: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 7: to.add(" bot_info: "); ++stages.back(); if (flag & MTPDuserFull::flag_bot_info) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2688,7 +2712,9 @@ void _serialize_updateChannelTooLong(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 2: to.add(" pts: "); ++stages.back(); if (flag & MTPDupdateChannelTooLong::flag_pts) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2891,6 +2917,20 @@ void _serialize_updateEditChannelMessage(MTPStringLogger &to, int32 stage, int32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_updateChannelPinnedMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ updateChannelPinnedMessage");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -4304,10 +4344,6 @@ void _serialize_botCommand(MTPStringLogger &to, int32 stage, int32 lev, Types &t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_botInfoEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
to.add("{ botInfoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_botInfo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_botInfo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -4317,10 +4353,8 @@ void _serialize_botInfo(MTPStringLogger &to, int32 stage, int32 lev, Types &type
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" description: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 2: to.add(" share_text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" commands: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 3: to.add(" description: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 4: to.add(" commands: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5558,6 +5592,19 @@ void _serialize_messages_reportSpam(MTPStringLogger &to, int32 stage, int32 lev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_messages_hideReportSpam(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ messages_hideReportSpam");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_messages_discardEncryption(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_messages_discardEncryption(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -6031,8 +6078,10 @@ void _serialize_account_updateProfile(MTPStringLogger &to, int32 stage, int32 le
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" first_name: "); ++stages.back(); if (flag & MTPaccount_updateProfile::flag_first_name) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
|
case 2: to.add(" last_name: "); ++stages.back(); if (flag & MTPaccount_updateProfile::flag_last_name) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||||
|
case 3: to.add(" about: "); ++stages.back(); if (flag & MTPaccount_updateProfile::flag_about) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6937,6 +6986,35 @@ void _serialize_channels_editMessage(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_channels_updatePinnedMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ channels_updatePinnedMessage");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" silent: "); ++stages.back(); if (flag & MTPchannels_updatePinnedMessage::flag_silent) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
|
case 2: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 3: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_messages_getPeerSettings(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ messages_getPeerSettings");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -7656,6 +7734,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_messageActionChannelCreate, _serialize_messageActionChannelCreate);
|
_serializers.insert(mtpc_messageActionChannelCreate, _serialize_messageActionChannelCreate);
|
||||||
_serializers.insert(mtpc_messageActionChatMigrateTo, _serialize_messageActionChatMigrateTo);
|
_serializers.insert(mtpc_messageActionChatMigrateTo, _serialize_messageActionChatMigrateTo);
|
||||||
_serializers.insert(mtpc_messageActionChannelMigrateFrom, _serialize_messageActionChannelMigrateFrom);
|
_serializers.insert(mtpc_messageActionChannelMigrateFrom, _serialize_messageActionChannelMigrateFrom);
|
||||||
|
_serializers.insert(mtpc_messageActionPinMessage, _serialize_messageActionPinMessage);
|
||||||
_serializers.insert(mtpc_dialog, _serialize_dialog);
|
_serializers.insert(mtpc_dialog, _serialize_dialog);
|
||||||
_serializers.insert(mtpc_dialogChannel, _serialize_dialogChannel);
|
_serializers.insert(mtpc_dialogChannel, _serialize_dialogChannel);
|
||||||
_serializers.insert(mtpc_photoEmpty, _serialize_photoEmpty);
|
_serializers.insert(mtpc_photoEmpty, _serialize_photoEmpty);
|
||||||
|
@ -7681,6 +7760,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_peerNotifyEventsAll, _serialize_peerNotifyEventsAll);
|
_serializers.insert(mtpc_peerNotifyEventsAll, _serialize_peerNotifyEventsAll);
|
||||||
_serializers.insert(mtpc_peerNotifySettingsEmpty, _serialize_peerNotifySettingsEmpty);
|
_serializers.insert(mtpc_peerNotifySettingsEmpty, _serialize_peerNotifySettingsEmpty);
|
||||||
_serializers.insert(mtpc_peerNotifySettings, _serialize_peerNotifySettings);
|
_serializers.insert(mtpc_peerNotifySettings, _serialize_peerNotifySettings);
|
||||||
|
_serializers.insert(mtpc_peerSettings, _serialize_peerSettings);
|
||||||
_serializers.insert(mtpc_wallPaper, _serialize_wallPaper);
|
_serializers.insert(mtpc_wallPaper, _serialize_wallPaper);
|
||||||
_serializers.insert(mtpc_wallPaperSolid, _serialize_wallPaperSolid);
|
_serializers.insert(mtpc_wallPaperSolid, _serialize_wallPaperSolid);
|
||||||
_serializers.insert(mtpc_inputReportReasonSpam, _serialize_inputReportReasonSpam);
|
_serializers.insert(mtpc_inputReportReasonSpam, _serialize_inputReportReasonSpam);
|
||||||
|
@ -7760,6 +7840,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_updateBotInlineQuery, _serialize_updateBotInlineQuery);
|
_serializers.insert(mtpc_updateBotInlineQuery, _serialize_updateBotInlineQuery);
|
||||||
_serializers.insert(mtpc_updateBotInlineSend, _serialize_updateBotInlineSend);
|
_serializers.insert(mtpc_updateBotInlineSend, _serialize_updateBotInlineSend);
|
||||||
_serializers.insert(mtpc_updateEditChannelMessage, _serialize_updateEditChannelMessage);
|
_serializers.insert(mtpc_updateEditChannelMessage, _serialize_updateEditChannelMessage);
|
||||||
|
_serializers.insert(mtpc_updateChannelPinnedMessage, _serialize_updateChannelPinnedMessage);
|
||||||
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
||||||
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
||||||
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
||||||
|
@ -7876,7 +7957,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_stickerSet, _serialize_stickerSet);
|
_serializers.insert(mtpc_stickerSet, _serialize_stickerSet);
|
||||||
_serializers.insert(mtpc_messages_stickerSet, _serialize_messages_stickerSet);
|
_serializers.insert(mtpc_messages_stickerSet, _serialize_messages_stickerSet);
|
||||||
_serializers.insert(mtpc_botCommand, _serialize_botCommand);
|
_serializers.insert(mtpc_botCommand, _serialize_botCommand);
|
||||||
_serializers.insert(mtpc_botInfoEmpty, _serialize_botInfoEmpty);
|
|
||||||
_serializers.insert(mtpc_botInfo, _serialize_botInfo);
|
_serializers.insert(mtpc_botInfo, _serialize_botInfo);
|
||||||
_serializers.insert(mtpc_keyboardButton, _serialize_keyboardButton);
|
_serializers.insert(mtpc_keyboardButton, _serialize_keyboardButton);
|
||||||
_serializers.insert(mtpc_keyboardButtonRow, _serialize_keyboardButtonRow);
|
_serializers.insert(mtpc_keyboardButtonRow, _serialize_keyboardButtonRow);
|
||||||
|
@ -7973,6 +8053,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_contacts_unblock, _serialize_contacts_unblock);
|
_serializers.insert(mtpc_contacts_unblock, _serialize_contacts_unblock);
|
||||||
_serializers.insert(mtpc_messages_setTyping, _serialize_messages_setTyping);
|
_serializers.insert(mtpc_messages_setTyping, _serialize_messages_setTyping);
|
||||||
_serializers.insert(mtpc_messages_reportSpam, _serialize_messages_reportSpam);
|
_serializers.insert(mtpc_messages_reportSpam, _serialize_messages_reportSpam);
|
||||||
|
_serializers.insert(mtpc_messages_hideReportSpam, _serialize_messages_hideReportSpam);
|
||||||
_serializers.insert(mtpc_messages_discardEncryption, _serialize_messages_discardEncryption);
|
_serializers.insert(mtpc_messages_discardEncryption, _serialize_messages_discardEncryption);
|
||||||
_serializers.insert(mtpc_messages_setEncryptedTyping, _serialize_messages_setEncryptedTyping);
|
_serializers.insert(mtpc_messages_setEncryptedTyping, _serialize_messages_setEncryptedTyping);
|
||||||
_serializers.insert(mtpc_messages_readEncryptedHistory, _serialize_messages_readEncryptedHistory);
|
_serializers.insert(mtpc_messages_readEncryptedHistory, _serialize_messages_readEncryptedHistory);
|
||||||
|
@ -8072,6 +8153,8 @@ namespace {
|
||||||
_serializers.insert(mtpc_channels_toggleInvites, _serialize_channels_toggleInvites);
|
_serializers.insert(mtpc_channels_toggleInvites, _serialize_channels_toggleInvites);
|
||||||
_serializers.insert(mtpc_channels_toggleSignatures, _serialize_channels_toggleSignatures);
|
_serializers.insert(mtpc_channels_toggleSignatures, _serialize_channels_toggleSignatures);
|
||||||
_serializers.insert(mtpc_channels_editMessage, _serialize_channels_editMessage);
|
_serializers.insert(mtpc_channels_editMessage, _serialize_channels_editMessage);
|
||||||
|
_serializers.insert(mtpc_channels_updatePinnedMessage, _serialize_channels_updatePinnedMessage);
|
||||||
|
_serializers.insert(mtpc_messages_getPeerSettings, _serialize_messages_getPeerSettings);
|
||||||
_serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats);
|
_serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats);
|
||||||
_serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels);
|
_serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels);
|
||||||
_serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat);
|
_serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -209,11 +209,11 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
||||||
chatEmpty#9ba2d800 id:int = Chat;
|
chatEmpty#9ba2d800 id:int = Chat;
|
||||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||||
chatForbidden#7328bdb id:int title:string = Chat;
|
chatForbidden#7328bdb id:int title:string = Chat;
|
||||||
channel#4b1b7506 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat;
|
channel#a14dca52 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat;
|
||||||
channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
|
channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
|
||||||
|
|
||||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||||
channelFull#9e341ddf flags:# can_view_participants:flags.3?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int read_inbox_max_id:int unread_count:int unread_important_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int = ChatFull;
|
channelFull#97bee562 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int read_inbox_max_id:int unread_count:int unread_important_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int = ChatFull;
|
||||||
|
|
||||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||||
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
||||||
|
@ -227,7 +227,7 @@ chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||||
|
|
||||||
messageEmpty#83e5de54 id:int = Message;
|
messageEmpty#83e5de54 id:int = Message;
|
||||||
message#c09be45f flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int = Message;
|
message#c09be45f flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int = Message;
|
||||||
messageService#c06b9607 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer date:int action:MessageAction = Message;
|
messageService#9e19a1f6 flags:# unread:flags.0?true out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||||
|
|
||||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||||
messageMediaPhoto#3d8ce53d photo:Photo caption:string = MessageMedia;
|
messageMediaPhoto#3d8ce53d photo:Photo caption:string = MessageMedia;
|
||||||
|
@ -249,6 +249,7 @@ messageActionChatJoinedByLink#f89cf5e8 inviter_id:int = MessageAction;
|
||||||
messageActionChannelCreate#95d2ac92 title:string = MessageAction;
|
messageActionChannelCreate#95d2ac92 title:string = MessageAction;
|
||||||
messageActionChatMigrateTo#51bdb021 channel_id:int = MessageAction;
|
messageActionChatMigrateTo#51bdb021 channel_id:int = MessageAction;
|
||||||
messageActionChannelMigrateFrom#b055eaee title:string chat_id:int = MessageAction;
|
messageActionChannelMigrateFrom#b055eaee title:string chat_id:int = MessageAction;
|
||||||
|
messageActionPinMessage#94bd38ed = MessageAction;
|
||||||
|
|
||||||
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
|
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
|
||||||
dialogChannel#5b8496b2 peer:Peer top_message:int top_important_message:int read_inbox_max_id:int unread_count:int unread_important_count:int notify_settings:PeerNotifySettings pts:int = Dialog;
|
dialogChannel#5b8496b2 peer:Peer top_message:int top_important_message:int read_inbox_max_id:int unread_count:int unread_important_count:int notify_settings:PeerNotifySettings pts:int = Dialog;
|
||||||
|
@ -288,6 +289,8 @@ peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
|
||||||
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
|
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
|
||||||
peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings;
|
peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings;
|
||||||
|
|
||||||
|
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
|
||||||
|
|
||||||
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
||||||
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
||||||
|
|
||||||
|
@ -296,7 +299,7 @@ inputReportReasonViolence#1e22c78d = ReportReason;
|
||||||
inputReportReasonPornography#2e59d922 = ReportReason;
|
inputReportReasonPornography#2e59d922 = ReportReason;
|
||||||
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||||
|
|
||||||
userFull#5a89ac5b user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool bot_info:BotInfo = UserFull;
|
userFull#5932fc03 flags:# blocked:flags.0?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo = UserFull;
|
||||||
|
|
||||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||||
|
|
||||||
|
@ -368,7 +371,7 @@ updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Upd
|
||||||
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
|
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
|
||||||
updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update;
|
updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update;
|
||||||
updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
|
updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
|
||||||
updateChannelTooLong#60946422 channel_id:int = Update;
|
updateChannelTooLong#eb0467fb flags:# channel_id:int pts:flags.0?int = Update;
|
||||||
updateChannel#b6d45656 channel_id:int = Update;
|
updateChannel#b6d45656 channel_id:int = Update;
|
||||||
updateChannelGroup#c36c1e3c channel_id:int group:MessageGroup = Update;
|
updateChannelGroup#c36c1e3c channel_id:int group:MessageGroup = Update;
|
||||||
updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
|
updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
|
||||||
|
@ -384,6 +387,7 @@ updateSavedGifs#9375341e = Update;
|
||||||
updateBotInlineQuery#c01eea08 query_id:long user_id:int query:string offset:string = Update;
|
updateBotInlineQuery#c01eea08 query_id:long user_id:int query:string offset:string = Update;
|
||||||
updateBotInlineSend#f69e113 user_id:int query:string id:string = Update;
|
updateBotInlineSend#f69e113 user_id:int query:string id:string = Update;
|
||||||
updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
|
updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
|
||||||
|
updateChannelPinnedMessage#98592475 channel_id:int id:int = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
|
@ -553,8 +557,7 @@ messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:
|
||||||
|
|
||||||
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
||||||
|
|
||||||
botInfoEmpty#bb2e37ce = BotInfo;
|
botInfo#98e81d3a user_id:int description:string commands:Vector<BotCommand> = BotInfo;
|
||||||
botInfo#9cf585d user_id:int version:int share_text:string description:string commands:Vector<BotCommand> = BotInfo;
|
|
||||||
|
|
||||||
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
||||||
|
|
||||||
|
@ -676,7 +679,7 @@ account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
|
||||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||||
account.resetNotifySettings#db7e1747 = Bool;
|
account.resetNotifySettings#db7e1747 = Bool;
|
||||||
account.updateProfile#f0888d68 first_name:string last_name:string = User;
|
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
|
||||||
account.updateStatus#6628562c offline:Bool = Bool;
|
account.updateStatus#6628562c offline:Bool = Bool;
|
||||||
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
||||||
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
|
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
|
||||||
|
@ -725,6 +728,8 @@ messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true broadcast:flags.4?
|
||||||
messages.sendMedia#c8f16791 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
messages.sendMedia#c8f16791 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||||
messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
|
messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
|
||||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||||
|
messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
|
||||||
|
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
|
||||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||||
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
|
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
|
||||||
|
@ -821,3 +826,4 @@ channels.exportMessageLink#c846d22d channel:InputChannel id:int = ExportedMessag
|
||||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.getMessageEditData#27ea3a28 channel:InputChannel id:int = channels.MessageEditData;
|
channels.getMessageEditData#27ea3a28 channel:InputChannel id:int = channels.MessageEditData;
|
||||||
channels.editMessage#dcda80ed flags:# no_webpage:flags.1?true channel:InputChannel id:int message:string entities:flags.3?Vector<MessageEntity> = Updates;
|
channels.editMessage#dcda80ed flags:# no_webpage:flags.1?true channel:InputChannel id:int message:string entities:flags.3?Vector<MessageEntity> = Updates;
|
||||||
|
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||||
|
|
|
@ -58,6 +58,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
, _invitationLink(this, qsl("telegram.me/joinchat/"))
|
, _invitationLink(this, qsl("telegram.me/joinchat/"))
|
||||||
, _botSettings(this, lang(lng_profile_bot_settings))
|
, _botSettings(this, lang(lng_profile_bot_settings))
|
||||||
, _botHelp(this, lang(lng_profile_bot_help))
|
, _botHelp(this, lang(lng_profile_bot_help))
|
||||||
|
, _pinnedMessage(this, lang(lng_pinned_message))
|
||||||
, _username(this, (_peerChannel && _peerChannel->isPublic()) ? (qsl("telegram.me/") + _peerChannel->username) : lang(lng_profile_create_public_link))
|
, _username(this, (_peerChannel && _peerChannel->isPublic()) ? (qsl("telegram.me/") + _peerChannel->username) : lang(lng_profile_create_public_link))
|
||||||
, _members(this, lng_channel_members_link(lt_count, (_peerChannel && _peerChannel->count > 0) ? _peerChannel->count : 1))
|
, _members(this, lng_channel_members_link(lt_count, (_peerChannel && _peerChannel->count > 0) ? _peerChannel->count : 1))
|
||||||
, _admins(this, lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled()) ? (_peerChat->admins.size() + 1) : 0))))
|
, _admins(this, lng_channel_admins_link(lt_count, (_peerChannel ? (_peerChannel->adminsCount > 0 ? _peerChannel->adminsCount : 1) : ((_peerChat && _peerChat->adminsEnabled()) ? (_peerChat->admins.size() + 1) : 0))))
|
||||||
|
@ -85,6 +86,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
, _searchInPeer(this, lang(lng_profile_search_messages))
|
, _searchInPeer(this, lang(lng_profile_search_messages))
|
||||||
|
, _convertToSupergroup(this, lang(lng_profile_convert_button))
|
||||||
, _clearHistory(this, lang(lng_profile_clear_history))
|
, _clearHistory(this, lang(lng_profile_clear_history))
|
||||||
, _deleteConversation(this, lang(_peer->isUser() ? lng_profile_delete_conversation : (_peer->isChat() ? lng_profile_clear_and_exit : (_peer->isMegagroup() ? lng_profile_leave_group : lng_profile_leave_channel))))
|
, _deleteConversation(this, lang(_peer->isUser() ? lng_profile_delete_conversation : (_peer->isChat() ? lng_profile_clear_and_exit : (_peer->isMegagroup() ? lng_profile_leave_group : lng_profile_leave_channel))))
|
||||||
, _wasBlocked(_peerUser ? _peerUser->blocked : UserBlockUnknown)
|
, _wasBlocked(_peerUser ? _peerUser->blocked : UserBlockUnknown)
|
||||||
|
@ -102,7 +104,8 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
, _kickDown(0)
|
, _kickDown(0)
|
||||||
, _kickConfirm(0)
|
, _kickConfirm(0)
|
||||||
|
|
||||||
, _menu(0) {
|
, _menu(0)
|
||||||
|
, _updateDelayed(false) {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
|
|
||||||
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
||||||
|
@ -178,6 +181,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
|
|
||||||
connect(&_botSettings, SIGNAL(clicked()), this, SLOT(onBotSettings()));
|
connect(&_botSettings, SIGNAL(clicked()), this, SLOT(onBotSettings()));
|
||||||
connect(&_botHelp, SIGNAL(clicked()), this, SLOT(onBotHelp()));
|
connect(&_botHelp, SIGNAL(clicked()), this, SLOT(onBotHelp()));
|
||||||
|
connect(&_pinnedMessage, SIGNAL(clicked()), this, SLOT(onPinnedMessage()));
|
||||||
|
|
||||||
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUpdateDone(PeerId)));
|
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUpdateDone(PeerId)));
|
||||||
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUpdateFail(PeerId)));
|
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUpdateFail(PeerId)));
|
||||||
|
@ -187,9 +191,9 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
connect(App::main(), SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(peerUpdated(PeerData *)));
|
connect(App::main(), SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(peerUpdated(PeerData *)));
|
||||||
|
|
||||||
// about
|
// about
|
||||||
if (_peerUser && _peerUser->botInfo) {
|
if (_peerUser) {
|
||||||
if (!_peerUser->botInfo->shareText.isEmpty()) {
|
if (!_peerUser->about.isEmpty()) {
|
||||||
_about.setText(st::linkFont, _peerUser->botInfo->shareText, _historyBotNoMonoOptions);
|
_about.setText(st::linkFont, _peerUser->about, _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||||
}
|
}
|
||||||
updateBotLinksVisibility();
|
updateBotLinksVisibility();
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,6 +203,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
_botSettings.hide();
|
_botSettings.hide();
|
||||||
_botHelp.hide();
|
_botHelp.hide();
|
||||||
}
|
}
|
||||||
|
updatePinnedMessageVisibility();
|
||||||
|
|
||||||
// migrate to megagroup
|
// migrate to megagroup
|
||||||
connect(&_migrate, SIGNAL(clicked()), this, SLOT(onMigrate()));
|
connect(&_migrate, SIGNAL(clicked()), this, SLOT(onMigrate()));
|
||||||
|
@ -217,6 +222,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
connect(&_searchInPeer, SIGNAL(clicked()), this, SLOT(onSearchInPeer()));
|
connect(&_searchInPeer, SIGNAL(clicked()), this, SLOT(onSearchInPeer()));
|
||||||
|
connect(&_convertToSupergroup, SIGNAL(clicked()), this, SLOT(onConvertToSupergroup()));
|
||||||
connect(&_clearHistory, SIGNAL(clicked()), this, SLOT(onClearHistory()));
|
connect(&_clearHistory, SIGNAL(clicked()), this, SLOT(onClearHistory()));
|
||||||
connect(&_deleteConversation, SIGNAL(clicked()), this, SLOT(onDeleteConversation()));
|
connect(&_deleteConversation, SIGNAL(clicked()), this, SLOT(onDeleteConversation()));
|
||||||
connect(&_blockUser, SIGNAL(clicked()), this, SLOT(onBlockUser()));
|
connect(&_blockUser, SIGNAL(clicked()), this, SLOT(onBlockUser()));
|
||||||
|
@ -244,6 +250,10 @@ void ProfileInner::onSearchInPeer() {
|
||||||
App::main()->searchInPeer(_peer);
|
App::main()->searchInPeer(_peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProfileInner::onConvertToSupergroup() {
|
||||||
|
Ui::showLayer(new ConvertToSupergroupBox(_peerChat));
|
||||||
|
}
|
||||||
|
|
||||||
void ProfileInner::onEnableNotifications() {
|
void ProfileInner::onEnableNotifications() {
|
||||||
App::main()->updateNotifySetting(_peer, _enableNotifications.checked() ? NotifySettingSetNotify : NotifySettingSetMuted);
|
App::main()->updateNotifySetting(_peer, _enableNotifications.checked() ? NotifySettingSetNotify : NotifySettingSetMuted);
|
||||||
}
|
}
|
||||||
|
@ -526,11 +536,11 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) {
|
||||||
} else {
|
} else {
|
||||||
_photoLink = TextLinkPtr();
|
_photoLink = TextLinkPtr();
|
||||||
}
|
}
|
||||||
if (_peerUser->botInfo) {
|
if (_peerUser) {
|
||||||
if (_peerUser->botInfo->shareText.isEmpty()) {
|
if (_peerUser->about.isEmpty()) {
|
||||||
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
|
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
|
||||||
} else {
|
} else {
|
||||||
_about.setText(st::linkFont, _peerUser->botInfo->shareText, _historyBotNoMonoOptions);
|
_about.setText(st::linkFont, _peerUser->about, _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||||
}
|
}
|
||||||
updateBotLinksVisibility();
|
updateBotLinksVisibility();
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
|
@ -584,6 +594,14 @@ void ProfileInner::onBotHelp() {
|
||||||
updateBotLinksVisibility();
|
updateBotLinksVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProfileInner::onPinnedMessage() {
|
||||||
|
if (!_peerChannel || !_peerChannel->isMegagroup() || !_peerChannel->mgInfo->pinnedMsgId) {
|
||||||
|
updatePinnedMessageVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ui::showPeerHistory(_peer, _peerChannel->mgInfo->pinnedMsgId);
|
||||||
|
}
|
||||||
|
|
||||||
void ProfileInner::peerUpdated(PeerData *data) {
|
void ProfileInner::peerUpdated(PeerData *data) {
|
||||||
if (data == _peer) {
|
if (data == _peer) {
|
||||||
PhotoData *photo = 0;
|
PhotoData *photo = 0;
|
||||||
|
@ -607,17 +625,24 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
||||||
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1));
|
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1));
|
||||||
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1));
|
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1));
|
||||||
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
||||||
|
updatePinnedMessageVisibility();
|
||||||
}
|
}
|
||||||
_photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr();
|
_photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr();
|
||||||
if (_peer->name != _nameCache) {
|
if (_peer->name != _nameCache) {
|
||||||
_nameCache = _peer->name;
|
_nameCache = _peer->name;
|
||||||
_nameText.setText(st::profileNameFont, _nameCache, _textNameOptions);
|
_nameText.setText(st::profileNameFont, _nameCache, _textNameOptions);
|
||||||
}
|
}
|
||||||
showAll();
|
|
||||||
resizeEvent(0);
|
|
||||||
} else {
|
|
||||||
showAll();
|
|
||||||
}
|
}
|
||||||
|
if (!_updateDelayed) {
|
||||||
|
_updateDelayed = true;
|
||||||
|
QMetaObject::invokeMethod(this, "onUpdateDelayed", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfileInner::onUpdateDelayed() {
|
||||||
|
_updateDelayed = false;
|
||||||
|
showAll();
|
||||||
|
resizeEvent(0);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,34 +713,76 @@ void ProfileInner::reorderParticipants() {
|
||||||
}
|
}
|
||||||
loadProfilePhotos(_lastPreload);
|
loadProfilePhotos(_lastPreload);
|
||||||
} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||||
bool needAdmins = _peerChannel->amEditor(), adminsOutdated = (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated);
|
bool needAdmins = true, adminsOutdated = (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated);
|
||||||
|
bool orderByOnline = true;// (_peerChannel->count > 0) && (_peerChannel->count <= Global::ChatSizeMax());
|
||||||
|
|
||||||
|
_onlineText.clear();
|
||||||
if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (needAdmins && adminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) {
|
if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (needAdmins && adminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) {
|
||||||
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
|
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
|
||||||
} else if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
} else if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) {
|
||||||
const MegagroupInfo::LastParticipants &list(_peerChannel->mgInfo->lastParticipants);
|
const MegagroupInfo::LastParticipants &list(_peerChannel->mgInfo->lastParticipants);
|
||||||
int32 s = list.size();
|
int32 s = list.size();
|
||||||
for (int32 i = 0, l = _participants.size(); i < l; ++i) {
|
if (orderByOnline) {
|
||||||
if (i >= s || _participants.at(i) != list.at(i)) {
|
_participants.clear();
|
||||||
if (_participantsData.at(i)) {
|
for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) {
|
||||||
delete _participantsData.at(i);
|
if (*i) {
|
||||||
_participantsData[i] = 0;
|
delete *i;
|
||||||
}
|
*i = 0;
|
||||||
if (i < s) {
|
|
||||||
_participants[i] = list.at(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (_participants.size() > s) {
|
|
||||||
_participants.resize(s);
|
|
||||||
} else {
|
|
||||||
_participants.reserve(s);
|
_participants.reserve(s);
|
||||||
for (int32 i = _participants.size(); i < s; ++i) {
|
|
||||||
_participants.push_back(list.at(i));
|
UserData *self = App::self();
|
||||||
|
bool onlyMe = true;
|
||||||
|
for (int32 i = 0; i < s; ++i) {
|
||||||
|
UserData *user = list.at(i);
|
||||||
|
int32 until = App::onlineForSort(user, t);
|
||||||
|
Participants::iterator before = _participants.begin();
|
||||||
|
if (user != self) {
|
||||||
|
if (before != _participants.end() && (*before) == self) {
|
||||||
|
++before;
|
||||||
|
}
|
||||||
|
while (before != _participants.end() && App::onlineForSort(*before, t) >= until) {
|
||||||
|
++before;
|
||||||
|
}
|
||||||
|
if (until > t && onlyMe) onlyMe = false;
|
||||||
|
}
|
||||||
|
_participants.insert(before, user);
|
||||||
|
if (until > t) {
|
||||||
|
++onlineCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (onlineCount && !onlyMe) {
|
||||||
|
_onlineText = lng_chat_status_members_online(lt_count, _peerChannel->count, lt_count_online, onlineCount);
|
||||||
|
} else {
|
||||||
|
_onlineText = lng_chat_status_members(lt_count, _peerChannel->count);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int32 i = 0, l = _participants.size(); i < l; ++i) {
|
||||||
|
if (i >= s || _participants.at(i) != list.at(i)) {
|
||||||
|
if (_participantsData.at(i)) {
|
||||||
|
delete _participantsData.at(i);
|
||||||
|
_participantsData[i] = 0;
|
||||||
|
}
|
||||||
|
if (i < s) {
|
||||||
|
_participants[i] = list.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_participants.size() > s) {
|
||||||
|
_participants.resize(s);
|
||||||
|
} else {
|
||||||
|
_participants.reserve(s);
|
||||||
|
for (int32 i = _participants.size(); i < s; ++i) {
|
||||||
|
_participants.push_back(list.at(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_participantsData.resize(s);
|
_participantsData.resize(s);
|
||||||
}
|
}
|
||||||
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
if (_onlineText.isEmpty()) {
|
||||||
|
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
||||||
|
}
|
||||||
loadProfilePhotos(_lastPreload);
|
loadProfilePhotos(_lastPreload);
|
||||||
} else {
|
} else {
|
||||||
_participants.clear();
|
_participants.clear();
|
||||||
|
@ -792,7 +859,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
p.setPen(st::black->p);
|
p.setPen(st::black->p);
|
||||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
||||||
} else if (_peerChannel && !_peerChannel->isMegagroup() && (_peerChannel->isPublic() || _amCreator )) {
|
} else if (_peerChannel && (_peerChannel->isPublic() || _peerChannel->canEditUsername())) {
|
||||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
}
|
}
|
||||||
if (!_peerChannel || !_peerChannel->canViewParticipants() || _peerChannel->isMegagroup()) {
|
if (!_peerChannel || !_peerChannel->canViewParticipants() || _peerChannel->isMegagroup()) {
|
||||||
|
@ -900,6 +967,9 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
top += st::profileHeaderSkip;
|
top += st::profileHeaderSkip;
|
||||||
|
|
||||||
top += _searchInPeer.height() + st::setLittleSkip;
|
top += _searchInPeer.height() + st::setLittleSkip;
|
||||||
|
if (_peerChat && _amCreator && !_showMigrate) {
|
||||||
|
top += _convertToSupergroup.height() + st::setLittleSkip;
|
||||||
|
}
|
||||||
if (_peerUser || _peerChat) {
|
if (_peerUser || _peerChat) {
|
||||||
top += _clearHistory.height() + st::setLittleSkip;
|
top += _clearHistory.height() + st::setLittleSkip;
|
||||||
}
|
}
|
||||||
|
@ -922,6 +992,22 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
int32 partfrom = top;
|
int32 partfrom = top;
|
||||||
if (!_participants.isEmpty()) {
|
if (!_participants.isEmpty()) {
|
||||||
|
if (App::self()) {
|
||||||
|
if (_peerChat) {
|
||||||
|
if (_peerChat->amAdmin() && _peerChat->admins.constFind(App::self()) == _peerChat->admins.cend()) {
|
||||||
|
_peerChat->admins.insert(App::self());
|
||||||
|
} else if (!_peerChat->amAdmin() && _peerChat->admins.constFind(App::self()) != _peerChat->admins.cend()) {
|
||||||
|
_peerChat->admins.remove(App::self());
|
||||||
|
}
|
||||||
|
} else if (_peerChannel && _peerChannel->isMegagroup()) {
|
||||||
|
if ((_peerChannel->amCreator() || _peerChannel->amEditor()) && _peerChannel->mgInfo->lastAdmins.constFind(App::self()) == _peerChannel->mgInfo->lastAdmins.cend()) {
|
||||||
|
_peerChannel->mgInfo->lastAdmins.insert(App::self());
|
||||||
|
} else if (!_peerChannel->amCreator() && !_peerChannel->amEditor() && _peerChannel->mgInfo->lastAdmins.constFind(App::self()) != _peerChannel->mgInfo->lastAdmins.cend()) {
|
||||||
|
_peerChannel->mgInfo->lastAdmins.remove(App::self());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32 cnt = 0, fullCnt = _participants.size();
|
int32 cnt = 0, fullCnt = _participants.size();
|
||||||
for (Participants::const_iterator i = _participants.cbegin(), e = _participants.cend(); i != e; ++i, ++cnt) {
|
for (Participants::const_iterator i = _participants.cbegin(), e = _participants.cend(); i != e; ++i, ++cnt) {
|
||||||
int32 top = partfrom + cnt * _pHeight;
|
int32 top = partfrom + cnt * _pHeight;
|
||||||
|
@ -947,24 +1033,31 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
data->online = App::onlineText(user, l_time);
|
data->online = App::onlineText(user, l_time);
|
||||||
}
|
}
|
||||||
|
if (_peerChat) {
|
||||||
|
data->admin = (peerFromUser(_peerChat->creator) == user->id) || (_peerChat->admins.constFind(user) != _peerChat->admins.cend());
|
||||||
|
} else if (_peerChannel) {
|
||||||
|
data->admin = (_peerChannel->mgInfo->lastAdmins.constFind(user) != _peerChannel->mgInfo->lastAdmins.cend());
|
||||||
|
} else {
|
||||||
|
data->admin = false;
|
||||||
|
}
|
||||||
if (_amCreator) {
|
if (_amCreator) {
|
||||||
data->cankick = (user != App::self());
|
data->cankick = (user != App::self());
|
||||||
} else if (_peerChat && _peerChat->amAdmin()) {
|
} else if (_peerChat && _peerChat->amAdmin()) {
|
||||||
data->cankick = (user != App::self()) && (_peerChat->admins.constFind(user) == _peerChat->admins.cend()) && (peerFromUser(_peerChat->creator) != user->id);
|
data->cankick = (user != App::self()) && !data->admin;
|
||||||
} else if (_peerChannel && _peerChannel->amEditor()) {
|
} else if (_peerChannel && _peerChannel->amEditor()) {
|
||||||
data->cankick = (user != App::self()) && (_peerChannel->mgInfo->lastAdmins.constFind(user) == _peerChannel->mgInfo->lastAdmins.cend());
|
data->cankick = (user != App::self()) && !data->admin;
|
||||||
} else {
|
} else {
|
||||||
data->cankick = (user != App::self()) && !_peerChannel && (_peerChat->invitedByMe.constFind(user) != _peerChat->invitedByMe.cend());
|
data->cankick = (user != App::self()) && !_peerChannel && (_peerChat->invitedByMe.constFind(user) != _peerChat->invitedByMe.cend());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.setPen(st::profileListNameColor->p);
|
p.setPen(st::profileListNameColor);
|
||||||
p.setFont(st::linkFont->f);
|
p.setFont(st::linkFont);
|
||||||
data->name.drawElided(p, _left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListNameTop, _width - _kickWidth - st::profileListPadding.width() - st::profileListPhotoSize - st::profileListPadding.width());
|
data->name.drawElided(p, _left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListNameTop, _width - _kickWidth - st::profileListPadding.width() - st::profileListPhotoSize - st::profileListPadding.width());
|
||||||
p.setFont(st::profileSubFont->f);
|
p.setFont(st::profileSubFont);
|
||||||
p.setPen((App::onlineColorUse(user, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
p.setPen(App::onlineColorUse(user, l_time) ? st::profileOnlineColor : st::profileOfflineColor);
|
||||||
p.drawText(_left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online);
|
p.drawText(_left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online);
|
||||||
|
|
||||||
if (data->cankick) {
|
if (_selectedRow == cnt && data->cankick) {
|
||||||
bool over = (user == _kickOver && (!_kickDown || _kickDown == _kickOver));
|
bool over = (user == _kickOver && (!_kickDown || _kickDown == _kickOver));
|
||||||
p.setFont((over ? st::linkOverFont : st::linkFont)->f);
|
p.setFont((over ? st::linkOverFont : st::linkFont)->f);
|
||||||
if (user == _kickOver && _kickOver == _kickDown) {
|
if (user == _kickOver && _kickOver == _kickDown) {
|
||||||
|
@ -972,7 +1065,11 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
p.setPen(st::btnDefLink.color->p);
|
p.setPen(st::btnDefLink.color->p);
|
||||||
}
|
}
|
||||||
p.drawText(_left + _width - _kickWidth, top + st::profileListNameTop + st::linkFont->ascent, lang(lng_profile_kick));
|
p.drawTextRight(width() - _left - _width, top + st::profileListNameTop, width(), lang(lng_profile_kick), _kickWidth);
|
||||||
|
} else if (data->admin) {
|
||||||
|
p.setFont(st::profileSubFont);
|
||||||
|
p.setPen(st::profileOfflineColor);
|
||||||
|
p.drawTextRight(width() - _left - _width, top + st::profileListNameTop, width(), lang(lng_profile_admin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
top += fullCnt * _pHeight;
|
top += fullCnt * _pHeight;
|
||||||
|
@ -1277,13 +1374,16 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||||
// profile
|
// profile
|
||||||
top += st::profilePadding.top();
|
top += st::profilePadding.top();
|
||||||
int32 addbyname = 0;
|
int32 addbyname = 0;
|
||||||
if (_peerChannel && !_peerChannel->isMegagroup() && (_amCreator || _peerChannel->isPublic())) {
|
if (_peerChannel && (_peerChannel->isPublic() || _peerChannel->canEditUsername())) {
|
||||||
_username.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop);
|
_username.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop);
|
||||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
}
|
}
|
||||||
_members.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
_members.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
||||||
addbyname += st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
addbyname += st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
_admins.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
if (!_admins.isHidden()) {
|
||||||
|
_admins.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
||||||
|
addbyname += st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||||
|
}
|
||||||
if ((_peerChat && _amCreator && _peerChat->canEdit()) || (_peerChannel && (_amCreator || _peerChannel->amEditor() || _peerChannel->amModerator()))) {
|
if ((_peerChat && _amCreator && _peerChat->canEdit()) || (_peerChannel && (_amCreator || _peerChannel->amEditor() || _peerChannel->amModerator()))) {
|
||||||
_cancelPhoto.move(_left + _width - _cancelPhoto.width(), top + st::profilePhotoSize - st::linkFont->height);
|
_cancelPhoto.move(_left + _width - _cancelPhoto.width(), top + st::profilePhotoSize - st::linkFont->height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1291,6 +1391,7 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||||
_botSettings.move(_left + st::profilePhotoSize + st::profilePhoneLeft, top + st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent) + st::profilePhoneTop);
|
_botSettings.move(_left + st::profilePhotoSize + st::profilePhoneLeft, top + st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent) + st::profilePhoneTop);
|
||||||
_botHelp.move(_botSettings.x() + (_botSettings.isHidden() ? 0 : _botSettings.width() + st::profilePhoneLeft), _botSettings.y());
|
_botHelp.move(_botSettings.x() + (_botSettings.isHidden() ? 0 : _botSettings.width() + st::profilePhoneLeft), _botSettings.y());
|
||||||
}
|
}
|
||||||
|
_pinnedMessage.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
||||||
top += st::profilePhotoSize;
|
top += st::profilePhotoSize;
|
||||||
|
|
||||||
top += st::profileButtonTop;
|
top += st::profileButtonTop;
|
||||||
|
@ -1369,6 +1470,9 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||||
// actions
|
// actions
|
||||||
top += st::profileHeaderSkip;
|
top += st::profileHeaderSkip;
|
||||||
_searchInPeer.move(_left, top); top += _searchInPeer.height() + st::setLittleSkip;
|
_searchInPeer.move(_left, top); top += _searchInPeer.height() + st::setLittleSkip;
|
||||||
|
if (_peerChat && _amCreator && !_showMigrate) {
|
||||||
|
_convertToSupergroup.move(_left, top); top += _convertToSupergroup.height() + st::setLittleSkip;
|
||||||
|
}
|
||||||
if (_peerUser || _peerChat) {
|
if (_peerUser || _peerChat) {
|
||||||
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
|
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
|
||||||
}
|
}
|
||||||
|
@ -1525,6 +1629,11 @@ void ProfileInner::allowDecreaseHeight(int32 decreaseBy) {
|
||||||
|
|
||||||
void ProfileInner::showAll() {
|
void ProfileInner::showAll() {
|
||||||
_searchInPeer.show();
|
_searchInPeer.show();
|
||||||
|
if (_peerChat && _amCreator && !_showMigrate) {
|
||||||
|
_convertToSupergroup.show();
|
||||||
|
} else {
|
||||||
|
_convertToSupergroup.hide();
|
||||||
|
}
|
||||||
if (_peerUser || _peerChat) {
|
if (_peerUser || _peerChat) {
|
||||||
_clearHistory.show();
|
_clearHistory.show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1651,7 +1760,7 @@ void ProfileInner::showAll() {
|
||||||
} else {
|
} else {
|
||||||
_deleteChannel.hide();
|
_deleteChannel.hide();
|
||||||
}
|
}
|
||||||
if (!_peerChannel->isMegagroup() && (_peerChannel->isPublic() || _amCreator)) {
|
if (_peerChannel->isPublic() || _peerChannel->canEditUsername()) {
|
||||||
_username.show();
|
_username.show();
|
||||||
} else {
|
} else {
|
||||||
_username.hide();
|
_username.hide();
|
||||||
|
@ -1696,12 +1805,21 @@ void ProfileInner::updateInvitationLink() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProfileInner::updatePinnedMessageVisibility() {
|
||||||
|
if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->mgInfo->pinnedMsgId && !_amCreator && !_peerChannel->amEditor()) {
|
||||||
|
_pinnedMessage.show();
|
||||||
|
} else {
|
||||||
|
_pinnedMessage.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ProfileInner::updateBotLinksVisibility() {
|
void ProfileInner::updateBotLinksVisibility() {
|
||||||
if (!_peerUser || !_peerUser->botInfo || _peerUser->botInfo->commands.isEmpty()) {
|
if (!_peerUser || !_peerUser->botInfo || _peerUser->botInfo->commands.isEmpty()) {
|
||||||
_botSettings.hide();
|
_botSettings.hide();
|
||||||
_botHelp.hide();
|
_botHelp.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasSettings = false, hasHelp = false;
|
bool hasSettings = false, hasHelp = false;
|
||||||
for (int32 i = 0, l = _peerUser->botInfo->commands.size(); i != l; ++i) {
|
for (int32 i = 0, l = _peerUser->botInfo->commands.size(); i != l; ++i) {
|
||||||
QString cmd = _peerUser->botInfo->commands.at(i).command;
|
QString cmd = _peerUser->botInfo->commands.at(i).command;
|
||||||
|
|
|
@ -78,6 +78,7 @@ public slots:
|
||||||
void onInviteToGroup();
|
void onInviteToGroup();
|
||||||
void onSendMessage();
|
void onSendMessage();
|
||||||
void onSearchInPeer();
|
void onSearchInPeer();
|
||||||
|
void onConvertToSupergroup();
|
||||||
void onEnableNotifications();
|
void onEnableNotifications();
|
||||||
|
|
||||||
void onClearHistory();
|
void onClearHistory();
|
||||||
|
@ -123,12 +124,16 @@ public slots:
|
||||||
|
|
||||||
void onBotSettings();
|
void onBotSettings();
|
||||||
void onBotHelp();
|
void onBotHelp();
|
||||||
|
void onPinnedMessage();
|
||||||
|
|
||||||
|
void onUpdateDelayed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void showAll();
|
void showAll();
|
||||||
void updateInvitationLink();
|
void updateInvitationLink();
|
||||||
void updateBotLinksVisibility();
|
void updateBotLinksVisibility();
|
||||||
|
void updatePinnedMessageVisibility();
|
||||||
|
|
||||||
void chatInviteDone(const MTPExportedChatInvite &result);
|
void chatInviteDone(const MTPExportedChatInvite &result);
|
||||||
bool updateMediaLinks(int32 *addToScroll = 0); // returns if anything changed
|
bool updateMediaLinks(int32 *addToScroll = 0); // returns if anything changed
|
||||||
|
@ -157,7 +162,7 @@ private:
|
||||||
FlatButton _sendMessage, _shareContact, _inviteToGroup;
|
FlatButton _sendMessage, _shareContact, _inviteToGroup;
|
||||||
LinkButton _cancelPhoto, _createInvitationLink, _invitationLink;
|
LinkButton _cancelPhoto, _createInvitationLink, _invitationLink;
|
||||||
QString _invitationText;
|
QString _invitationText;
|
||||||
LinkButton _botSettings, _botHelp, _username, _members, _admins;
|
LinkButton _botSettings, _botHelp, _pinnedMessage, _username, _members, _admins;
|
||||||
|
|
||||||
Text _about;
|
Text _about;
|
||||||
int32 _aboutTop, _aboutHeight;
|
int32 _aboutTop, _aboutHeight;
|
||||||
|
@ -182,7 +187,7 @@ private:
|
||||||
QString overviewLinkText(int32 type, int32 count);
|
QString overviewLinkText(int32 type, int32 count);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
LinkButton _searchInPeer, _clearHistory, _deleteConversation;
|
LinkButton _searchInPeer, _convertToSupergroup, _clearHistory, _deleteConversation;
|
||||||
UserBlockedStatus _wasBlocked;
|
UserBlockedStatus _wasBlocked;
|
||||||
mtpRequestId _blockRequest;
|
mtpRequestId _blockRequest;
|
||||||
LinkButton _blockUser, _deleteChannel;
|
LinkButton _blockUser, _deleteChannel;
|
||||||
|
@ -193,11 +198,11 @@ private:
|
||||||
uint64 _contactId;
|
uint64 _contactId;
|
||||||
UserData *_kickOver, *_kickDown, *_kickConfirm;
|
UserData *_kickOver, *_kickDown, *_kickConfirm;
|
||||||
|
|
||||||
typedef struct {
|
struct ParticipantData {
|
||||||
Text name;
|
Text name;
|
||||||
QString online;
|
QString online;
|
||||||
bool cankick;
|
bool cankick, admin;
|
||||||
} ParticipantData;
|
};
|
||||||
typedef QVector<UserData*> Participants;
|
typedef QVector<UserData*> Participants;
|
||||||
Participants _participants;
|
Participants _participants;
|
||||||
typedef QVector<ParticipantData*> ParticipantsData;
|
typedef QVector<ParticipantData*> ParticipantsData;
|
||||||
|
@ -210,6 +215,8 @@ private:
|
||||||
|
|
||||||
QString _secretText;
|
QString _secretText;
|
||||||
|
|
||||||
|
bool _updateDelayed;
|
||||||
|
|
||||||
void blockDone(bool blocked, const MTPBool &result);
|
void blockDone(bool blocked, const MTPBool &result);
|
||||||
bool blockFail(const RPCError &error);
|
bool blockFail(const RPCError &error);
|
||||||
|
|
||||||
|
|
|
@ -263,6 +263,13 @@ namespace Shortcuts {
|
||||||
|
|
||||||
QMap<QKeySequence, QShortcut*> sequences;
|
QMap<QKeySequence, QShortcut*> sequences;
|
||||||
QMap<int, ShortcutCommands::Handler> handlers;
|
QMap<int, ShortcutCommands::Handler> handlers;
|
||||||
|
|
||||||
|
QSet<QString> autoRepeatCommands = {
|
||||||
|
qsl("media_previous"),
|
||||||
|
qsl("media_next"),
|
||||||
|
qsl("next_chat"),
|
||||||
|
qsl("previous_chat"),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
void _createCommand(const QString &command, ShortcutCommands::Handler handler) {
|
void _createCommand(const QString &command, ShortcutCommands::Handler handler) {
|
||||||
|
@ -287,7 +294,9 @@ namespace Shortcuts {
|
||||||
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
||||||
} else {
|
} else {
|
||||||
QShortcut *shortcut(new QShortcut(seq, App::wnd(), nullptr, nullptr, Qt::ApplicationShortcut));
|
QShortcut *shortcut(new QShortcut(seq, App::wnd(), nullptr, nullptr, Qt::ApplicationShortcut));
|
||||||
shortcut->setAutoRepeat(false);
|
if (!DataPtr->autoRepeatCommands.contains(command)) {
|
||||||
|
shortcut->setAutoRepeat(false);
|
||||||
|
}
|
||||||
int shortcutId = shortcut->id();
|
int shortcutId = shortcut->id();
|
||||||
if (!shortcutId) {
|
if (!shortcutId) {
|
||||||
DataPtr->errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys));
|
DataPtr->errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys));
|
||||||
|
|
|
@ -263,7 +263,6 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||||
Notify::botCommandsChanged(this);
|
Notify::botCommandsChanged(this);
|
||||||
}
|
}
|
||||||
botInfo->description.clear();
|
botInfo->description.clear();
|
||||||
botInfo->shareText.clear();
|
|
||||||
botInfo->version = version;
|
botInfo->version = version;
|
||||||
botInfo->inited = false;
|
botInfo->inited = false;
|
||||||
}
|
}
|
||||||
|
@ -271,33 +270,15 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||||
|
|
||||||
void UserData::setBotInfo(const MTPBotInfo &info) {
|
void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||||
switch (info.type()) {
|
switch (info.type()) {
|
||||||
case mtpc_botInfoEmpty:
|
|
||||||
if (botInfo) {
|
|
||||||
if (!botInfo->commands.isEmpty()) {
|
|
||||||
botInfo->commands.clear();
|
|
||||||
Notify::botCommandsChanged(this);
|
|
||||||
}
|
|
||||||
delete botInfo;
|
|
||||||
botInfo = 0;
|
|
||||||
Notify::userIsBotChanged(this);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mtpc_botInfo: {
|
case mtpc_botInfo: {
|
||||||
const MTPDbotInfo &d(info.c_botInfo());
|
const MTPDbotInfo &d(info.c_botInfo());
|
||||||
if (peerFromUser(d.vuser_id.v) != id) return;
|
if (peerFromUser(d.vuser_id.v) != id || !botInfo) return;
|
||||||
|
|
||||||
if (botInfo) {
|
|
||||||
botInfo->version = d.vversion.v;
|
|
||||||
} else {
|
|
||||||
setBotInfoVersion(d.vversion.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString desc = qs(d.vdescription);
|
QString desc = qs(d.vdescription);
|
||||||
if (botInfo->description != desc) {
|
if (botInfo->description != desc) {
|
||||||
botInfo->description = desc;
|
botInfo->description = desc;
|
||||||
botInfo->text = Text(st::msgMinWidth);
|
botInfo->text = Text(st::msgMinWidth);
|
||||||
}
|
}
|
||||||
botInfo->shareText = qs(d.vshare_text);
|
|
||||||
|
|
||||||
const QVector<MTPBotCommand> &v(d.vcommands.c_vector().v);
|
const QVector<MTPBotCommand> &v(d.vcommands.c_vector().v);
|
||||||
botInfo->commands.reserve(v.size());
|
botInfo->commands.reserve(v.size());
|
||||||
|
@ -879,14 +860,14 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
|
||||||
if (App::main()) App::main()->mediaMarkRead(data);
|
if (App::main()) App::main()->mediaMarkRead(data);
|
||||||
} else if (data->size < MediaViewImageSizeLimit) {
|
} else if (data->size < MediaViewImageSizeLimit) {
|
||||||
if (!data->data().isEmpty() && playAnimation) {
|
if (!data->data().isEmpty() && playAnimation) {
|
||||||
if (action == ActionOnLoadPlayInline) {
|
if (action == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
item->getMedia()->playInline(item);
|
item->getMedia()->playInline(item);
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->showDocument(data, item);
|
App::wnd()->showDocument(data, item);
|
||||||
}
|
}
|
||||||
} else if (location.accessEnable()) {
|
} else if (location.accessEnable()) {
|
||||||
if ((App::hoveredLinkItem() || App::contextItem()) && (data->isAnimation() || QImageReader(location.name()).canRead())) {
|
if (item && (data->isAnimation() || QImageReader(location.name()).canRead())) {
|
||||||
if (action == ActionOnLoadPlayInline) {
|
if (action == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
item->getMedia()->playInline(item);
|
item->getMedia()->playInline(item);
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->showDocument(data, item);
|
App::wnd()->showDocument(data, item);
|
||||||
|
@ -1162,7 +1143,7 @@ void DocumentData::performActionOnLoad() {
|
||||||
}
|
}
|
||||||
} else if (playAnimation) {
|
} else if (playAnimation) {
|
||||||
if (loaded()) {
|
if (loaded()) {
|
||||||
if (_actionOnLoad == ActionOnLoadPlayInline) {
|
if (_actionOnLoad == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
item->getMedia()->playInline(item);
|
item->getMedia()->playInline(item);
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->showDocument(this, item);
|
App::wnd()->showDocument(this, item);
|
||||||
|
@ -1182,7 +1163,7 @@ void DocumentData::performActionOnLoad() {
|
||||||
if (App::main()) App::main()->mediaMarkRead(this);
|
if (App::main()) App::main()->mediaMarkRead(this);
|
||||||
} else if (loc.accessEnable()) {
|
} else if (loc.accessEnable()) {
|
||||||
if (showImage && QImageReader(loc.name()).canRead()) {
|
if (showImage && QImageReader(loc.name()).canRead()) {
|
||||||
if (_actionOnLoad == ActionOnLoadPlayInline) {
|
if (_actionOnLoad == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
item->getMedia()->playInline(item);
|
item->getMedia()->playInline(item);
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->showDocument(this, item);
|
App::wnd()->showDocument(this, item);
|
||||||
|
|
|
@ -334,7 +334,7 @@ struct BotInfo {
|
||||||
bool inited;
|
bool inited;
|
||||||
bool readsAllHistory, cantJoinGroups;
|
bool readsAllHistory, cantJoinGroups;
|
||||||
int32 version;
|
int32 version;
|
||||||
QString shareText, description, inlinePlaceholder;
|
QString description, inlinePlaceholder;
|
||||||
QList<BotCommand> commands;
|
QList<BotCommand> commands;
|
||||||
Text text; // description
|
Text text; // description
|
||||||
|
|
||||||
|
@ -351,7 +351,14 @@ class PhotoData;
|
||||||
class UserData : public PeerData {
|
class UserData : public PeerData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UserData(const PeerId &id) : PeerData(id), access(0), flags(0), onlineTill(0), contact(-1), blocked(UserBlockUnknown), photosCount(-1), botInfo(0) {
|
UserData(const PeerId &id) : PeerData(id)
|
||||||
|
, access(0)
|
||||||
|
, flags(0)
|
||||||
|
, onlineTill(0)
|
||||||
|
, contact(-1)
|
||||||
|
, blocked(UserBlockUnknown)
|
||||||
|
, photosCount(-1)
|
||||||
|
, botInfo(0) {
|
||||||
setName(QString(), QString(), QString(), QString());
|
setName(QString(), QString(), QString(), QString());
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPUserProfilePhoto &photo);
|
void setPhoto(const MTPUserProfilePhoto &photo);
|
||||||
|
@ -390,6 +397,8 @@ public:
|
||||||
Photos photos;
|
Photos photos;
|
||||||
int32 photosCount; // -1 not loaded, 0 all loaded
|
int32 photosCount; // -1 not loaded, 0 all loaded
|
||||||
|
|
||||||
|
QString about;
|
||||||
|
|
||||||
BotInfo *botInfo;
|
BotInfo *botInfo;
|
||||||
};
|
};
|
||||||
static UserData * const InlineBotLookingUpData = SharedMemoryLocation<UserData, 0>();
|
static UserData * const InlineBotLookingUpData = SharedMemoryLocation<UserData, 0>();
|
||||||
|
@ -397,7 +406,16 @@ static UserData * const InlineBotLookingUpData = SharedMemoryLocation<UserData,
|
||||||
class ChatData : public PeerData {
|
class ChatData : public PeerData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_int(bareId())), migrateToPtr(0), count(0), date(0), version(0), creator(0), inviterForSpamReport(0), flags(0), isForbidden(false), botStatus(0) {
|
ChatData(const PeerId &id) : PeerData(id)
|
||||||
|
, inputChat(MTP_int(bareId()))
|
||||||
|
, migrateToPtr(0)
|
||||||
|
, count(0)
|
||||||
|
, date(0)
|
||||||
|
, version(0)
|
||||||
|
, creator(0)
|
||||||
|
, flags(0)
|
||||||
|
, isForbidden(false)
|
||||||
|
, botStatus(0) {
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||||
void invalidateParticipants() {
|
void invalidateParticipants() {
|
||||||
|
@ -419,7 +437,6 @@ public:
|
||||||
int32 date;
|
int32 date;
|
||||||
int32 version;
|
int32 version;
|
||||||
int32 creator;
|
int32 creator;
|
||||||
int32 inviterForSpamReport; // > 0 - user who invited me to chat in unread service msg, < 0 - have outgoing message
|
|
||||||
|
|
||||||
int32 flags;
|
int32 flags;
|
||||||
bool isForbidden;
|
bool isForbidden;
|
||||||
|
@ -455,13 +472,13 @@ public:
|
||||||
}
|
}
|
||||||
typedef QMap<UserData*, int32> Participants;
|
typedef QMap<UserData*, int32> Participants;
|
||||||
Participants participants;
|
Participants participants;
|
||||||
typedef QMap<UserData*, bool> InvitedByMe;
|
typedef OrderedSet<UserData*> InvitedByMe;
|
||||||
InvitedByMe invitedByMe;
|
InvitedByMe invitedByMe;
|
||||||
typedef QMap<UserData*, bool> Admins;
|
typedef OrderedSet<UserData*> Admins;
|
||||||
Admins admins;
|
Admins admins;
|
||||||
typedef QList<UserData*> LastAuthors;
|
typedef QList<UserData*> LastAuthors;
|
||||||
LastAuthors lastAuthors;
|
LastAuthors lastAuthors;
|
||||||
typedef QMap<PeerData*, bool> MarkupSenders;
|
typedef OrderedSet<PeerData*> 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;
|
||||||
|
@ -475,14 +492,14 @@ enum PtsSkippedQueue {
|
||||||
class PtsWaiter {
|
class PtsWaiter {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PtsWaiter() :
|
PtsWaiter()
|
||||||
_good(0),
|
: _good(0)
|
||||||
_last(0),
|
, _last(0)
|
||||||
_count(0),
|
, _count(0)
|
||||||
_applySkippedLevel(0),
|
, _applySkippedLevel(0)
|
||||||
_requesting(false),
|
, _requesting(false)
|
||||||
_waitingForSkipped(false),
|
, _waitingForSkipped(false)
|
||||||
_waitingForShortPoll(false) {
|
, _waitingForShortPoll(false) {
|
||||||
}
|
}
|
||||||
void init(int32 pts) {
|
void init(int32 pts) {
|
||||||
_good = _last = _count = pts;
|
_good = _last = _count = pts;
|
||||||
|
@ -530,22 +547,25 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MegagroupInfo {
|
struct MegagroupInfo {
|
||||||
MegagroupInfo() : botStatus(0)
|
MegagroupInfo()
|
||||||
, joinedMessageFound(false)
|
: botStatus(0)
|
||||||
, lastParticipantsStatus(LastParticipantsUpToDate)
|
, pinnedMsgId(0)
|
||||||
, lastParticipantsCount(0)
|
, joinedMessageFound(false)
|
||||||
, migrateFromPtr(0) {
|
, lastParticipantsStatus(LastParticipantsUpToDate)
|
||||||
|
, lastParticipantsCount(0)
|
||||||
|
, migrateFromPtr(0) {
|
||||||
}
|
}
|
||||||
typedef QList<UserData*> LastParticipants;
|
typedef QList<UserData*> LastParticipants;
|
||||||
LastParticipants lastParticipants;
|
LastParticipants lastParticipants;
|
||||||
typedef QMap<UserData*, bool> LastAdmins;
|
typedef OrderedSet<UserData*> LastAdmins;
|
||||||
LastAdmins lastAdmins;
|
LastAdmins lastAdmins;
|
||||||
typedef QMap<PeerData*, bool> MarkupSenders;
|
typedef OrderedSet<PeerData*> MarkupSenders;
|
||||||
MarkupSenders markupSenders;
|
MarkupSenders markupSenders;
|
||||||
typedef QMap<UserData*, bool> Bots;
|
typedef OrderedSet<UserData*> Bots;
|
||||||
Bots bots;
|
Bots bots;
|
||||||
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
|
||||||
|
|
||||||
|
MsgId pinnedMsgId;
|
||||||
bool joinedMessageFound;
|
bool joinedMessageFound;
|
||||||
|
|
||||||
enum LastParticipantsStatus {
|
enum LastParticipantsStatus {
|
||||||
|
@ -562,7 +582,19 @@ struct MegagroupInfo {
|
||||||
class ChannelData : public PeerData {
|
class ChannelData : public PeerData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), count(1), adminsCount(1), date(0), version(0), flags(0), flagsFull(0), mgInfo(0), isForbidden(true), inviter(0), _lastFullUpdate(0) {
|
ChannelData(const PeerId &id) : PeerData(id)
|
||||||
|
, access(0)
|
||||||
|
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0)))
|
||||||
|
, count(1)
|
||||||
|
, adminsCount(1)
|
||||||
|
, date(0)
|
||||||
|
, version(0)
|
||||||
|
, flags(0)
|
||||||
|
, flagsFull(0)
|
||||||
|
, mgInfo(nullptr)
|
||||||
|
, isForbidden(true)
|
||||||
|
, inviter(0)
|
||||||
|
, _lastFullUpdate(0) {
|
||||||
setName(QString(), QString());
|
setName(QString(), QString());
|
||||||
}
|
}
|
||||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||||
|
@ -602,6 +634,9 @@ public:
|
||||||
bool isPublic() const {
|
bool isPublic() const {
|
||||||
return flags & MTPDchannel::flag_username;
|
return flags & MTPDchannel::flag_username;
|
||||||
}
|
}
|
||||||
|
bool canEditUsername() const {
|
||||||
|
return amCreator() && (flagsFull & MTPDchannelFull::flag_can_set_username);
|
||||||
|
}
|
||||||
bool amCreator() const {
|
bool amCreator() const {
|
||||||
return flags & MTPDchannel::flag_creator;
|
return flags & MTPDchannel::flag_creator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,67 +323,6 @@ protected:
|
||||||
QString translitRusEng(const QString &rus);
|
QString translitRusEng(const QString &rus);
|
||||||
QString rusKeyboardLayoutSwitch(const QString &from);
|
QString rusKeyboardLayoutSwitch(const QString &from);
|
||||||
|
|
||||||
enum DataBlockId {
|
|
||||||
dbiKey = 0x00,
|
|
||||||
dbiUser = 0x01,
|
|
||||||
dbiDcOptionOld = 0x02,
|
|
||||||
dbiChatSizeMax = 0x03,
|
|
||||||
dbiMutePeer = 0x04,
|
|
||||||
dbiSendKey = 0x05,
|
|
||||||
dbiAutoStart = 0x06,
|
|
||||||
dbiStartMinimized = 0x07,
|
|
||||||
dbiSoundNotify = 0x08,
|
|
||||||
dbiWorkMode = 0x09,
|
|
||||||
dbiSeenTrayTooltip = 0x0a,
|
|
||||||
dbiDesktopNotify = 0x0b,
|
|
||||||
dbiAutoUpdate = 0x0c,
|
|
||||||
dbiLastUpdateCheck = 0x0d,
|
|
||||||
dbiWindowPosition = 0x0e,
|
|
||||||
dbiConnectionType = 0x0f,
|
|
||||||
// 0x10 reserved
|
|
||||||
dbiDefaultAttach = 0x11,
|
|
||||||
dbiCatsAndDogs = 0x12,
|
|
||||||
dbiReplaceEmojis = 0x13,
|
|
||||||
dbiAskDownloadPath = 0x14,
|
|
||||||
dbiDownloadPathOld = 0x15,
|
|
||||||
dbiScale = 0x16,
|
|
||||||
dbiEmojiTabOld = 0x17,
|
|
||||||
dbiRecentEmojisOld = 0x18,
|
|
||||||
dbiLoggedPhoneNumber = 0x19,
|
|
||||||
dbiMutedPeers = 0x1a,
|
|
||||||
// 0x1b reserved
|
|
||||||
dbiNotifyView = 0x1c,
|
|
||||||
dbiSendToMenu = 0x1d,
|
|
||||||
dbiCompressPastedImage = 0x1e,
|
|
||||||
dbiLang = 0x1f,
|
|
||||||
dbiLangFile = 0x20,
|
|
||||||
dbiTileBackground = 0x21,
|
|
||||||
dbiAutoLock = 0x22,
|
|
||||||
dbiDialogLastPath = 0x23,
|
|
||||||
dbiRecentEmojis = 0x24,
|
|
||||||
dbiEmojiVariants = 0x25,
|
|
||||||
dbiRecentStickers = 0x26,
|
|
||||||
dbiDcOption = 0x27,
|
|
||||||
dbiTryIPv6 = 0x28,
|
|
||||||
dbiSongVolume = 0x29,
|
|
||||||
dbiWindowsNotifications = 0x30,
|
|
||||||
dbiIncludeMuted = 0x31,
|
|
||||||
dbiMegagroupSizeMax = 0x32,
|
|
||||||
dbiDownloadPath = 0x33,
|
|
||||||
dbiAutoDownload = 0x34,
|
|
||||||
dbiSavedGifsLimit = 0x35,
|
|
||||||
dbiShowingSavedGifs = 0x36,
|
|
||||||
dbiAutoPlay = 0x37,
|
|
||||||
dbiAdaptiveForWide = 0x38,
|
|
||||||
|
|
||||||
dbiEncryptedWithSalt = 333,
|
|
||||||
dbiEncrypted = 444,
|
|
||||||
|
|
||||||
// 500-600 reserved
|
|
||||||
|
|
||||||
dbiVersion = 666,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DBISendKey {
|
enum DBISendKey {
|
||||||
dbiskEnter = 0,
|
dbiskEnter = 0,
|
||||||
dbiskCtrlEnter = 1,
|
dbiskCtrlEnter = 1,
|
||||||
|
@ -458,10 +397,12 @@ enum DBIPlatform {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DBIPeerReportSpamStatus {
|
enum DBIPeerReportSpamStatus {
|
||||||
dbiprsNoButton,
|
dbiprsNoButton = 0, // hidden, but not in the cloud settings yet
|
||||||
dbiprsUnknown,
|
dbiprsUnknown = 1, // contacts not loaded yet
|
||||||
dbiprsShowButton,
|
dbiprsShowButton = 2, // show report spam button, each show peer request setting from cloud
|
||||||
dbiprsReportSent,
|
dbiprsReportSent = 3, // report sent, but the report spam panel is not hidden yet
|
||||||
|
dbiprsHidden = 4, // hidden in the cloud or not needed (bots, contacts, etc), no more requests
|
||||||
|
dbiprsRequesting = 5, // requesting the cloud setting right now
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -815,6 +756,15 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
class SharedCallback2 {
|
||||||
|
public:
|
||||||
|
virtual R call(A1 channel, A2 msgId) const = 0;
|
||||||
|
virtual ~SharedCallback2() {
|
||||||
|
}
|
||||||
|
typedef QSharedPointer<SharedCallback2<R, A1, A2> > Ptr;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
class FunctionImplementation {
|
class FunctionImplementation {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1408,6 +1408,9 @@ void Window::notifySchedule(History *history, HistoryItem *item) {
|
||||||
}
|
}
|
||||||
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input));
|
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input));
|
||||||
}
|
}
|
||||||
|
if (!item->notificationReady()) {
|
||||||
|
haveSetting = false;
|
||||||
|
}
|
||||||
|
|
||||||
int delay = item->Is<HistoryMessageForwarded>() ? 500 : 100, t = unixtime();
|
int delay = item->Is<HistoryMessageForwarded>() ? 500 : 100, t = unixtime();
|
||||||
uint64 ms = getms(true);
|
uint64 ms = getms(true);
|
||||||
|
@ -1419,7 +1422,7 @@ void Window::notifySchedule(History *history, HistoryItem *item) {
|
||||||
delay = Global::NotifyDefaultDelay();
|
delay = Global::NotifyDefaultDelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 when = getms(true) + delay;
|
uint64 when = ms + delay;
|
||||||
notifyWhenAlerts[history].insert(when, notifyByFrom);
|
notifyWhenAlerts[history].insert(when, notifyByFrom);
|
||||||
if (cDesktopNotify() && !psSkipDesktopNotify()) {
|
if (cDesktopNotify() && !psSkipDesktopNotify()) {
|
||||||
NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
|
NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
|
||||||
|
@ -1487,20 +1490,38 @@ void Window::notifySettingGot() {
|
||||||
int32 t = unixtime();
|
int32 t = unixtime();
|
||||||
for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) {
|
for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) {
|
||||||
History *history = i.key();
|
History *history = i.key();
|
||||||
if (history->peer->notify == UnknownNotifySettings) {
|
bool loaded = false, muted = false;
|
||||||
++i;
|
if (history->peer->notify != UnknownNotifySettings) {
|
||||||
} else {
|
|
||||||
if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
|
if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
|
||||||
notifyWaiters.insert(i.key(), i.value());
|
loaded = true;
|
||||||
} else if (PeerData *from = i.value().notifyByFrom) {
|
} else if (PeerData *from = i.value().notifyByFrom) {
|
||||||
if (from->notify == UnknownNotifySettings) {
|
if (from->notify != UnknownNotifySettings) {
|
||||||
++i;
|
if (from->notify == EmptyNotifySettings || from->notify->mute <= t) {
|
||||||
continue;
|
loaded = true;
|
||||||
} else if (from->notify == EmptyNotifySettings || from->notify->mute <= t) {
|
} else {
|
||||||
notifyWaiters.insert(i.key(), i.value());
|
loaded = muted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
loaded = muted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loaded) {
|
||||||
|
if (HistoryItem *item = App::histItemById(history->channelId(), i.value().msg)) {
|
||||||
|
if (!item->notificationReady()) {
|
||||||
|
loaded = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
muted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loaded) {
|
||||||
|
if (!muted) {
|
||||||
|
notifyWaiters.insert(i.key(), i.value());
|
||||||
}
|
}
|
||||||
i = notifySettingWaiters.erase(i);
|
i = notifySettingWaiters.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyWaitTimer.stop();
|
notifyWaitTimer.stop();
|
||||||
|
@ -2020,6 +2041,25 @@ void PreLaunchButton::setText(const QString &text) {
|
||||||
resize(sizeHint());
|
resize(sizeHint());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreLaunchCheckbox::PreLaunchCheckbox(QWidget *parent) : QCheckBox(parent) {
|
||||||
|
setTristate(false);
|
||||||
|
setCheckState(Qt::Checked);
|
||||||
|
|
||||||
|
QFont closeFont(font());
|
||||||
|
closeFont.setFamily(qsl("Open Sans Semibold"));
|
||||||
|
closeFont.setPixelSize(static_cast<PreLaunchWindow*>(parent)->basicSize());
|
||||||
|
setFont(closeFont);
|
||||||
|
|
||||||
|
setCursor(Qt::PointingHandCursor);
|
||||||
|
show();
|
||||||
|
};
|
||||||
|
|
||||||
|
void PreLaunchCheckbox::setText(const QString &text) {
|
||||||
|
QCheckBox::setText(text);
|
||||||
|
updateGeometry();
|
||||||
|
resize(sizeHint());
|
||||||
|
}
|
||||||
|
|
||||||
NotStartedWindow::NotStartedWindow()
|
NotStartedWindow::NotStartedWindow()
|
||||||
: _label(this)
|
: _label(this)
|
||||||
, _log(this)
|
, _log(this)
|
||||||
|
@ -2076,6 +2116,7 @@ LastCrashedWindow::LastCrashedWindow()
|
||||||
, _showReport(this)
|
, _showReport(this)
|
||||||
, _saveReport(this)
|
, _saveReport(this)
|
||||||
, _getApp(this)
|
, _getApp(this)
|
||||||
|
, _includeUsername(this)
|
||||||
, _reportText(QString::fromUtf8(Sandbox::LastCrashDump()))
|
, _reportText(QString::fromUtf8(Sandbox::LastCrashDump()))
|
||||||
, _reportShown(false)
|
, _reportShown(false)
|
||||||
, _reportSaved(false)
|
, _reportSaved(false)
|
||||||
|
@ -2090,6 +2131,8 @@ LastCrashedWindow::LastCrashedWindow()
|
||||||
, _updatingSkip(this, false)
|
, _updatingSkip(this, false)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
excludeReportUsername();
|
||||||
|
|
||||||
if (!cDevVersion() && !cBetaVersion()) { // currently accept crash reports only from testers
|
if (!cDevVersion() && !cBetaVersion()) { // currently accept crash reports only from testers
|
||||||
_sendingState = SendingNoReport;
|
_sendingState = SendingNoReport;
|
||||||
}
|
}
|
||||||
|
@ -2193,7 +2236,9 @@ LastCrashedWindow::LastCrashedWindow()
|
||||||
_yourReportName.setCursor(style::cur_text);
|
_yourReportName.setCursor(style::cur_text);
|
||||||
_yourReportName.setTextInteractionFlags(Qt::TextSelectableByMouse);
|
_yourReportName.setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
|
|
||||||
_report.setPlainText(_reportText);
|
_includeUsername.setText(qsl("Include username @%1 as your contact info").arg(_reportUsername));
|
||||||
|
|
||||||
|
_report.setPlainText(_reportTextNoUsername);
|
||||||
|
|
||||||
_showReport.setText(qsl("VIEW REPORT"));
|
_showReport.setText(qsl("VIEW REPORT"));
|
||||||
connect(&_showReport, SIGNAL(clicked()), this, SLOT(onViewReport()));
|
connect(&_showReport, SIGNAL(clicked()), this, SLOT(onViewReport()));
|
||||||
|
@ -2226,17 +2271,38 @@ void LastCrashedWindow::onSaveReport() {
|
||||||
if (!to.isEmpty()) {
|
if (!to.isEmpty()) {
|
||||||
QFile file(to);
|
QFile file(to);
|
||||||
if (file.open(QIODevice::WriteOnly)) {
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
file.write(Sandbox::LastCrashDump());
|
file.write(getCrashReportRaw());
|
||||||
_reportSaved = true;
|
_reportSaved = true;
|
||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray LastCrashedWindow::getCrashReportRaw() const {
|
||||||
|
QByteArray result(Sandbox::LastCrashDump());
|
||||||
|
if (!_reportUsername.isEmpty() && _includeUsername.checkState() != Qt::Checked) {
|
||||||
|
result.replace((qsl("Username: ") + _reportUsername).toUtf8(), "Username: _not_included_");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void LastCrashedWindow::onGetApp() {
|
void LastCrashedWindow::onGetApp() {
|
||||||
QDesktopServices::openUrl(qsl("https://desktop.telegram.org"));
|
QDesktopServices::openUrl(qsl("https://desktop.telegram.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LastCrashedWindow::excludeReportUsername() {
|
||||||
|
QString prefix = qstr("Username:");
|
||||||
|
QStringList lines = _reportText.split('\n');
|
||||||
|
for (int32 i = 0, l = lines.size(); i < l; ++i) {
|
||||||
|
if (lines.at(i).trimmed().startsWith(prefix)) {
|
||||||
|
_reportUsername = lines.at(i).trimmed().mid(prefix.size()).trimmed();
|
||||||
|
lines.removeAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_reportTextNoUsername = _reportUsername.isEmpty() ? _reportText : lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
QString LastCrashedWindow::getReportField(const QLatin1String &name, const QLatin1String &prefix) {
|
QString LastCrashedWindow::getReportField(const QLatin1String &name, const QLatin1String &prefix) {
|
||||||
QStringList lines = _reportText.split('\n');
|
QStringList lines = _reportText.split('\n');
|
||||||
for (int32 i = 0, l = lines.size(); i < l; ++i) {
|
for (int32 i = 0, l = lines.size(); i < l; ++i) {
|
||||||
|
@ -2420,7 +2486,7 @@ void LastCrashedWindow::onCheckingFinished() {
|
||||||
QHttpPart reportPart;
|
QHttpPart reportPart;
|
||||||
reportPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
reportPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||||
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"report\"; filename=\"report.telegramcrash\""));
|
reportPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"report\"; filename=\"report.telegramcrash\""));
|
||||||
reportPart.setBody(Sandbox::LastCrashDump());
|
reportPart.setBody(getCrashReportRaw());
|
||||||
multipart->append(reportPart);
|
multipart->append(reportPart);
|
||||||
|
|
||||||
QString dmpName = minidumpFileName();
|
QString dmpName = minidumpFileName();
|
||||||
|
@ -2499,6 +2565,7 @@ void LastCrashedWindow::updateControls() {
|
||||||
_continue.hide();
|
_continue.hide();
|
||||||
_pleaseSendReport.hide();
|
_pleaseSendReport.hide();
|
||||||
_yourReportName.hide();
|
_yourReportName.hide();
|
||||||
|
_includeUsername.hide();
|
||||||
_getApp.hide();
|
_getApp.hide();
|
||||||
_showReport.hide();
|
_showReport.hide();
|
||||||
_report.hide();
|
_report.hide();
|
||||||
|
@ -2516,6 +2583,7 @@ void LastCrashedWindow::updateControls() {
|
||||||
if (_sendingState == SendingNoReport) {
|
if (_sendingState == SendingNoReport) {
|
||||||
_pleaseSendReport.hide();
|
_pleaseSendReport.hide();
|
||||||
_yourReportName.hide();
|
_yourReportName.hide();
|
||||||
|
_includeUsername.hide();
|
||||||
_getApp.hide();
|
_getApp.hide();
|
||||||
_showReport.hide();
|
_showReport.hide();
|
||||||
_report.hide();
|
_report.hide();
|
||||||
|
@ -2528,6 +2596,12 @@ void LastCrashedWindow::updateControls() {
|
||||||
h += _showReport.height() + padding + _yourReportName.height() + padding;
|
h += _showReport.height() + padding + _yourReportName.height() + padding;
|
||||||
_pleaseSendReport.show();
|
_pleaseSendReport.show();
|
||||||
_yourReportName.show();
|
_yourReportName.show();
|
||||||
|
if (_reportUsername.isEmpty()) {
|
||||||
|
_includeUsername.hide();
|
||||||
|
} else {
|
||||||
|
h += _includeUsername.height() + padding;
|
||||||
|
_includeUsername.show();
|
||||||
|
}
|
||||||
if (_sendingState == SendingTooOld || _sendingState == SendingUnofficial) {
|
if (_sendingState == SendingTooOld || _sendingState == SendingUnofficial) {
|
||||||
QString verStr = getReportField(qstr("version"), qstr("Version:"));
|
QString verStr = getReportField(qstr("version"), qstr("Version:"));
|
||||||
qint64 ver = verStr.isEmpty() ? 0 : verStr.toLongLong();
|
qint64 ver = verStr.isEmpty() ? 0 : verStr.toLongLong();
|
||||||
|
@ -2536,6 +2610,10 @@ void LastCrashedWindow::updateControls() {
|
||||||
_getApp.show();
|
_getApp.show();
|
||||||
h -= _yourReportName.height() + padding; // hide report name
|
h -= _yourReportName.height() + padding; // hide report name
|
||||||
_yourReportName.hide();
|
_yourReportName.hide();
|
||||||
|
if (!_reportUsername.isEmpty()) {
|
||||||
|
h -= _includeUsername.height() + padding;
|
||||||
|
_includeUsername.hide();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_getApp.hide();
|
_getApp.hide();
|
||||||
}
|
}
|
||||||
|
@ -2591,6 +2669,7 @@ void LastCrashedWindow::updateControls() {
|
||||||
_getApp.hide();
|
_getApp.hide();
|
||||||
_pleaseSendReport.hide();
|
_pleaseSendReport.hide();
|
||||||
_yourReportName.hide();
|
_yourReportName.hide();
|
||||||
|
_includeUsername.hide();
|
||||||
_showReport.hide();
|
_showReport.hide();
|
||||||
_report.hide();
|
_report.hide();
|
||||||
_minidump.hide();
|
_minidump.hide();
|
||||||
|
@ -2613,6 +2692,7 @@ void LastCrashedWindow::updateControls() {
|
||||||
if (_sendingState == SendingNoReport) {
|
if (_sendingState == SendingNoReport) {
|
||||||
_pleaseSendReport.hide();
|
_pleaseSendReport.hide();
|
||||||
_yourReportName.hide();
|
_yourReportName.hide();
|
||||||
|
_includeUsername.hide();
|
||||||
_showReport.hide();
|
_showReport.hide();
|
||||||
_report.hide();
|
_report.hide();
|
||||||
_minidump.hide();
|
_minidump.hide();
|
||||||
|
@ -2625,6 +2705,12 @@ void LastCrashedWindow::updateControls() {
|
||||||
h += _showReport.height() + padding + _yourReportName.height() + padding;
|
h += _showReport.height() + padding + _yourReportName.height() + padding;
|
||||||
_pleaseSendReport.show();
|
_pleaseSendReport.show();
|
||||||
_yourReportName.show();
|
_yourReportName.show();
|
||||||
|
if (_reportUsername.isEmpty()) {
|
||||||
|
_includeUsername.hide();
|
||||||
|
} else {
|
||||||
|
h += _includeUsername.height() + padding;
|
||||||
|
_includeUsername.show();
|
||||||
|
}
|
||||||
if (_reportShown) {
|
if (_reportShown) {
|
||||||
h += (_pleaseSendReport.height() * 12.5) + padding + (_minidumpName.isEmpty() ? 0 : (_minidump.height() + padding));
|
h += (_pleaseSendReport.height() * 12.5) + padding + (_minidumpName.isEmpty() ? 0 : (_minidump.height() + padding));
|
||||||
_report.show();
|
_report.show();
|
||||||
|
@ -2867,6 +2953,7 @@ void LastCrashedWindow::resizeEvent(QResizeEvent *e) {
|
||||||
_pleaseSendReport.move(padding, padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + (_showReport.height() - _pleaseSendReport.height()) / 2);
|
_pleaseSendReport.move(padding, padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + (_showReport.height() - _pleaseSendReport.height()) / 2);
|
||||||
_showReport.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding);
|
_showReport.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding);
|
||||||
_yourReportName.move(padding, _showReport.y() + _showReport.height() + padding);
|
_yourReportName.move(padding, _showReport.y() + _showReport.height() + padding);
|
||||||
|
_includeUsername.move(padding, _yourReportName.y() + _yourReportName.height() + padding);
|
||||||
_getApp.move((width() - _getApp.width()) / 2, _showReport.y() + _showReport.height() + padding);
|
_getApp.move((width() - _getApp.width()) / 2, _showReport.y() + _showReport.height() + padding);
|
||||||
|
|
||||||
if (_sendingState == SendingFail || _sendingState == SendingProgress) {
|
if (_sendingState == SendingFail || _sendingState == SendingProgress) {
|
||||||
|
@ -2888,10 +2975,15 @@ void LastCrashedWindow::resizeEvent(QResizeEvent *e) {
|
||||||
_pleaseSendReport.move(padding, padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding + (_showReport.height() - _pleaseSendReport.height()) / 2);
|
_pleaseSendReport.move(padding, padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding + (_showReport.height() - _pleaseSendReport.height()) / 2);
|
||||||
_showReport.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding);
|
_showReport.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding);
|
||||||
_yourReportName.move(padding, _showReport.y() + _showReport.height() + padding);
|
_yourReportName.move(padding, _showReport.y() + _showReport.height() + padding);
|
||||||
|
_includeUsername.move(padding, _yourReportName.y() + _yourReportName.height() + padding);
|
||||||
|
|
||||||
_networkSettings.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding);
|
_networkSettings.move(padding * 2 + _pleaseSendReport.width(), padding * 2 + _networkSettings.height() + _networkSettings.height() + padding + _getApp.height() + padding);
|
||||||
#endif
|
#endif
|
||||||
_report.setGeometry(padding, _yourReportName.y() + _yourReportName.height() + padding, width() - 2 * padding, _pleaseSendReport.height() * 12.5);
|
if (_reportUsername.isEmpty()) {
|
||||||
|
_report.setGeometry(padding, _yourReportName.y() + _yourReportName.height() + padding, width() - 2 * padding, _pleaseSendReport.height() * 12.5);
|
||||||
|
} else {
|
||||||
|
_report.setGeometry(padding, _includeUsername.y() + _includeUsername.height() + padding, width() - 2 * padding, _pleaseSendReport.height() * 12.5);
|
||||||
|
}
|
||||||
_minidump.move(padding, _report.y() + _report.height() + padding);
|
_minidump.move(padding, _report.y() + _report.height() + padding);
|
||||||
_saveReport.move(_showReport.x(), _showReport.y());
|
_saveReport.move(_showReport.x(), _showReport.y());
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,12 @@ public:
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PreLaunchCheckbox : public QCheckBox {
|
||||||
|
public:
|
||||||
|
PreLaunchCheckbox(QWidget *parent);
|
||||||
|
void setText(const QString &text);
|
||||||
|
};
|
||||||
|
|
||||||
class NotStartedWindow : public PreLaunchWindow {
|
class NotStartedWindow : public PreLaunchWindow {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -467,10 +473,16 @@ private:
|
||||||
PreLaunchLabel _label, _pleaseSendReport, _yourReportName, _minidump;
|
PreLaunchLabel _label, _pleaseSendReport, _yourReportName, _minidump;
|
||||||
PreLaunchLog _report;
|
PreLaunchLog _report;
|
||||||
PreLaunchButton _send, _sendSkip, _networkSettings, _continue, _showReport, _saveReport, _getApp;
|
PreLaunchButton _send, _sendSkip, _networkSettings, _continue, _showReport, _saveReport, _getApp;
|
||||||
|
PreLaunchCheckbox _includeUsername;
|
||||||
|
|
||||||
QString _minidumpName, _minidumpFull, _reportText;
|
QString _minidumpName, _minidumpFull, _reportText;
|
||||||
|
QString _reportUsername, _reportTextNoUsername;
|
||||||
|
QByteArray getCrashReportRaw() const;
|
||||||
|
|
||||||
bool _reportShown, _reportSaved;
|
bool _reportShown, _reportSaved;
|
||||||
|
|
||||||
|
void excludeReportUsername();
|
||||||
|
|
||||||
enum SendingState {
|
enum SendingState {
|
||||||
SendingNoReport,
|
SendingNoReport,
|
||||||
SendingUpdateCheck,
|
SendingUpdateCheck,
|
||||||
|
|
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,9,30,0
|
FILEVERSION 0,9,30,2
|
||||||
PRODUCTVERSION 0,9,30,0
|
PRODUCTVERSION 0,9,30,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.9.30.0"
|
VALUE "FileVersion", "0.9.30.2"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.9.30.0"
|
VALUE "ProductVersion", "0.9.30.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -2,5 +2,5 @@ AppVersion 9030
|
||||||
AppVersionStrMajor 0.9
|
AppVersionStrMajor 0.9
|
||||||
AppVersionStrSmall 0.9.30
|
AppVersionStrSmall 0.9.30
|
||||||
AppVersionStr 0.9.30
|
AppVersionStr 0.9.30
|
||||||
DevChannel 1
|
DevChannel 0
|
||||||
BetaVersion 0 9028002
|
BetaVersion 9030002
|
||||||
|
|
Loading…
Add table
Reference in a new issue