2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-30 22:25:12 +00:00

broadcast channels support started

This commit is contained in:
John Preston
2015-09-06 13:17:09 +03:00
parent 95ff7821a3
commit b53e35e046
31 changed files with 1006 additions and 525 deletions

View File

@@ -33,7 +33,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
#include "audio.h"
TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w),
a_over(0), _drawShadow(true), _selCount(0), _selStrLeft(-st::topBarButton.width / 2), _selStrWidth(0), _animating(false),
a_over(0), _drawShadow(true), _selPeer(0), _selCount(0), _selStrLeft(-st::topBarButton.width / 2), _selStrWidth(0), _animating(false),
_clearSelection(this, lang(lng_selected_clear), st::topBarButton),
_forward(this, lang(lng_selected_forward), st::topBarActionButton),
_delete(this, lang(lng_selected_delete), st::topBarActionButton),
@@ -201,7 +201,7 @@ void TopBarWidget::mousePressEvent(QMouseEvent *e) {
void TopBarWidget::resizeEvent(QResizeEvent *e) {
int32 r = width();
if (!_forward.isHidden()) {
if (!_forward.isHidden() || !_delete.isHidden()) {
int32 fullW = r - (_selectionButtonsWidth + (_selStrWidth - st::topBarButton.width) + st::topBarActionSkip);
int32 selectedClearWidth = st::topBarButton.width, forwardDeleteWidth = st::topBarActionButton.width - _forwardDeleteWidth, skip = st::topBarActionSkip;
while (fullW < 0) {
@@ -242,8 +242,14 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
_selStrLeft = -selectedClearWidth / 2;
int32 availX = _selStrLeft + _selStrWidth, availW = r - (_clearSelection.width() + selectedClearWidth / 2) - availX;
_forward.move(availX + (availW - _forward.width() - _delete.width() - skip) / 2, (st::topBarHeight - _forward.height()) / 2);
_delete.move(availX + (availW + _forward.width() - _delete.width() + skip) / 2, (st::topBarHeight - _forward.height()) / 2);
if (_forward.isHidden()) {
_delete.move(availX + (availW - _delete.width()) / 2, (st::topBarHeight - _forward.height()) / 2);
} else if (_delete.isHidden()) {
_forward.move(availX + (availW - _forward.width()) / 2, (st::topBarHeight - _forward.height()) / 2);
} else {
_forward.move(availX + (availW - _forward.width() - _delete.width() - skip) / 2, (st::topBarHeight - _forward.height()) / 2);
_delete.move(availX + (availW + _forward.width() - _delete.width() + skip) / 2, (st::topBarHeight - _forward.height()) / 2);
}
_clearSelection.move(r -= _clearSelection.width(), 0);
}
if (!_info.isHidden()) _info.move(r -= _info.width(), 0);
@@ -316,7 +322,11 @@ void TopBarWidget::showAll() {
if (!p && _selCount) {
_clearSelection.show();
_delete.show();
_forward.show();
if (!_selPeer || _selPeer->isChannel()) {
_forward.hide();
} else {
_forward.show();
}
_mediaType.hide();
} else {
_clearSelection.hide();
@@ -339,6 +349,7 @@ void TopBarWidget::showAll() {
void TopBarWidget::showSelected(uint32 selCount) {
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
_selPeer = App::main()->overviewPeer() ? App::main()->overviewPeer() : App::main()->peer();
_selCount = selCount;
_selStr = (_selCount > 0) ? lng_selected_count(lt_count, _selCount) : QString();
_selStrWidth = st::btnDefLink.font->m.width(_selStr);
@@ -1085,8 +1096,14 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
flags |= MTPDmessage::flag_media;
}
bool fromChannelName = hist->peer->isChannel();
if (fromChannelName) {
sendFlags |= MTPmessages_SendMessage_flag_broadcast;
} else {
flags |= MTPDmessage::flag_from_id;
}
MTPVector<MTPMessageEntity> localEntities = linksToMTP(textParseLinks(sendingText, itemTextParseOptions(hist, App::self()).flags));
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(MTP::authedId()), peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities));
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities));
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, localEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
}
@@ -1131,10 +1148,17 @@ void MainWidget::readServerHistory(History *hist, bool force) {
if (!hist || (!force && !hist->unreadCount)) return;
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
MsgId upTo = hist->inboxRead(0);
if (i == _readRequests.cend()) {
hist->inboxRead(0);
_readRequests.insert(hist->peer, MTP::send(MTPmessages_ReadHistory(hist->peer->input, MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::partWasRead, hist->peer)));
}
sendReadRequest(hist->peer, upTo);
} else {
ReadRequestsPending::iterator i = _readRequestsPending.find(hist->peer);
if (i == _readRequestsPending.cend()) {
_readRequestsPending.insert(hist->peer, upTo);
} else if (i.value() < upTo) {
i.value() = upTo;
}
}
}
uint64 MainWidget::animActiveTime(MsgId id) const {
@@ -1447,18 +1471,47 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR
if (App::wnd()) App::wnd()->mediaOverviewUpdated(h->peer, type);
}
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
if (!MTP::authedId()) return;
if (peer->isChannel()) {
_readRequests.insert(peer, MTP::send(MTPmessages_ReadChannelHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::channelWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)));
} else {
//_readRequests.insert(peer, MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo), MTP_int(0)), rpcDone(&MainWidget::partWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)));
}
}
void MainWidget::channelWasRead(PeerData *peer, const MTPBool &result) {
readRequestDone(peer);
}
void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
updPtsUpdated(d.vpts.v, d.vpts_count.v);
int32 offset = d.voffset.v;
if (!MTP::authedId() || offset <= 0) {
_readRequests.remove(peer);
if (!MTP::authedId() || offset <= 0 || true) {
readRequestDone(peer);
} else {
_readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(0), MTP_int(offset)), rpcDone(&MainWidget::partWasRead, peer));
// _readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo), MTP_int(offset)), rpcDone(&MainWidget::partWasRead, peer));
}
}
bool MainWidget::readRequestFail(PeerData *peer, const RPCError &error) {
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
readRequestDone(peer);
return false;
}
void MainWidget::readRequestDone(PeerData *peer) {
_readRequests.remove(peer);
ReadRequestsPending::iterator i = _readRequestsPending.find(peer);
if (i != _readRequestsPending.cend()) {
sendReadRequest(peer, i.value());
_readRequestsPending.erase(i);
}
}
void MainWidget::messagesAffected(const MTPmessages_AffectedMessages &result) {
const MTPDmessages_affectedMessages &d(result.c_messages_affectedMessages());
updPtsUpdated(d.vpts.v, d.vpts_count.v);
@@ -2178,7 +2231,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
if (overview) {
_stack.push_back(new StackItemOverview(overview->peer(), overview->type(), overview->lastWidth(), overview->lastScrollTop()));
} else if (profile) {
_stack.push_back(new StackItemProfile(profile->peer(), profile->lastScrollTop(), profile->allMediaShown()));
_stack.push_back(new StackItemProfile(profile->peer(), profile->lastScrollTop()));
} else if (history.peer()) {
_peerInStack = history.peer();
_msgIdInStack = history.msgId();
@@ -2219,7 +2272,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
App::wnd()->getTitle()->updateBackButton();
}
void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop, bool allMediaShown) {
void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop) {
App::wnd()->hideSettings();
if (profile && profile->peer() == peer) return;
@@ -2232,7 +2285,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop,
if (overview) {
_stack.push_back(new StackItemOverview(overview->peer(), overview->type(), overview->lastWidth(), overview->lastScrollTop()));
} else if (profile) {
_stack.push_back(new StackItemProfile(profile->peer(), profile->lastScrollTop(), profile->allMediaShown()));
_stack.push_back(new StackItemProfile(profile->peer(), profile->lastScrollTop()));
} else {
_peerInStack = history.peer();
_msgIdInStack = history.msgId();
@@ -2255,7 +2308,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop,
profile = new ProfileWidget(this, peer);
_topBar.show();
resizeEvent(0);
profile->animShow(animCache, animTopBarCache, back, lastScrollTop, allMediaShown);
profile->animShow(animCache, animTopBarCache, back, lastScrollTop);
history.animStop();
if (back) clearBotStartToken(history.peer());
history.showPeerHistory(0, 0);
@@ -2291,7 +2344,7 @@ void MainWidget::showBackFromStack() {
if (histItem->kbWasHidden) history.setKbWasHidden();
} else if (item->type() == ProfileStackItem) {
StackItemProfile *profItem = static_cast<StackItemProfile*>(item);
showPeerProfile(profItem->peer, true, profItem->lastScrollTop, profItem->allMediaShown);
showPeerProfile(profItem->peer, true, profItem->lastScrollTop);
} else if (item->type() == OverviewStackItem) {
StackItemOverview *overItem = static_cast<StackItemOverview*>(item);
showMediaOverview(overItem->peer, overItem->mediaType, true, overItem->lastScrollTop);
@@ -2866,7 +2919,7 @@ void MainWidget::openLocalUrl(const QString &url) {
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+))?(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
if (m.hasMatch()) {
QString start = m.captured(3), startToken = m.captured(4);
openUserByName(m.captured(1), (start == qsl("startgroup")), startToken);
openPeerByName(m.captured(1), (start == qsl("startgroup")), startToken);
}
} else if (u.startsWith(qstr("tg://join"), Qt::CaseInsensitive)) {
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
@@ -2881,27 +2934,27 @@ void MainWidget::openLocalUrl(const QString &url) {
}
}
void MainWidget::openUserByName(const QString &username, bool toProfile, const QString &startToken) {
void MainWidget::openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
App::wnd()->hideMediaview();
UserData *user = App::userByName(username);
if (user) {
PeerData *peer = App::peerByName(username);
if (peer) {
if (toProfile) {
if (user->botInfo && !user->botInfo->cantJoinGroups && !startToken.isEmpty()) {
user->botInfo->startGroupToken = startToken;
App::wnd()->showLayer(new ContactsBox(user));
if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) {
peer->asUser()->botInfo->startGroupToken = startToken;
App::wnd()->showLayer(new ContactsBox(peer->asUser()));
} else {
showPeerProfile(user);
showPeerProfile(peer);
}
} else {
if (user->botInfo) {
user->botInfo->startToken = startToken;
if (user == history.peer()) {
if (peer->isUser() && peer->asUser()->botInfo) {
peer->asUser()->botInfo->startToken = startToken;
if (peer == history.peer()) {
history.updateControlsVisibility();
history.resizeEvent(0);
}
}
emit showPeerAsync(user->id, 0);
emit showPeerAsync(peer->id, 0);
}
} else {
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, qMakePair(toProfile, startToken)), rpcFail(&MainWidget::usernameResolveFail, username));
@@ -2925,25 +2978,33 @@ void MainWidget::onStickersInstalled(uint64 setId) {
history.stickersInstalled(setId);
}
void MainWidget::usernameResolveDone(QPair<bool, QString> toProfileStartToken, const MTPUser &result) {
void MainWidget::usernameResolveDone(QPair<bool, QString> toProfileStartToken, const MTPcontacts_ResolvedPeer &result) {
App::wnd()->hideLayer();
UserData *user = App::feedUsers(MTP_vector<MTPUser>(1, result));
if (result.type() != mtpc_contacts_resolvedPeer) return;
const MTPDcontacts_resolvedPeer &d(result.c_contacts_resolvedPeer());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
PeerId peerId = peerFromMTP(d.vpeer);
if (!peerId) return;
PeerData *peer = App::peer(peerId);
if (toProfileStartToken.first) {
if (user->botInfo && !user->botInfo->cantJoinGroups && !toProfileStartToken.second.isEmpty()) {
user->botInfo->startGroupToken = toProfileStartToken.second;
App::wnd()->showLayer(new ContactsBox(user));
if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !toProfileStartToken.second.isEmpty()) {
peer->asUser()->botInfo->startGroupToken = toProfileStartToken.second;
App::wnd()->showLayer(new ContactsBox(peer->asUser()));
} else {
showPeerProfile(user);
showPeerProfile(peer);
}
} else {
if (user->botInfo) {
user->botInfo->startToken = toProfileStartToken.second;
if (user == history.peer()) {
if (peer->isUser() && peer->asUser()->botInfo) {
peer->asUser()->botInfo->startToken = toProfileStartToken.second;
if (peer == history.peer()) {
history.updateControlsVisibility();
history.resizeEvent(0);
}
}
showPeerHistory(user->id, ShowAtUnreadMsgId);
showPeerHistory(peer->id, ShowAtUnreadMsgId);
}
}
@@ -3517,22 +3578,6 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateNewChannelMessage: {
const MTPDupdateNewChannelMessage &d(update.c_updateNewChannelMessage());
//if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { // CHANNELS_TODO
// _byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
// return;
//}
if (d.vmessage.type() == mtpc_message) { // index forwarded messages to links overview
App::checkEntitiesUpdate(d.vmessage.c_message());
}
HistoryItem *item = App::histories().addToBack(d.vmessage);
if (item) {
history.peerMessagesUpdated(item->history()->peer->id);
}
} break;
case mtpc_updateMessageID: {
const MTPDupdateMessageID &d(update.c_updateMessageID());
FullMsgId msg = App::histItemByRandom(d.vrandom_id.v);
@@ -3811,5 +3856,49 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updatePrivacy: {
const MTPDupdatePrivacy &d(update.c_updatePrivacy());
} break;
case mtpc_updateNewChannelMessage: {
const MTPDupdateNewChannelMessage &d(update.c_updateNewChannelMessage());
//if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { // CHANNELS_TODO
// _byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
// return;
//}
if (d.vmessage.type() == mtpc_message) { // index forwarded messages to links overview
App::checkEntitiesUpdate(d.vmessage.c_message());
}
HistoryItem *item = App::histories().addToBack(d.vmessage);
if (item) {
history.peerMessagesUpdated(item->history()->peer->id);
}
} break;
case mtpc_updateReadChannelInbox: {
const MTPDupdateReadChannelInbox &d(update.c_updateReadChannelInbox());
//if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { // CHANNELS_TODO
// _byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
// return;
//}
App::feedInboxRead(peerFromMTP(d.vpeer), d.vmax_id.v);
} break;
case mtpc_updateDeleteChannelMessages: {
const MTPDupdateDeleteChannelMessages &d(update.c_updateDeleteChannelMessages());
//if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { // CHANNELS_TODO
// _byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
// return;
//}
App::feedWereDeleted(peerToChannel(peerFromMTP(d.vpeer)), d.vmessages.c_vector().v);
history.peerMessagesUpdated();
} break;
case mtpc_updateChannelGroup: {
const MTPDupdateChannelGroup &d(update.c_updateChannelGroup());
} break;
case mtpc_updateChannelTooLong: {
const MTPDupdateChannelTooLong &d(update.c_updateChannelTooLong());
} break;
}
}