mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Add supergroup restriction placeholders / labels.
This commit is contained in:
parent
7d2d5c6100
commit
5c0a1bafe2
15 changed files with 462 additions and 59 deletions
|
@ -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_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_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_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_confirm" = "Forward 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_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_messages#one" = "{count} forwarded message";
|
||||
"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_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
|
||||
|
||||
"lng_topbar_info" = "Info";
|
||||
|
|
|
@ -884,6 +884,25 @@ void shareGameScoreFromItem(HistoryItem *item) {
|
|||
if (!data->requests.empty()) {
|
||||
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) {
|
||||
if (auto main = App::main()) {
|
||||
|
@ -901,6 +920,12 @@ void shareGameScoreFromItem(HistoryItem *item) {
|
|||
if (auto main = App::main()) {
|
||||
if (auto item = App::histItemById(data->msgId)) {
|
||||
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>());
|
||||
auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input);
|
||||
auto callback = doneCallback;
|
||||
|
|
|
@ -28,6 +28,11 @@ switchPmButton: RoundButton(defaultBoxButton) {
|
|||
height: 34px;
|
||||
textTop: 7px;
|
||||
}
|
||||
stickersRestrictedLabel: FlatLabel(defaultFlatLabel) {
|
||||
width: 320px;
|
||||
align: align(center);
|
||||
textFg: noContactsColor;
|
||||
}
|
||||
|
||||
stickersTrendingHeader: 45px;
|
||||
stickersTrendingSkip: 15px;
|
||||
|
|
|
@ -26,12 +26,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "chat_helpers/stickers.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/discrete_sliders.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwindow.h"
|
||||
#include "observer_peer.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
namespace {
|
||||
|
@ -46,7 +48,7 @@ public:
|
|||
LeftToRight,
|
||||
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 paintFrame(QPainter &p, float64 dt, float64 opacity);
|
||||
|
@ -72,10 +74,11 @@ private:
|
|||
int _painterInnerRight = 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());
|
||||
_direction = direction;
|
||||
_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();
|
||||
_painterInnerHeight = _innerHeight / cIntRetinaFactor();
|
||||
_painterCategoriesTop = _painterInnerBottom - st::emojiCategory.height;
|
||||
|
||||
_wasSectionIcons = wasSectionIcons;
|
||||
}
|
||||
|
||||
void TabbedSelector::SlideAnimation::start() {
|
||||
|
@ -166,7 +171,7 @@ void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64
|
|||
Painter p(&_frame);
|
||||
p.setOpacity(opacity);
|
||||
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);
|
||||
if (leftTo > _innerLeft) {
|
||||
p.setOpacity(opacity * leftAlpha);
|
||||
|
@ -337,6 +342,12 @@ TabbedSelector::TabbedSelector(QWidget *parent, gsl::not_null<Window::Controller
|
|||
_bottomShadow->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_OpaquePaintEvent, false);
|
||||
showAll();
|
||||
|
@ -354,6 +365,9 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
|||
_scroll->resize(_scroll->width(), contentHeight);
|
||||
}
|
||||
_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;
|
||||
for (auto &tab : _tabs) {
|
||||
|
@ -394,8 +408,7 @@ void TabbedSelector::paintSlideFrame(Painter &p, TimeMs ms) {
|
|||
}
|
||||
|
||||
void TabbedSelector::paintContent(Painter &p) {
|
||||
auto showSectionIcons = (_currentTabType != SelectorTab::Gifs);
|
||||
auto &bottomBg = showSectionIcons ? st::emojiPanCategories : st::emojiPanBg;
|
||||
auto &bottomBg = hasSectionIcons() ? st::emojiPanCategories : st::emojiPanBg;
|
||||
if (_roundRadius > 0) {
|
||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
||||
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 sidesHeight = height() - sidesTop - marginBottom();
|
||||
p.fillRect(myrtlrect(width() - st::emojiScroll.width, sidesTop, st::emojiScroll.width, sidesHeight), st::emojiPanBg);
|
||||
p.fillRect(myrtlrect(0, sidesTop, st::buttonRadius, sidesHeight), st::emojiPanBg);
|
||||
if (_restrictedLabel) {
|
||||
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 {
|
||||
|
@ -504,15 +521,56 @@ void TabbedSelector::stickersInstalled(uint64 setId) {
|
|||
stickers()->showStickerSet(setId);
|
||||
}
|
||||
|
||||
void TabbedSelector::setInlineQueryPeer(PeerData *peer) {
|
||||
void TabbedSelector::setCurrentPeer(PeerData *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() {
|
||||
currentTab()->footer()->show();
|
||||
_scroll->show();
|
||||
if (isRestrictedView()) {
|
||||
_restrictedLabel->show();
|
||||
} else {
|
||||
currentTab()->footer()->show();
|
||||
_scroll->show();
|
||||
_bottomShadow->setVisible(_currentTabType == SelectorTab::Gifs);
|
||||
}
|
||||
_topShadow->show();
|
||||
_bottomShadow->setVisible(_currentTabType == SelectorTab::Gifs);
|
||||
_tabsSlider->show();
|
||||
}
|
||||
|
||||
|
@ -551,6 +609,10 @@ void TabbedSelector::createTabsSlider() {
|
|||
_topShadow->setGeometry(_tabsSlider->x(), _tabsSlider->bottomNoMargins() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
||||
}
|
||||
|
||||
bool TabbedSelector::hasSectionIcons() const {
|
||||
return (_currentTabType != SelectorTab::Gifs) && !_restrictedLabel;
|
||||
}
|
||||
|
||||
void TabbedSelector::switchTab() {
|
||||
auto tab = _tabsSlider->activeSection();
|
||||
t_assert(tab >= 0 && tab < Tab::kCount);
|
||||
|
@ -559,6 +621,7 @@ void TabbedSelector::switchTab() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto wasSectionIcons = hasSectionIcons();
|
||||
auto wasTab = _currentTabType;
|
||||
currentTab()->saveScrollTop();
|
||||
|
||||
|
@ -573,6 +636,9 @@ void TabbedSelector::switchTab() {
|
|||
currentTab()->returnWidget(std::move(widget));
|
||||
|
||||
_currentTabType = newTabType;
|
||||
_restrictedLabel.destroy();
|
||||
checkRestrictedPeer();
|
||||
|
||||
currentTab()->widget()->refreshRecent();
|
||||
currentTab()->widget()->preloadImages();
|
||||
setWidgetToScrollArea();
|
||||
|
@ -585,7 +651,7 @@ void TabbedSelector::switchTab() {
|
|||
}
|
||||
_slideAnimation = std::make_unique<SlideAnimation>();
|
||||
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);
|
||||
_slideAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3]));
|
||||
_slideAnimation->start();
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace Ui {
|
|||
class PlainShadow;
|
||||
class ScrollArea;
|
||||
class SettingsSlider;
|
||||
class FlatLabel;
|
||||
} // namesapce Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -51,7 +52,7 @@ class EmojiListWidget;
|
|||
class StickersListWidget;
|
||||
class GifsListWidget;
|
||||
|
||||
class TabbedSelector : public TWidget {
|
||||
class TabbedSelector : public TWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -60,7 +61,7 @@ public:
|
|||
void setRoundRadius(int radius);
|
||||
void refreshStickers();
|
||||
void stickersInstalled(uint64 setId);
|
||||
void setInlineQueryPeer(PeerData *peer);
|
||||
void setCurrentPeer(PeerData *peer);
|
||||
|
||||
void hideFinished();
|
||||
void showStarted();
|
||||
|
@ -150,6 +151,9 @@ private:
|
|||
void paintSlideFrame(Painter &p, TimeMs ms);
|
||||
void paintContent(Painter &p);
|
||||
|
||||
void checkRestrictedPeer();
|
||||
bool isRestrictedView();
|
||||
|
||||
QImage grabForAnimation();
|
||||
|
||||
void scrollToY(int y);
|
||||
|
@ -157,6 +161,7 @@ private:
|
|||
void showAll();
|
||||
void hideForSliding();
|
||||
|
||||
bool hasSectionIcons() const;
|
||||
void setWidgetToScrollArea();
|
||||
void createTabsSlider();
|
||||
void switchTab();
|
||||
|
@ -178,6 +183,7 @@ private:
|
|||
|
||||
int _roundRadius = 0;
|
||||
int _footerTop = 0;
|
||||
PeerData *_currentPeer = nullptr;
|
||||
|
||||
class SlideAnimation;
|
||||
std::unique_ptr<SlideAnimation> _slideAnimation;
|
||||
|
@ -187,6 +193,7 @@ private:
|
|||
object_ptr<Ui::PlainShadow> _topShadow;
|
||||
object_ptr<Ui::PlainShadow> _bottomShadow;
|
||||
object_ptr<Ui::ScrollArea> _scroll;
|
||||
object_ptr<Ui::FlatLabel> _restrictedLabel = { nullptr };
|
||||
std::array<Tab, Tab::kCount> _tabs;
|
||||
SelectorTab _currentTabType = SelectorTab::Emoji;
|
||||
|
||||
|
|
|
@ -2947,10 +2947,9 @@ void DialogsWidget::updateDragInScroll(bool inScroll) {
|
|||
void DialogsWidget::dropEvent(QDropEvent *e) {
|
||||
_chooseByDragTimer.stop();
|
||||
if (_scroll->geometry().contains(e->pos())) {
|
||||
PeerData *p = _inner->updateFromParentDrag(mapToGlobal(e->pos()));
|
||||
if (p) {
|
||||
if (auto peer = _inner->updateFromParentDrag(mapToGlobal(e->pos()))) {
|
||||
e->acceptProposedAction();
|
||||
App::main()->onFilesOrForwardDrop(p->id, e->mimeData());
|
||||
App::main()->onFilesOrForwardDrop(peer->id, e->mimeData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ constexpr auto kTabbedSelectorToggleTooltipCount = 3;
|
|||
constexpr auto kScrollToVoiceAfterScrolledMs = 1000;
|
||||
constexpr auto kSkipRepaintWhileScrollMs = 100;
|
||||
constexpr auto kShowMembersDropdownTimeoutMs = 300;
|
||||
constexpr auto kDisplayEditTimeWarningMs = 300 * 1000;
|
||||
constexpr auto kFullDayInMs = 86400 * 1000;
|
||||
|
||||
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
||||
return [](ChannelData *channel, MsgId msgId) {
|
||||
|
@ -363,8 +365,16 @@ bool HistoryHider::offerPeer(PeerId peer) {
|
|||
}
|
||||
_offered = App::peer(peer);
|
||||
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 (!_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);
|
||||
} else if (_sendPath) {
|
||||
auto toId = _offered->id;
|
||||
|
@ -650,6 +660,11 @@ HistoryWidget::HistoryWidget(QWidget *parent, gsl::not_null<Window::Controller*>
|
|||
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();
|
||||
}
|
||||
|
@ -1879,7 +1894,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
|||
_peer = App::peer(peerId);
|
||||
_channel = peerToChannel(_peer->id);
|
||||
_canSendMessages = canSendMessages(_peer);
|
||||
_tabbedSelector->setInlineQueryPeer(_peer);
|
||||
_tabbedSelector->setCurrentPeer(_peer);
|
||||
}
|
||||
updateTopBarSelection();
|
||||
|
||||
|
@ -2143,6 +2158,13 @@ bool HistoryWidget::canWriteMessage() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HistoryWidget::isRestrictedWrite() const {
|
||||
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
|
||||
return megagroup->restrictedRights().is_send_messages();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HistoryWidget::updateControlsVisibility() {
|
||||
if (!_a_show.animating()) {
|
||||
_topShadow->setVisible(_peer != nullptr);
|
||||
|
@ -3198,7 +3220,13 @@ void HistoryWidget::step_recording(float64 ms, bool timer) {
|
|||
}
|
||||
|
||||
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(")");
|
||||
|
||||
|
@ -3297,6 +3325,13 @@ void HistoryWidget::recordStartCallback() {
|
|||
if (!Media::Capture::instance()->available()) {
|
||||
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();
|
||||
|
||||
_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) {
|
||||
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) {
|
||||
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) {
|
||||
|
@ -4955,6 +4996,8 @@ void HistoryWidget::updateHistoryGeometry(bool initial, bool loadedDown, const S
|
|||
} else {
|
||||
if (_canSendMessages) {
|
||||
newScrollHeight -= (_field->height() + 2 * st::historySendPadding);
|
||||
} else if (isRestrictedWrite()) {
|
||||
newScrollHeight -= _unblock->height();
|
||||
}
|
||||
if (_editMsgId || replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||
newScrollHeight -= st::historyReplyHeight;
|
||||
|
@ -5268,16 +5311,34 @@ void HistoryWidget::onFieldTabbed() {
|
|||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot) {
|
||||
if (!_history || !result || !canSendMessages(_peer)) return;
|
||||
|
||||
auto errorText = result->getErrorOnSend(_history);
|
||||
if (!errorText.isEmpty()) {
|
||||
Ui::show(Box<InformBox>(errorText));
|
||||
return;
|
||||
}
|
||||
|
||||
App::main()->readServerHistory(_history);
|
||||
fastShowAtEnd(_history);
|
||||
|
||||
|
@ -5867,8 +5928,7 @@ void HistoryWidget::onStickerPackInfo() {
|
|||
}
|
||||
|
||||
void HistoryWidget::previewCancel() {
|
||||
MTP::cancel(_previewRequest);
|
||||
_previewRequest = 0;
|
||||
MTP::cancel(base::take(_previewRequest));
|
||||
_previewData = nullptr;
|
||||
_previewLinks.clear();
|
||||
updatePreview();
|
||||
|
@ -5884,11 +5944,25 @@ void HistoryWidget::onPreviewParse() {
|
|||
}
|
||||
|
||||
void HistoryWidget::onPreviewCheck() {
|
||||
if (_previewCancelled) return;
|
||||
QStringList linksList = _field->linksList();
|
||||
QString newLinks = linksList.join(' ');
|
||||
auto previewRestricted = [this] {
|
||||
if (auto megagroup = _peer ? _peer->asMegagroup() : nullptr) {
|
||||
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) {
|
||||
MTP::cancel(_previewRequest);
|
||||
MTP::cancel(base::take(_previewRequest));
|
||||
_previewLinks = newLinks;
|
||||
if (_previewLinks.isEmpty()) {
|
||||
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;
|
||||
constexpr int FullDayInMs = 86400 * 1000;
|
||||
|
||||
} // namespace
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::windowSubTextFg);
|
||||
p.drawText(rect.marginsRemoved(QMargins(st::historySendPadding, 0, st::historySendPadding, 0)), lang(lng_restricted_send_message), style::al_center);
|
||||
}
|
||||
|
||||
void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const {
|
||||
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;
|
||||
if (editTimeLeft < 2) {
|
||||
editTimeLeftText = qsl("0:00");
|
||||
} else if (editTimeLeft > DisplayEditTimeWarningMs) {
|
||||
updateIn = static_cast<int>(qMin(editTimeLeft - DisplayEditTimeWarningMs, qint64(FullDayInMs)));
|
||||
} else if (editTimeLeft > kDisplayEditTimeWarningMs) {
|
||||
updateIn = static_cast<int>(qMin(editTimeLeft - kDisplayEditTimeWarningMs, qint64(kFullDayInMs)));
|
||||
} else {
|
||||
updateIn = static_cast<int>(editTimeLeft % 1000);
|
||||
if (!updateIn) {
|
||||
|
@ -6583,6 +6659,8 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
|||
if (!_send->isHidden() && _recording) {
|
||||
drawRecording(p, _send->recordActiveRatio());
|
||||
}
|
||||
} else if (isRestrictedWrite()) {
|
||||
drawRestrictedWrite(p);
|
||||
}
|
||||
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
|
||||
drawPinnedBar(p);
|
||||
|
|
|
@ -523,6 +523,7 @@ private:
|
|||
|
||||
bool historyHasNotFreezedUnreadBar(History *history) const;
|
||||
bool canWriteMessage() const;
|
||||
bool isRestrictedWrite() const;
|
||||
void orderWidgets();
|
||||
|
||||
void clearInlineBot();
|
||||
|
@ -577,6 +578,7 @@ private:
|
|||
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;
|
||||
void drawRecording(Painter &p, float64 recordActive);
|
||||
void drawPinnedBar(Painter &p);
|
||||
void drawRestrictedWrite(Painter &p);
|
||||
|
||||
void updateMouseTracking();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
QString Result::getErrorOnSend(History *history) const {
|
||||
return sendData->getErrorOnSend(this, history);
|
||||
}
|
||||
|
||||
bool Result::getLocationCoords(LocationCoords *outLocation) const {
|
||||
return sendData->getLocationCoords(outLocation);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
bool hasThumbDisplay() 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
|
||||
bool getLocationCoords(LocationCoords *outLocation) const;
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
||||
namespace InlineBots {
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
SentMTPMessageFields result;
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
|
||||
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,
|
||||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const {
|
||||
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 InlineBots
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
virtual void addToHistory(const Result *owner, History *history,
|
||||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const = 0;
|
||||
virtual QString getErrorOnSend(const Result *owner, History *history) const = 0;
|
||||
|
||||
virtual bool hasLocationCoords() const {
|
||||
return false;
|
||||
|
@ -74,6 +75,8 @@ public:
|
|||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
|
||||
|
||||
QString getErrorOnSend(const Result *owner, History *history) const override;
|
||||
|
||||
};
|
||||
|
||||
// Plain text message.
|
||||
|
@ -193,6 +196,8 @@ public:
|
|||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
|
||||
|
||||
QString getErrorOnSend(const Result *owner, History *history) const override;
|
||||
|
||||
private:
|
||||
PhotoData *_photo;
|
||||
QString _caption;
|
||||
|
@ -215,6 +220,8 @@ public:
|
|||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
|
||||
|
||||
QString getErrorOnSend(const Result *owner, History *history) const override;
|
||||
|
||||
private:
|
||||
DocumentData *_document;
|
||||
QString _caption;
|
||||
|
@ -236,6 +243,8 @@ public:
|
|||
MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate,
|
||||
UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const override;
|
||||
|
||||
QString getErrorOnSend(const Result *owner, History *history) const override;
|
||||
|
||||
private:
|
||||
GameData *_game;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "auth_session.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "observer_peer.h"
|
||||
|
||||
namespace InlineBots {
|
||||
namespace Layout {
|
||||
|
@ -67,6 +69,15 @@ Inner::Inner(QWidget *parent, gsl::not_null<Window::Controller*> controller) : T
|
|||
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) {
|
||||
|
@ -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() {
|
||||
if (isRestrictedView()) {
|
||||
return st::stickerPanPadding + _restrictedLabel->height() + st::stickerPanPadding;
|
||||
}
|
||||
auto result = st::stickerPanPadding;
|
||||
if (_switchPmButton) {
|
||||
result += _switchPmButton->height() + st::inlineResultsSkip;
|
||||
|
@ -102,6 +145,9 @@ void Inner::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void Inner::paintInlineItems(Painter &p, const QRect &r) {
|
||||
if (_restrictedLabel) {
|
||||
return;
|
||||
}
|
||||
if (_rows.isEmpty() && !_switchPmButton) {
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::noContactsColor);
|
||||
|
@ -278,7 +324,7 @@ bool Inner::inlineRowFinalize(Row &row, int32 &sumWidth, bool force) {
|
|||
}
|
||||
|
||||
void Inner::inlineBotChanged() {
|
||||
refreshInlineRows(nullptr, nullptr, true);
|
||||
refreshInlineRows(nullptr, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
void Inner::clearInlineRows(bool resultsDeleted) {
|
||||
|
@ -392,12 +438,16 @@ void Inner::refreshSwitchPmButton(const CacheEntry *entry) {
|
|||
_switchPmStartToken = entry->switchPmStartToken;
|
||||
auto buttonTop = st::stickerPanPadding;
|
||||
_switchPmButton->move(st::inlineResultsLeft - st::buttonRadius, buttonTop);
|
||||
if (isRestrictedView()) {
|
||||
_switchPmButton->hide();
|
||||
}
|
||||
}
|
||||
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;
|
||||
_inlineQueryPeer = queryPeer;
|
||||
refreshSwitchPmButton(entry);
|
||||
auto clearResults = [this, entry]() {
|
||||
if (!entry) {
|
||||
|
@ -1072,7 +1122,7 @@ bool Widget::refreshInlineRows(int *added) {
|
|||
_inlineNextOffset = it->second->nextOffset;
|
||||
}
|
||||
if (!entry) prepareCache();
|
||||
auto result = _inner->refreshInlineRows(_inlineBot, entry, false);
|
||||
auto result = _inner->refreshInlineRows(_inlineQueryPeer, _inlineBot, entry, false);
|
||||
if (added) *added = result;
|
||||
return (entry != nullptr);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ class ScrollArea;
|
|||
class IconButton;
|
||||
class LinkButton;
|
||||
class RoundButton;
|
||||
class FlatLabel;
|
||||
class RippleAnimation;
|
||||
} // namesapce Ui
|
||||
|
||||
|
@ -68,7 +69,7 @@ public:
|
|||
|
||||
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 hideInlineRowsPanel();
|
||||
void clearInlineRowsPanel();
|
||||
|
@ -110,6 +111,8 @@ private:
|
|||
static constexpr bool kRefreshIconsNoAnimation = false;
|
||||
|
||||
void updateSelected();
|
||||
void checkRestrictedPeer();
|
||||
bool isRestrictedView();
|
||||
|
||||
void paintInlineItems(Painter &p, const QRect &r);
|
||||
|
||||
|
@ -120,7 +123,8 @@ private:
|
|||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
|
||||
UserData *_inlineBot;
|
||||
UserData *_inlineBot = nullptr;
|
||||
PeerData *_inlineQueryPeer = nullptr;
|
||||
TimeMs _lastScrolled = 0;
|
||||
QTimer _updateInlineItems;
|
||||
bool _inlineWithThumb = false;
|
||||
|
@ -128,6 +132,8 @@ private:
|
|||
object_ptr<Ui::RoundButton> _switchPmButton = { nullptr };
|
||||
QString _switchPmStartToken;
|
||||
|
||||
object_ptr<Ui::FlatLabel> _restrictedLabel = { nullptr };
|
||||
|
||||
struct Row {
|
||||
int height = 0;
|
||||
QVector<ItemBase*> items;
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace {
|
|||
|
||||
constexpr auto kSaveFloatPlayerPositionTimeoutMs = TimeMs(1000);
|
||||
|
||||
MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||
MTPMessagesFilter TypeToMediaFilter(MediaOverviewType &type) {
|
||||
switch (type) {
|
||||
case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
|
||||
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
|
||||
|
||||
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) {
|
||||
PeerData *p = App::peer(peer);
|
||||
if (!peer || (p->isChannel() && !p->asChannel()->canPublish() && p->asChannel()->isBroadcast()) || (p->isChat() && !p->asChat()->canWrite()) || (p->isUser() && p->asUser()->isInaccessible())) {
|
||||
Ui::show(Box<InformBox>(lang(lng_forward_cant)));
|
||||
bool MainWidget::onForward(const PeerId &peerId, ForwardWhatMessages what) {
|
||||
Expects(peerId != 0);
|
||||
auto peer = App::peer(peerId);
|
||||
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;
|
||||
};
|
||||
if (!peer->canWrite()) {
|
||||
return finishWithError(lang(lng_forward_cant));
|
||||
}
|
||||
_history->cancelReply();
|
||||
_toForward.clear();
|
||||
|
||||
auto toForward = SelectedItemSet();
|
||||
if (what == ForwardSelectedMessages) {
|
||||
if (_overview) {
|
||||
_overview->fillSelectedItems(_toForward, false);
|
||||
_overview->fillSelectedItems(toForward, false);
|
||||
} else {
|
||||
_history->fillSelectedItems(_toForward, false);
|
||||
_history->fillSelectedItems(toForward, false);
|
||||
}
|
||||
} else {
|
||||
HistoryItem *item = 0;
|
||||
auto item = (HistoryItem*)nullptr;
|
||||
if (what == ForwardContextMessage) {
|
||||
item = App::contextItem();
|
||||
} else if (what == ForwardPressedMessage) {
|
||||
|
@ -529,9 +598,25 @@ bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) {
|
|||
item = App::pressedLinkItem();
|
||||
}
|
||||
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();
|
||||
updateForwardingTexts();
|
||||
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||
|
@ -777,23 +862,40 @@ void MainWidget::onUpdateMuted() {
|
|||
App::updateMuted();
|
||||
}
|
||||
|
||||
void MainWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
||||
_history->onShareContact(peer, contact);
|
||||
void MainWidget::onShareContact(const PeerId &peerId, UserData *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);
|
||||
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"))) {
|
||||
onForward(peer, ForwardSelectedMessages);
|
||||
onForward(peerId, ForwardSelectedMessages);
|
||||
} 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"))) {
|
||||
onForward(peer, ForwardPressedMessage);
|
||||
onForward(peerId, ForwardPressedMessage);
|
||||
} else {
|
||||
auto peer = App::peer(peerId);
|
||||
if (!peer->canWrite()) {
|
||||
Ui::show(Box<InformBox>(lang(lng_forward_send_files_cant)));
|
||||
return;
|
||||
}
|
||||
Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
|
||||
_history->confirmSendingFiles(data);
|
||||
}
|
||||
|
@ -1622,7 +1724,7 @@ void MainWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
|||
}
|
||||
|
||||
bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
|
||||
auto filter = typeToMediaFilter(type);
|
||||
auto filter = TypeToMediaFilter(type);
|
||||
if (filter.type() == mtpc_inputMessagesFilterEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1695,7 +1797,7 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
|
|||
|
||||
auto minId = history->overviewMinId(type);
|
||||
auto limit = (many || history->overview[type].size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
|
||||
auto filter = typeToMediaFilter(type);
|
||||
auto filter = TypeToMediaFilter(type);
|
||||
if (filter.type() == mtpc_inputMessagesFilterEmpty) {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue