Add supergroup restriction placeholders / labels.

This commit is contained in:
John Preston 2017-06-11 20:33:20 +02:00
parent 7d2d5c6100
commit 5c0a1bafe2
15 changed files with 462 additions and 59 deletions

View File

@ -141,7 +141,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_error_pinned_max#other" = "Sorry, you can pin no more than {count} chats to the top."; "lng_error_pinned_max#other" = "Sorry, you can pin no more than {count} chats to the top.";
"lng_error_public_groups_denied" = "Unfortunately, you were banned from participating in public groups.\n{more_info}"; "lng_error_public_groups_denied" = "Unfortunately, you were banned from participating in public groups.\n{more_info}";
"lng_error_cant_edit_admin" = "Sorry, you can't edit permissions for this admin."; "lng_error_cant_edit_admin" = "Sorry, you can't edit permissions for this admin.";
"lng_error_cant_add_member" = "Sorry, you can't add the bot to this group."; "lng_error_cant_add_member" = "Sorry, you can't add the bot to this group. Ask a group admin to do it.";
"lng_edit_deleted" = "This message was deleted"; "lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long"; "lng_edit_too_long" = "Your message text is too long";
@ -1060,8 +1060,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_forward_cant" = "Sorry, no way to forward here :("; "lng_forward_cant" = "Sorry, no way to forward here :(";
"lng_forward_confirm" = "Forward to {recipient}?"; "lng_forward_confirm" = "Forward to {recipient}?";
"lng_forward_share_contact" = "Share contact to {recipient}?"; "lng_forward_share_contact" = "Share contact to {recipient}?";
"lng_forward_share_cant" = "Sorry, no way to share contact here :(";
"lng_forward_send_file_confirm" = "Send «{name}» to {recipient}?"; "lng_forward_send_file_confirm" = "Send «{name}» to {recipient}?";
"lng_forward_send_files_confirm" = "Send selected files to {recipient}?"; "lng_forward_send_files_confirm" = "Send selected files to {recipient}?";
"lng_forward_send_files_cant" = "Sorry, no way to send media here :(";
"lng_forward_send" = "Send"; "lng_forward_send" = "Send";
"lng_forward_messages#one" = "{count} forwarded message"; "lng_forward_messages#one" = "{count} forwarded message";
"lng_forward_messages#other" = "{count} forwarded messages"; "lng_forward_messages#other" = "{count} forwarded messages";
@ -1275,6 +1277,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_rights_chat_banned_forever" = "Forever"; "lng_rights_chat_banned_forever" = "Forever";
"lng_rights_chat_banned_block" = "Block and remove from group"; "lng_rights_chat_banned_block" = "Block and remove from group";
"lng_restricted_send_message" = "The admins of this group restricted you from writing here.";
"lng_restricted_send_media" = "The admins of this group restricted you from posting media content here.";
"lng_restricted_send_stickers" = "The admins of this group restricted you from posting stickers here.";
"lng_restricted_send_gifs" = "The admins of this group restricted you from posting GIFs here.";
"lng_restricted_send_inline" = "The admins of this group restricted you from posting inline content here.";
// Not used // Not used
"lng_topbar_info" = "Info"; "lng_topbar_info" = "Info";

View File

@ -884,6 +884,25 @@ void shareGameScoreFromItem(HistoryItem *item) {
if (!data->requests.empty()) { if (!data->requests.empty()) {
return; // Share clicked already. return; // Share clicked already.
} }
if (result.empty()) {
return;
}
auto restrictedEverywhere = true;
auto restrictedSomewhere = false;
for_const (auto peer, result) {
if (auto megagroup = peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_games()) {
restrictedSomewhere = true;
continue;
}
}
restrictedEverywhere = false;
}
if (restrictedEverywhere) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_inline)), KeepOtherLayers);
return;
}
auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) { auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) {
if (auto main = App::main()) { if (auto main = App::main()) {
@ -901,6 +920,12 @@ void shareGameScoreFromItem(HistoryItem *item) {
if (auto main = App::main()) { if (auto main = App::main()) {
if (auto item = App::histItemById(data->msgId)) { if (auto item = App::histItemById(data->msgId)) {
for_const (auto peer, result) { for_const (auto peer, result) {
if (auto megagroup = peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_games()) {
continue;
}
}
MTPVector<MTPlong> random = MTP_vector<MTPlong>(1, rand_value<MTPlong>()); MTPVector<MTPlong> random = MTP_vector<MTPlong>(1, rand_value<MTPlong>());
auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input); auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input);
auto callback = doneCallback; auto callback = doneCallback;

View File

@ -28,6 +28,11 @@ switchPmButton: RoundButton(defaultBoxButton) {
height: 34px; height: 34px;
textTop: 7px; textTop: 7px;
} }
stickersRestrictedLabel: FlatLabel(defaultFlatLabel) {
width: 320px;
align: align(center);
textFg: noContactsColor;
}
stickersTrendingHeader: 45px; stickersTrendingHeader: 45px;
stickersTrendingSkip: 15px; stickersTrendingSkip: 15px;

View File

@ -26,12 +26,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "chat_helpers/stickers.h" #include "chat_helpers/stickers.h"
#include "styles/style_chat_helpers.h" #include "styles/style_chat_helpers.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/shadow.h" #include "ui/widgets/shadow.h"
#include "ui/widgets/discrete_sliders.h" #include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/scroll_area.h" #include "ui/widgets/scroll_area.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "observer_peer.h"
namespace ChatHelpers { namespace ChatHelpers {
namespace { namespace {
@ -46,7 +48,7 @@ public:
LeftToRight, LeftToRight,
RightToLeft, RightToLeft,
}; };
void setFinalImages(Direction direction, QImage &&left, QImage &&right, QRect inner); void setFinalImages(Direction direction, QImage &&left, QImage &&right, QRect inner, bool wasSectionIcons);
void start(); void start();
void paintFrame(QPainter &p, float64 dt, float64 opacity); void paintFrame(QPainter &p, float64 dt, float64 opacity);
@ -72,10 +74,11 @@ private:
int _painterInnerRight = 0; int _painterInnerRight = 0;
int _frameIntsPerLineAdd = 0; int _frameIntsPerLineAdd = 0;
bool _wasSectionIcons = false;
}; };
void TabbedSelector::SlideAnimation::setFinalImages(Direction direction, QImage &&left, QImage &&right, QRect inner) { void TabbedSelector::SlideAnimation::setFinalImages(Direction direction, QImage &&left, QImage &&right, QRect inner, bool wasSectionIcons) {
Expects(!started()); Expects(!started());
_direction = direction; _direction = direction;
_leftImage = QPixmap::fromImage(std::move(left).convertToFormat(QImage::Format_ARGB32_Premultiplied), Qt::ColorOnly); _leftImage = QPixmap::fromImage(std::move(left).convertToFormat(QImage::Format_ARGB32_Premultiplied), Qt::ColorOnly);
@ -109,6 +112,8 @@ void TabbedSelector::SlideAnimation::setFinalImages(Direction direction, QImage
_painterInnerWidth = _innerWidth / cIntRetinaFactor(); _painterInnerWidth = _innerWidth / cIntRetinaFactor();
_painterInnerHeight = _innerHeight / cIntRetinaFactor(); _painterInnerHeight = _innerHeight / cIntRetinaFactor();
_painterCategoriesTop = _painterInnerBottom - st::emojiCategory.height; _painterCategoriesTop = _painterInnerBottom - st::emojiCategory.height;
_wasSectionIcons = wasSectionIcons;
} }
void TabbedSelector::SlideAnimation::start() { void TabbedSelector::SlideAnimation::start() {
@ -166,7 +171,7 @@ void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64
Painter p(&_frame); Painter p(&_frame);
p.setOpacity(opacity); p.setOpacity(opacity);
p.fillRect(_painterInnerLeft, _painterInnerTop, _painterInnerWidth, _painterCategoriesTop - _painterInnerTop, st::emojiPanBg); p.fillRect(_painterInnerLeft, _painterInnerTop, _painterInnerWidth, _painterCategoriesTop - _painterInnerTop, st::emojiPanBg);
p.fillRect(_painterInnerLeft, _painterCategoriesTop, _painterInnerWidth, _painterInnerBottom - _painterCategoriesTop, st::emojiPanCategories); p.fillRect(_painterInnerLeft, _painterCategoriesTop, _painterInnerWidth, _painterInnerBottom - _painterCategoriesTop, _wasSectionIcons ? st::emojiPanCategories : st::emojiPanBg);
p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setCompositionMode(QPainter::CompositionMode_SourceOver);
if (leftTo > _innerLeft) { if (leftTo > _innerLeft) {
p.setOpacity(opacity * leftAlpha); p.setOpacity(opacity * leftAlpha);
@ -337,6 +342,12 @@ TabbedSelector::TabbedSelector(QWidget *parent, gsl::not_null<Window::Controller
_bottomShadow->raise(); _bottomShadow->raise();
_tabsSlider->raise(); _tabsSlider->raise();
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelRightsChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _currentPeer) {
checkRestrictedPeer();
}
}));
// setAttribute(Qt::WA_AcceptTouchEvents); // setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_OpaquePaintEvent, false);
showAll(); showAll();
@ -354,6 +365,9 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
_scroll->resize(_scroll->width(), contentHeight); _scroll->resize(_scroll->width(), contentHeight);
} }
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth); _bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
if (_restrictedLabel) {
_restrictedLabel->move((width() - _restrictedLabel->width()), (height() / 3 - _restrictedLabel->height() / 2));
}
_footerTop = height() - st::emojiCategory.height; _footerTop = height() - st::emojiCategory.height;
for (auto &tab : _tabs) { for (auto &tab : _tabs) {
@ -394,8 +408,7 @@ void TabbedSelector::paintSlideFrame(Painter &p, TimeMs ms) {
} }
void TabbedSelector::paintContent(Painter &p) { void TabbedSelector::paintContent(Painter &p) {
auto showSectionIcons = (_currentTabType != SelectorTab::Gifs); auto &bottomBg = hasSectionIcons() ? st::emojiPanCategories : st::emojiPanBg;
auto &bottomBg = showSectionIcons ? st::emojiPanCategories : st::emojiPanBg;
if (_roundRadius > 0) { if (_roundRadius > 0) {
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius); auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom); App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
@ -410,8 +423,12 @@ void TabbedSelector::paintContent(Painter &p) {
auto sidesTop = marginTop(); auto sidesTop = marginTop();
auto sidesHeight = height() - sidesTop - marginBottom(); auto sidesHeight = height() - sidesTop - marginBottom();
p.fillRect(myrtlrect(width() - st::emojiScroll.width, sidesTop, st::emojiScroll.width, sidesHeight), st::emojiPanBg); if (_restrictedLabel) {
p.fillRect(myrtlrect(0, sidesTop, st::buttonRadius, sidesHeight), st::emojiPanBg); p.fillRect(0, sidesTop, width(), sidesHeight, st::emojiPanBg);
} else {
p.fillRect(myrtlrect(width() - st::emojiScroll.width, sidesTop, st::emojiScroll.width, sidesHeight), st::emojiPanBg);
p.fillRect(myrtlrect(0, sidesTop, st::buttonRadius, sidesHeight), st::emojiPanBg);
}
} }
int TabbedSelector::marginTop() const { int TabbedSelector::marginTop() const {
@ -504,15 +521,56 @@ void TabbedSelector::stickersInstalled(uint64 setId) {
stickers()->showStickerSet(setId); stickers()->showStickerSet(setId);
} }
void TabbedSelector::setInlineQueryPeer(PeerData *peer) { void TabbedSelector::setCurrentPeer(PeerData *peer) {
gifs()->setInlineQueryPeer(peer); gifs()->setInlineQueryPeer(peer);
_currentPeer = peer;
checkRestrictedPeer();
}
void TabbedSelector::checkRestrictedPeer() {
if (auto megagroup = _currentPeer ? _currentPeer->asMegagroup() : nullptr) {
auto restricted = (_currentTabType == SelectorTab::Stickers) ? megagroup->restrictedRights().is_send_stickers() :
(_currentTabType == SelectorTab::Gifs) ? megagroup->restrictedRights().is_send_gifs() : false;
if (restricted) {
if (!_restrictedLabel) {
auto text = (_currentTabType == SelectorTab::Stickers) ? lang(lng_restricted_send_stickers) :
(_currentTabType == SelectorTab::Gifs) ? lang(lng_restricted_send_gifs) : false;
_restrictedLabel.create(this, text, Ui::FlatLabel::InitType::Simple, st::stickersRestrictedLabel);
_restrictedLabel->show();
_restrictedLabel->move((width() - _restrictedLabel->width()), (height() / 3 - _restrictedLabel->height() / 2));
currentTab()->footer()->hide();
_scroll->hide();
_bottomShadow->hide();
update();
}
return;
}
}
if (_restrictedLabel) {
_restrictedLabel.destroy();
if (!_a_slide.animating()) {
currentTab()->footer()->show();
_scroll->show();
_bottomShadow->setVisible(_currentTabType == SelectorTab::Gifs);
update();
}
}
}
bool TabbedSelector::isRestrictedView() {
checkRestrictedPeer();
return (_restrictedLabel != nullptr);
} }
void TabbedSelector::showAll() { void TabbedSelector::showAll() {
currentTab()->footer()->show(); if (isRestrictedView()) {
_scroll->show(); _restrictedLabel->show();
} else {
currentTab()->footer()->show();
_scroll->show();
_bottomShadow->setVisible(_currentTabType == SelectorTab::Gifs);
}
_topShadow->show(); _topShadow->show();
_bottomShadow->setVisible(_currentTabType == SelectorTab::Gifs);
_tabsSlider->show(); _tabsSlider->show();
} }
@ -551,6 +609,10 @@ void TabbedSelector::createTabsSlider() {
_topShadow->setGeometry(_tabsSlider->x(), _tabsSlider->bottomNoMargins() - st::lineWidth, _tabsSlider->width(), st::lineWidth); _topShadow->setGeometry(_tabsSlider->x(), _tabsSlider->bottomNoMargins() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
} }
bool TabbedSelector::hasSectionIcons() const {
return (_currentTabType != SelectorTab::Gifs) && !_restrictedLabel;
}
void TabbedSelector::switchTab() { void TabbedSelector::switchTab() {
auto tab = _tabsSlider->activeSection(); auto tab = _tabsSlider->activeSection();
t_assert(tab >= 0 && tab < Tab::kCount); t_assert(tab >= 0 && tab < Tab::kCount);
@ -559,6 +621,7 @@ void TabbedSelector::switchTab() {
return; return;
} }
auto wasSectionIcons = hasSectionIcons();
auto wasTab = _currentTabType; auto wasTab = _currentTabType;
currentTab()->saveScrollTop(); currentTab()->saveScrollTop();
@ -573,6 +636,9 @@ void TabbedSelector::switchTab() {
currentTab()->returnWidget(std::move(widget)); currentTab()->returnWidget(std::move(widget));
_currentTabType = newTabType; _currentTabType = newTabType;
_restrictedLabel.destroy();
checkRestrictedPeer();
currentTab()->widget()->refreshRecent(); currentTab()->widget()->refreshRecent();
currentTab()->widget()->preloadImages(); currentTab()->widget()->preloadImages();
setWidgetToScrollArea(); setWidgetToScrollArea();
@ -585,7 +651,7 @@ void TabbedSelector::switchTab() {
} }
_slideAnimation = std::make_unique<SlideAnimation>(); _slideAnimation = std::make_unique<SlideAnimation>();
auto slidingRect = QRect(_tabsSlider->x() * cIntRetinaFactor(), _scroll->y() * cIntRetinaFactor(), _tabsSlider->width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor()); auto slidingRect = QRect(_tabsSlider->x() * cIntRetinaFactor(), _scroll->y() * cIntRetinaFactor(), _tabsSlider->width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor());
_slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect); _slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect, wasSectionIcons);
auto corners = App::cornersMask(ImageRoundRadius::Small); auto corners = App::cornersMask(ImageRoundRadius::Small);
_slideAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3])); _slideAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3]));
_slideAnimation->start(); _slideAnimation->start();

View File

@ -33,6 +33,7 @@ namespace Ui {
class PlainShadow; class PlainShadow;
class ScrollArea; class ScrollArea;
class SettingsSlider; class SettingsSlider;
class FlatLabel;
} // namesapce Ui } // namesapce Ui
namespace Window { namespace Window {
@ -51,7 +52,7 @@ class EmojiListWidget;
class StickersListWidget; class StickersListWidget;
class GifsListWidget; class GifsListWidget;
class TabbedSelector : public TWidget { class TabbedSelector : public TWidget, private base::Subscriber {
Q_OBJECT Q_OBJECT
public: public:
@ -60,7 +61,7 @@ public:
void setRoundRadius(int radius); void setRoundRadius(int radius);
void refreshStickers(); void refreshStickers();
void stickersInstalled(uint64 setId); void stickersInstalled(uint64 setId);
void setInlineQueryPeer(PeerData *peer); void setCurrentPeer(PeerData *peer);
void hideFinished(); void hideFinished();
void showStarted(); void showStarted();
@ -150,6 +151,9 @@ private:
void paintSlideFrame(Painter &p, TimeMs ms); void paintSlideFrame(Painter &p, TimeMs ms);
void paintContent(Painter &p); void paintContent(Painter &p);
void checkRestrictedPeer();
bool isRestrictedView();
QImage grabForAnimation(); QImage grabForAnimation();
void scrollToY(int y); void scrollToY(int y);
@ -157,6 +161,7 @@ private:
void showAll(); void showAll();
void hideForSliding(); void hideForSliding();
bool hasSectionIcons() const;
void setWidgetToScrollArea(); void setWidgetToScrollArea();
void createTabsSlider(); void createTabsSlider();
void switchTab(); void switchTab();
@ -178,6 +183,7 @@ private:
int _roundRadius = 0; int _roundRadius = 0;
int _footerTop = 0; int _footerTop = 0;
PeerData *_currentPeer = nullptr;
class SlideAnimation; class SlideAnimation;
std::unique_ptr<SlideAnimation> _slideAnimation; std::unique_ptr<SlideAnimation> _slideAnimation;
@ -187,6 +193,7 @@ private:
object_ptr<Ui::PlainShadow> _topShadow; object_ptr<Ui::PlainShadow> _topShadow;
object_ptr<Ui::PlainShadow> _bottomShadow; object_ptr<Ui::PlainShadow> _bottomShadow;
object_ptr<Ui::ScrollArea> _scroll; object_ptr<Ui::ScrollArea> _scroll;
object_ptr<Ui::FlatLabel> _restrictedLabel = { nullptr };
std::array<Tab, Tab::kCount> _tabs; std::array<Tab, Tab::kCount> _tabs;
SelectorTab _currentTabType = SelectorTab::Emoji; SelectorTab _currentTabType = SelectorTab::Emoji;

View File

@ -2947,10 +2947,9 @@ void DialogsWidget::updateDragInScroll(bool inScroll) {
void DialogsWidget::dropEvent(QDropEvent *e) { void DialogsWidget::dropEvent(QDropEvent *e) {
_chooseByDragTimer.stop(); _chooseByDragTimer.stop();
if (_scroll->geometry().contains(e->pos())) { if (_scroll->geometry().contains(e->pos())) {
PeerData *p = _inner->updateFromParentDrag(mapToGlobal(e->pos())); if (auto peer = _inner->updateFromParentDrag(mapToGlobal(e->pos()))) {
if (p) {
e->acceptProposedAction(); e->acceptProposedAction();
App::main()->onFilesOrForwardDrop(p->id, e->mimeData()); App::main()->onFilesOrForwardDrop(peer->id, e->mimeData());
} }
} }
} }

View File

@ -85,6 +85,8 @@ constexpr auto kTabbedSelectorToggleTooltipCount = 3;
constexpr auto kScrollToVoiceAfterScrolledMs = 1000; constexpr auto kScrollToVoiceAfterScrolledMs = 1000;
constexpr auto kSkipRepaintWhileScrollMs = 100; constexpr auto kSkipRepaintWhileScrollMs = 100;
constexpr auto kShowMembersDropdownTimeoutMs = 300; constexpr auto kShowMembersDropdownTimeoutMs = 300;
constexpr auto kDisplayEditTimeWarningMs = 300 * 1000;
constexpr auto kFullDayInMs = 86400 * 1000;
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() { ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
return [](ChannelData *channel, MsgId msgId) { return [](ChannelData *channel, MsgId msgId) {
@ -363,8 +365,16 @@ bool HistoryHider::offerPeer(PeerId peer) {
} }
_offered = App::peer(peer); _offered = App::peer(peer);
auto phrase = QString(); auto phrase = QString();
QString recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB'; auto recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB';
if (_sharedContact) { if (_sharedContact) {
if (!_offered->canWrite()) {
Ui::show(Box<InformBox>(lang(lng_forward_share_cant)));
_offered = nullptr;
_toText.setText(st::boxLabelStyle, QString());
_toTextWidth = 0;
resizeEvent(nullptr);
return false;
}
phrase = lng_forward_share_contact(lt_recipient, recipient); phrase = lng_forward_share_contact(lt_recipient, recipient);
} else if (_sendPath) { } else if (_sendPath) {
auto toId = _offered->id; auto toId = _offered->id;
@ -650,6 +660,11 @@ HistoryWidget::HistoryWidget(QWidget *parent, gsl::not_null<Window::Controller*>
scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to); scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to);
} }
}); });
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelRightsChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _peer) {
onPreviewCheck();
}
}));
orderWidgets(); orderWidgets();
} }
@ -1879,7 +1894,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_peer = App::peer(peerId); _peer = App::peer(peerId);
_channel = peerToChannel(_peer->id); _channel = peerToChannel(_peer->id);
_canSendMessages = canSendMessages(_peer); _canSendMessages = canSendMessages(_peer);
_tabbedSelector->setInlineQueryPeer(_peer); _tabbedSelector->setCurrentPeer(_peer);
} }
updateTopBarSelection(); updateTopBarSelection();
@ -2143,6 +2158,13 @@ bool HistoryWidget::canWriteMessage() const {
return true; return true;
} }
bool HistoryWidget::isRestrictedWrite() const {
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
return megagroup->restrictedRights().is_send_messages();
}
return false;
}
void HistoryWidget::updateControlsVisibility() { void HistoryWidget::updateControlsVisibility() {
if (!_a_show.animating()) { if (!_a_show.animating()) {
_topShadow->setVisible(_peer != nullptr); _topShadow->setVisible(_peer != nullptr);
@ -3198,7 +3220,13 @@ void HistoryWidget::step_recording(float64 ms, bool timer) {
} }
void HistoryWidget::chooseAttach() { void HistoryWidget::chooseAttach() {
if (!_history) return; if (!_peer || !_peer->canWrite()) return;
if (auto megagroup = _peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_media()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)));
return;
}
}
auto filter = FileDialog::AllFilesFilter() + qsl(";;Image files (*") + cImgExtensions().join(qsl(" *")) + qsl(")"); auto filter = FileDialog::AllFilesFilter() + qsl(";;Image files (*") + cImgExtensions().join(qsl(" *")) + qsl(")");
@ -3297,6 +3325,13 @@ void HistoryWidget::recordStartCallback() {
if (!Media::Capture::instance()->available()) { if (!Media::Capture::instance()->available()) {
return; return;
} }
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restrictedRights().is_send_media()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)));
return;
}
}
emit Media::Capture::instance()->start(); emit Media::Capture::instance()->start();
_recording = _inField = true; _recording = _inField = true;
@ -4307,6 +4342,12 @@ bool HistoryWidget::confirmSendingFiles(const QStringList &files, CompressConfir
} }
bool HistoryWidget::confirmSendingFiles(const SendingFilesLists &lists, CompressConfirm compressed, const QString *addedComment) { bool HistoryWidget::confirmSendingFiles(const SendingFilesLists &lists, CompressConfirm compressed, const QString *addedComment) {
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restrictedRights().is_send_media()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)));
return false;
}
}
return validateSendingFiles(lists, [this, &lists, compressed, addedComment](const QStringList &files) { return validateSendingFiles(lists, [this, &lists, compressed, addedComment](const QStringList &files) {
auto insertTextOnCancel = QString(); auto insertTextOnCancel = QString();
auto sendCallback = [this](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, MsgId replyTo) { auto sendCallback = [this](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, MsgId replyTo) {
@ -4955,6 +4996,8 @@ void HistoryWidget::updateHistoryGeometry(bool initial, bool loadedDown, const S
} else { } else {
if (_canSendMessages) { if (_canSendMessages) {
newScrollHeight -= (_field->height() + 2 * st::historySendPadding); newScrollHeight -= (_field->height() + 2 * st::historySendPadding);
} else if (isRestrictedWrite()) {
newScrollHeight -= _unblock->height();
} }
if (_editMsgId || replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) { if (_editMsgId || replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
newScrollHeight -= st::historyReplyHeight; newScrollHeight -= st::historyReplyHeight;
@ -5268,16 +5311,34 @@ void HistoryWidget::onFieldTabbed() {
} }
bool HistoryWidget::onStickerSend(DocumentData *sticker) { bool HistoryWidget::onStickerSend(DocumentData *sticker) {
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restrictedRights().is_send_stickers()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_stickers)), KeepOtherLayers);
return false;
}
}
return sendExistingDocument(sticker, QString()); return sendExistingDocument(sticker, QString());
} }
void HistoryWidget::onPhotoSend(PhotoData *photo) { void HistoryWidget::onPhotoSend(PhotoData *photo) {
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
if (megagroup->restrictedRights().is_send_media()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)), KeepOtherLayers);
return;
}
}
sendExistingPhoto(photo, QString()); sendExistingPhoto(photo, QString());
} }
void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot) { void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot) {
if (!_history || !result || !canSendMessages(_peer)) return; if (!_history || !result || !canSendMessages(_peer)) return;
auto errorText = result->getErrorOnSend(_history);
if (!errorText.isEmpty()) {
Ui::show(Box<InformBox>(errorText));
return;
}
App::main()->readServerHistory(_history); App::main()->readServerHistory(_history);
fastShowAtEnd(_history); fastShowAtEnd(_history);
@ -5867,8 +5928,7 @@ void HistoryWidget::onStickerPackInfo() {
} }
void HistoryWidget::previewCancel() { void HistoryWidget::previewCancel() {
MTP::cancel(_previewRequest); MTP::cancel(base::take(_previewRequest));
_previewRequest = 0;
_previewData = nullptr; _previewData = nullptr;
_previewLinks.clear(); _previewLinks.clear();
updatePreview(); updatePreview();
@ -5884,11 +5944,25 @@ void HistoryWidget::onPreviewParse() {
} }
void HistoryWidget::onPreviewCheck() { void HistoryWidget::onPreviewCheck() {
if (_previewCancelled) return; auto previewRestricted = [this] {
QStringList linksList = _field->linksList(); if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
QString newLinks = linksList.join(' '); if (megagroup->restrictedRights().is_embed_links()) {
return true;
}
}
return false;
};
if (_previewCancelled || previewRestricted()) {
MTP::cancel(base::take(_previewRequest));
_previewData = nullptr;
_previewLinks.clear();
update();
return;
}
auto linksList = _field->linksList();
auto newLinks = linksList.join(' ');
if (newLinks != _previewLinks) { if (newLinks != _previewLinks) {
MTP::cancel(_previewRequest); MTP::cancel(base::take(_previewRequest));
_previewLinks = newLinks; _previewLinks = newLinks;
if (_previewLinks.isEmpty()) { if (_previewLinks.isEmpty()) {
if (_previewData && _previewData->pendingTill >= 0) previewCancel(); if (_previewData && _previewData->pendingTill >= 0) previewCancel();
@ -6397,12 +6471,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
} }
} }
namespace { void HistoryWidget::drawRestrictedWrite(Painter &p) {
auto rect = myrtlrect(0, height() - _unblock->height(), _chatWidth, _unblock->height());
p.fillRect(rect, st::historyReplyBg);
constexpr int DisplayEditTimeWarningMs = 300 * 1000; p.setFont(st::normalFont);
constexpr int FullDayInMs = 86400 * 1000; p.setPen(st::windowSubTextFg);
p.drawText(rect.marginsRemoved(QMargins(st::historySendPadding, 0, st::historySendPadding, 0)), lang(lng_restricted_send_message), style::al_center);
} // namespace }
void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const { void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const {
if (!rect.intersects(myrtlrect(left, top, _chatWidth - left, st::normalFont->height))) { if (!rect.intersects(myrtlrect(left, top, _chatWidth - left, st::normalFont->height))) {
@ -6421,8 +6497,8 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
auto editTimeLeft = (Global::EditTimeLimit() * 1000LL) - timeSinceMessage; auto editTimeLeft = (Global::EditTimeLimit() * 1000LL) - timeSinceMessage;
if (editTimeLeft < 2) { if (editTimeLeft < 2) {
editTimeLeftText = qsl("0:00"); editTimeLeftText = qsl("0:00");
} else if (editTimeLeft > DisplayEditTimeWarningMs) { } else if (editTimeLeft > kDisplayEditTimeWarningMs) {
updateIn = static_cast<int>(qMin(editTimeLeft - DisplayEditTimeWarningMs, qint64(FullDayInMs))); updateIn = static_cast<int>(qMin(editTimeLeft - kDisplayEditTimeWarningMs, qint64(kFullDayInMs)));
} else { } else {
updateIn = static_cast<int>(editTimeLeft % 1000); updateIn = static_cast<int>(editTimeLeft % 1000);
if (!updateIn) { if (!updateIn) {
@ -6583,6 +6659,8 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
if (!_send->isHidden() && _recording) { if (!_send->isHidden() && _recording) {
drawRecording(p, _send->recordActiveRatio()); drawRecording(p, _send->recordActiveRatio());
} }
} else if (isRestrictedWrite()) {
drawRestrictedWrite(p);
} }
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) { if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
drawPinnedBar(p); drawPinnedBar(p);

View File

@ -523,6 +523,7 @@ private:
bool historyHasNotFreezedUnreadBar(History *history) const; bool historyHasNotFreezedUnreadBar(History *history) const;
bool canWriteMessage() const; bool canWriteMessage() const;
bool isRestrictedWrite() const;
void orderWidgets(); void orderWidgets();
void clearInlineBot(); void clearInlineBot();
@ -577,6 +578,7 @@ private:
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const; void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;
void drawRecording(Painter &p, float64 recordActive); void drawRecording(Painter &p, float64 recordActive);
void drawPinnedBar(Painter &p); void drawPinnedBar(Painter &p);
void drawRestrictedWrite(Painter &p);
void updateMouseTracking(); void updateMouseTracking();

View File

@ -290,6 +290,10 @@ void Result::addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgI
sendData->addToHistory(this, history, flags, msgId, fromId, mtpDate, viaBotId, replyToId, markup); sendData->addToHistory(this, history, flags, msgId, fromId, mtpDate, viaBotId, replyToId, markup);
} }
QString Result::getErrorOnSend(History *history) const {
return sendData->getErrorOnSend(this, history);
}
bool Result::getLocationCoords(LocationCoords *outLocation) const { bool Result::getLocationCoords(LocationCoords *outLocation) const {
return sendData->getLocationCoords(outLocation); return sendData->getLocationCoords(outLocation);
} }

View File

@ -68,6 +68,7 @@ public:
bool hasThumbDisplay() const; bool hasThumbDisplay() const;
void addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId) const; void addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId) const;
QString getErrorOnSend(History *history) const;
// interface for Layout:: usage // interface for Layout:: usage
bool getLocationCoords(LocationCoords *outLocation) const; bool getLocationCoords(LocationCoords *outLocation) const;

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "inline_bots/inline_bot_result.h" #include "inline_bots/inline_bot_result.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "lang/lang_keys.h"
namespace InlineBots { namespace InlineBots {
namespace internal { namespace internal {
@ -44,6 +45,15 @@ UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(msgId), MTP_int(fromId), peerToMTP(history->peer->id), MTPnullFwdHeader, MTP_int(viaBotId), MTP_int(replyToId), mtpDate, fields.text, fields.media, markup, fields.entities, MTP_int(1), MTPint()), NewMessageUnread); history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(msgId), MTP_int(fromId), peerToMTP(history->peer->id), MTPnullFwdHeader, MTP_int(viaBotId), MTP_int(replyToId), mtpDate, fields.text, fields.media, markup, fields.entities, MTP_int(1), MTPint()), NewMessageUnread);
} }
QString SendDataCommon::getErrorOnSend(const Result *owner, History *history) const {
if (auto megagroup = history->peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_messages()) {
return lang(lng_restricted_send_message);
}
}
return QString();
}
SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const { SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const {
SentMTPMessageFields result; SentMTPMessageFields result;
result.text = MTP_string(_message); result.text = MTP_string(_message);
@ -83,17 +93,48 @@ UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
history->addNewPhoto(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _photo, _caption, markup); history->addNewPhoto(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _photo, _caption, markup);
} }
QString SendPhoto::getErrorOnSend(const Result *owner, History *history) const {
if (auto megagroup = history->peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_media()) {
return lang(lng_restricted_send_media);
}
}
return QString();
}
void SendFile::addToHistory(const Result *owner, History *history, void SendFile::addToHistory(const Result *owner, History *history,
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const { UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
history->addNewDocument(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _document, _caption, markup); history->addNewDocument(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _document, _caption, markup);
} }
QString SendFile::getErrorOnSend(const Result *owner, History *history) const {
if (auto megagroup = history->peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_media()) {
return lang(lng_restricted_send_media);
} else if (megagroup->restrictedRights().is_send_stickers() && (_document->sticker() != nullptr)) {
return lang(lng_restricted_send_stickers);
} else if (megagroup->restrictedRights().is_send_gifs() && _document->isAnimation() && !_document->isRoundVideo()) {
return lang(lng_restricted_send_gifs);
}
}
return QString();
}
void SendGame::addToHistory(const Result *owner, History *history, void SendGame::addToHistory(const Result *owner, History *history,
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const { UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
history->addNewGame(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _game, markup); history->addNewGame(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _game, markup);
} }
QString SendGame::getErrorOnSend(const Result *owner, History *history) const {
if (auto megagroup = history->peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_games()) {
return lang(lng_restricted_send_inline);
}
}
return QString();
}
} // namespace internal } // namespace internal
} // namespace InlineBots } // namespace InlineBots

View File

@ -46,6 +46,7 @@ public:
virtual void addToHistory(const Result *owner, History *history, virtual void addToHistory(const Result *owner, History *history,
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const = 0; UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const = 0;
virtual QString getErrorOnSend(const Result *owner, History *history) const = 0;
virtual bool hasLocationCoords() const { virtual bool hasLocationCoords() const {
return false; return false;
@ -74,6 +75,8 @@ public:
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override; UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
QString getErrorOnSend(const Result *owner, History *history) const override;
}; };
// Plain text message. // Plain text message.
@ -193,6 +196,8 @@ public:
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override; UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
QString getErrorOnSend(const Result *owner, History *history) const override;
private: private:
PhotoData *_photo; PhotoData *_photo;
QString _caption; QString _caption;
@ -215,6 +220,8 @@ public:
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override; UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
QString getErrorOnSend(const Result *owner, History *history) const override;
private: private:
DocumentData *_document; DocumentData *_document;
QString _caption; QString _caption;
@ -236,6 +243,8 @@ public:
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override; UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
QString getErrorOnSend(const Result *owner, History *history) const override;
private: private:
GameData *_game; GameData *_game;

View File

@ -36,6 +36,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "auth_session.h" #include "auth_session.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "ui/widgets/scroll_area.h" #include "ui/widgets/scroll_area.h"
#include "ui/widgets/labels.h"
#include "observer_peer.h"
namespace InlineBots { namespace InlineBots {
namespace Layout { namespace Layout {
@ -67,6 +69,15 @@ Inner::Inner(QWidget *parent, gsl::not_null<Window::Controller*> controller) : T
update(); update();
} }
}); });
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelRightsChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _inlineQueryPeer) {
auto isRestricted = (_restrictedLabel != nullptr);
if (isRestricted != isRestrictedView()) {
auto h = countHeight();
if (h != height()) resize(width(), h);
}
}
}));
} }
void Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) { void Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
@ -77,7 +88,39 @@ void Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
} }
} }
void Inner::checkRestrictedPeer() {
if (auto megagroup = _inlineQueryPeer ? _inlineQueryPeer->asMegagroup() : nullptr) {
if (megagroup->restrictedRights().is_send_inline()) {
if (!_restrictedLabel) {
_restrictedLabel.create(this, lang(lng_restricted_send_inline), Ui::FlatLabel::InitType::Simple, st::stickersRestrictedLabel);
_restrictedLabel->show();
_restrictedLabel->move(st::inlineResultsLeft - st::buttonRadius, st::stickerPanPadding);
if (_switchPmButton) {
_switchPmButton->hide();
}
update();
}
return;
}
}
if (_restrictedLabel) {
_restrictedLabel.destroy();
if (_switchPmButton) {
_switchPmButton->show();
}
update();
}
}
bool Inner::isRestrictedView() {
checkRestrictedPeer();
return (_restrictedLabel != nullptr);
}
int Inner::countHeight() { int Inner::countHeight() {
if (isRestrictedView()) {
return st::stickerPanPadding + _restrictedLabel->height() + st::stickerPanPadding;
}
auto result = st::stickerPanPadding; auto result = st::stickerPanPadding;
if (_switchPmButton) { if (_switchPmButton) {
result += _switchPmButton->height() + st::inlineResultsSkip; result += _switchPmButton->height() + st::inlineResultsSkip;
@ -102,6 +145,9 @@ void Inner::paintEvent(QPaintEvent *e) {
} }
void Inner::paintInlineItems(Painter &p, const QRect &r) { void Inner::paintInlineItems(Painter &p, const QRect &r) {
if (_restrictedLabel) {
return;
}
if (_rows.isEmpty() && !_switchPmButton) { if (_rows.isEmpty() && !_switchPmButton) {
p.setFont(st::normalFont); p.setFont(st::normalFont);
p.setPen(st::noContactsColor); p.setPen(st::noContactsColor);
@ -278,7 +324,7 @@ bool Inner::inlineRowFinalize(Row &row, int32 &sumWidth, bool force) {
} }
void Inner::inlineBotChanged() { void Inner::inlineBotChanged() {
refreshInlineRows(nullptr, nullptr, true); refreshInlineRows(nullptr, nullptr, nullptr, true);
} }
void Inner::clearInlineRows(bool resultsDeleted) { void Inner::clearInlineRows(bool resultsDeleted) {
@ -392,12 +438,16 @@ void Inner::refreshSwitchPmButton(const CacheEntry *entry) {
_switchPmStartToken = entry->switchPmStartToken; _switchPmStartToken = entry->switchPmStartToken;
auto buttonTop = st::stickerPanPadding; auto buttonTop = st::stickerPanPadding;
_switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, buttonTop); _switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, buttonTop);
if (isRestrictedView()) {
_switchPmButton->hide();
}
} }
update(); update();
} }
int Inner::refreshInlineRows(UserData *bot, const CacheEntry *entry, bool resultsDeleted) { int Inner::refreshInlineRows(PeerData *queryPeer, UserData *bot, const CacheEntry *entry, bool resultsDeleted) {
_inlineBot = bot; _inlineBot = bot;
_inlineQueryPeer = queryPeer;
refreshSwitchPmButton(entry); refreshSwitchPmButton(entry);
auto clearResults = [this, entry]() { auto clearResults = [this, entry]() {
if (!entry) { if (!entry) {
@ -1072,7 +1122,7 @@ bool Widget::refreshInlineRows(int *added) {
_inlineNextOffset = it->second->nextOffset; _inlineNextOffset = it->second->nextOffset;
} }
if (!entry) prepareCache(); if (!entry) prepareCache();
auto result = _inner->refreshInlineRows(_inlineBot, entry, false); auto result = _inner->refreshInlineRows(_inlineQueryPeer, _inlineBot, entry, false);
if (added) *added = result; if (added) *added = result;
return (entry != nullptr); return (entry != nullptr);
} }

View File

@ -31,6 +31,7 @@ class ScrollArea;
class IconButton; class IconButton;
class LinkButton; class LinkButton;
class RoundButton; class RoundButton;
class FlatLabel;
class RippleAnimation; class RippleAnimation;
} // namesapce Ui } // namesapce Ui
@ -68,7 +69,7 @@ public:
void clearSelection(); void clearSelection();
int refreshInlineRows(UserData *bot, const CacheEntry *results, bool resultsDeleted); int refreshInlineRows(PeerData *queryPeer, UserData *bot, const CacheEntry *results, bool resultsDeleted);
void inlineBotChanged(); void inlineBotChanged();
void hideInlineRowsPanel(); void hideInlineRowsPanel();
void clearInlineRowsPanel(); void clearInlineRowsPanel();
@ -110,6 +111,8 @@ private:
static constexpr bool kRefreshIconsNoAnimation = false; static constexpr bool kRefreshIconsNoAnimation = false;
void updateSelected(); void updateSelected();
void checkRestrictedPeer();
bool isRestrictedView();
void paintInlineItems(Painter &p, const QRect &r); void paintInlineItems(Painter &p, const QRect &r);
@ -120,7 +123,8 @@ private:
int _visibleTop = 0; int _visibleTop = 0;
int _visibleBottom = 0; int _visibleBottom = 0;
UserData *_inlineBot; UserData *_inlineBot = nullptr;
PeerData *_inlineQueryPeer = nullptr;
TimeMs _lastScrolled = 0; TimeMs _lastScrolled = 0;
QTimer _updateInlineItems; QTimer _updateInlineItems;
bool _inlineWithThumb = false; bool _inlineWithThumb = false;
@ -128,6 +132,8 @@ private:
object_ptr<Ui::RoundButton> _switchPmButton = { nullptr }; object_ptr<Ui::RoundButton> _switchPmButton = { nullptr };
QString _switchPmStartToken; QString _switchPmStartToken;
object_ptr<Ui::FlatLabel> _restrictedLabel = { nullptr };
struct Row { struct Row {
int height = 0; int height = 0;
QVector<ItemBase*> items; QVector<ItemBase*> items;

View File

@ -77,7 +77,7 @@ namespace {
constexpr auto kSaveFloatPlayerPositionTimeoutMs = TimeMs(1000); constexpr auto kSaveFloatPlayerPositionTimeoutMs = TimeMs(1000);
MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) { MTPMessagesFilter TypeToMediaFilter(MediaOverviewType &type) {
switch (type) { switch (type) {
case OverviewPhotos: return MTP_inputMessagesFilterPhotos(); case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
case OverviewVideos: return MTP_inputMessagesFilterVideo(); case OverviewVideos: return MTP_inputMessagesFilterVideo();
@ -92,6 +92,64 @@ MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
} }
} }
bool HasMediaItems(const SelectedItemSet &items) {
for_const (auto item, items) {
if (auto media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto:
case MediaTypeVideo:
case MediaTypeFile:
case MediaTypeMusicFile:
case MediaTypeVoiceFile: return true;
case MediaTypeGif: return media->getDocument()->isRoundVideo();
}
}
}
return false;
}
bool HasStickerItems(const SelectedItemSet &items) {
for_const (auto item, items) {
if (auto media = item->getMedia()) {
switch (media->type()) {
case MediaTypeSticker: return true;
}
}
}
return false;
}
bool HasGifItems(const SelectedItemSet &items) {
for_const (auto item, items) {
if (auto media = item->getMedia()) {
switch (media->type()) {
case MediaTypeGif: return !media->getDocument()->isRoundVideo();
}
}
}
return false;
}
bool HasGameItems(const SelectedItemSet &items) {
for_const (auto item, items) {
if (auto media = item->getMedia()) {
switch (media->type()) {
case MediaTypeGame: return true;
}
}
}
return false;
}
bool HasInlineItems(const SelectedItemSet &items) {
for_const (auto item, items) {
if (item->viaBot()) {
return true;
}
}
return false;
}
} // namespace } // namespace
StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr) StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
@ -505,22 +563,33 @@ void MainWidget::finishFloatPlayerDrag(gsl::not_null<Float*> instance, bool clos
} }
} }
bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) { bool MainWidget::onForward(const PeerId &peerId, ForwardWhatMessages what) {
PeerData *p = App::peer(peer); Expects(peerId != 0);
if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && !p->asChat()->canWrite()) || (p->isUser() && p->asUser()->isInaccessible())) { auto peer = App::peer(peerId);
Ui::show(Box<InformBox>(lang(lng_forward_cant))); auto finishWithError = [this, what](const QString &error) {
Ui::show(Box<InformBox>(error));
if (what == ForwardPressedMessage || what == ForwardPressedLinkMessage) {
// We've already released the mouse button, so the forwarding is cancelled.
if (_hider) {
_hider->startHide();
noHider(_hider);
}
}
return false; return false;
};
if (!peer->canWrite()) {
return finishWithError(lang(lng_forward_cant));
} }
_history->cancelReply();
_toForward.clear(); auto toForward = SelectedItemSet();
if (what == ForwardSelectedMessages) { if (what == ForwardSelectedMessages) {
if (_overview) { if (_overview) {
_overview->fillSelectedItems(_toForward, false); _overview->fillSelectedItems(toForward, false);
} else { } else {
_history->fillSelectedItems(_toForward, false); _history->fillSelectedItems(toForward, false);
} }
} else { } else {
HistoryItem *item = 0; auto item = (HistoryItem*)nullptr;
if (what == ForwardContextMessage) { if (what == ForwardContextMessage) {
item = App::contextItem(); item = App::contextItem();
} else if (what == ForwardPressedMessage) { } else if (what == ForwardPressedMessage) {
@ -529,9 +598,25 @@ bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) {
item = App::pressedLinkItem(); item = App::pressedLinkItem();
} }
if (item && item->toHistoryMessage() && item->id > 0) { if (item && item->toHistoryMessage() && item->id > 0) {
_toForward.insert(item->id, item); toForward.insert(item->id, item);
} }
} }
if (auto megagroup = peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_media() && HasMediaItems(toForward)) {
return finishWithError(lang(lng_restricted_send_media));
} else if (megagroup->restrictedRights().is_send_stickers() && HasStickerItems(toForward)) {
return finishWithError(lang(lng_restricted_send_stickers));
} else if (megagroup->restrictedRights().is_send_gifs() && HasGifItems(toForward)) {
return finishWithError(lang(lng_restricted_send_gifs));
} else if (megagroup->restrictedRights().is_send_games() && HasGameItems(toForward)) {
return finishWithError(lang(lng_restricted_send_inline));
} else if (megagroup->restrictedRights().is_send_inline() && HasInlineItems(toForward)) {
return finishWithError(lang(lng_restricted_send_inline));
}
}
_toForward = toForward;
_history->cancelReply();
updateForwardingItemRemovedSubscription(); updateForwardingItemRemovedSubscription();
updateForwardingTexts(); updateForwardingTexts();
Ui::showPeerHistory(peer, ShowAtUnreadMsgId); Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
@ -777,23 +862,40 @@ void MainWidget::onUpdateMuted() {
App::updateMuted(); App::updateMuted();
} }
void MainWidget::onShareContact(const PeerId &peer, UserData *contact) { void MainWidget::onShareContact(const PeerId &peerId, UserData *contact) {
_history->onShareContact(peer, contact); _history->onShareContact(peerId, contact);
} }
bool MainWidget::onSendPaths(const PeerId &peer) { bool MainWidget::onSendPaths(const PeerId &peerId) {
Expects(peerId != 0);
auto peer = App::peer(peerId);
if (!peer->canWrite()) {
Ui::show(Box<InformBox>(lang(lng_forward_send_files_cant)));
return false;
} else if (auto megagroup = peer->asMegagroup()) {
if (megagroup->restrictedRights().is_send_media()) {
Ui::show(Box<InformBox>(lang(lng_restricted_send_media)));
return false;
}
}
Ui::showPeerHistory(peer, ShowAtTheEndMsgId); Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
return _history->confirmSendingFiles(cSendPaths()); return _history->confirmSendingFiles(cSendPaths());
} }
void MainWidget::onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data) { void MainWidget::onFilesOrForwardDrop(const PeerId &peerId, const QMimeData *data) {
Expects(peerId != 0);
if (data->hasFormat(qsl("application/x-td-forward-selected"))) { if (data->hasFormat(qsl("application/x-td-forward-selected"))) {
onForward(peer, ForwardSelectedMessages); onForward(peerId, ForwardSelectedMessages);
} else if (data->hasFormat(qsl("application/x-td-forward-pressed-link"))) { } else if (data->hasFormat(qsl("application/x-td-forward-pressed-link"))) {
onForward(peer, ForwardPressedLinkMessage); onForward(peerId, ForwardPressedLinkMessage);
} else if (data->hasFormat(qsl("application/x-td-forward-pressed"))) { } else if (data->hasFormat(qsl("application/x-td-forward-pressed"))) {
onForward(peer, ForwardPressedMessage); onForward(peerId, ForwardPressedMessage);
} else { } else {
auto peer = App::peer(peerId);
if (!peer->canWrite()) {
Ui::show(Box<InformBox>(lang(lng_forward_send_files_cant)));
return;
}
Ui::showPeerHistory(peer, ShowAtTheEndMsgId); Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
_history->confirmSendingFiles(data); _history->confirmSendingFiles(data);
} }
@ -1622,7 +1724,7 @@ void MainWidget::searchMessages(const QString &query, PeerData *inPeer) {
} }
bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) { bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
auto filter = typeToMediaFilter(type); auto filter = TypeToMediaFilter(type);
if (filter.type() == mtpc_inputMessagesFilterEmpty) { if (filter.type() == mtpc_inputMessagesFilterEmpty) {
return false; return false;
} }
@ -1695,7 +1797,7 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
auto minId = history->overviewMinId(type); auto minId = history->overviewMinId(type);
auto limit = (many || history->overview[type].size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage; auto limit = (many || history->overview[type].size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
auto filter = typeToMediaFilter(type); auto filter = TypeToMediaFilter(type);
if (filter.type() == mtpc_inputMessagesFilterEmpty) { if (filter.type() == mtpc_inputMessagesFilterEmpty) {
return; return;
} }