Block field with toast if texts are not allowed.

This commit is contained in:
John Preston 2023-01-31 21:21:47 +04:00
parent d697a57834
commit 2886ae6909
7 changed files with 191 additions and 32 deletions

View file

@ -1944,6 +1944,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_broadcast_ph" = "Broadcast a message..."; "lng_broadcast_ph" = "Broadcast a message...";
"lng_broadcast_silent_ph" = "Silent broadcast..."; "lng_broadcast_silent_ph" = "Silent broadcast...";
"lng_send_anonymous_ph" = "Send anonymously..."; "lng_send_anonymous_ph" = "Send anonymously...";
"lng_send_text_no" = "Text not allowed.";
"lng_send_text_no_about" = "The admins of this group only allow sending {types}.";
"lng_send_text_type_and_last" = "{types} and {last}";
"lng_send_text_type_photos" = "Photos";
"lng_send_text_type_videos" = "Video files";
"lng_send_text_type_video_messages" = "Video Messages";
"lng_send_text_type_music" = "Music";
"lng_send_text_type_voice_messages" = "Voice Messages";
"lng_send_text_type_files" = "Files";
"lng_send_text_type_stickers" = "Stickers & GIFs";
"lng_send_text_type_polls" = "Polls";
"lng_send_as_title" = "Send message as..."; "lng_send_as_title" = "Send message as...";
"lng_send_as_anonymous_admin" = "Anonymous admin"; "lng_send_as_anonymous_admin" = "Anonymous admin";
"lng_send_as_premium_required" = "Subscribe to {link} to be able to comment on behalf of your channels in group chats."; "lng_send_as_premium_required" = "Subscribe to {link} to be able to comment on behalf of your channels in group chats.";

View file

@ -18,7 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/shortcuts.h" #include "core/shortcuts.h"
#include "core/application.h" #include "core/application.h"
#include "core/core_settings.h" #include "core/core_settings.h"
#include "ui/toast/toast.h"
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/ui_utility.h" #include "ui/ui_utility.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -50,6 +52,7 @@ using EditLinkAction = Ui::InputField::EditLinkAction;
using EditLinkSelection = Ui::InputField::EditLinkSelection; using EditLinkSelection = Ui::InputField::EditLinkSelection;
constexpr auto kParseLinksTimeout = crl::time(1000); constexpr auto kParseLinksTimeout = crl::time(1000);
constexpr auto kTypesDuration = 4 * crl::time(1000);
// For mention / custom emoji tags save and validate selfId, // For mention / custom emoji tags save and validate selfId,
// ignore tags for different users. // ignore tags for different users.
@ -773,3 +776,86 @@ void MessageLinksParser::apply(
} }
_list = std::move(parsed); _list = std::move(parsed);
} }
base::unique_qptr<Ui::RpWidget> CreateDisabledFieldView(
QWidget *parent,
not_null<PeerData*> peer) {
auto result = base::make_unique_q<Ui::AbstractButton>(parent);
const auto raw = result.get();
const auto label = CreateChild<Ui::FlatLabel>(
result.get(),
tr::lng_send_text_no(),
st::historySendDisabled);
label->setAttribute(Qt::WA_TransparentForMouseEvents);
raw->setPointerCursor(false);
raw->widthValue(
) | rpl::start_with_next([=](int width) {
const auto &st = st::historyComposeField;
const auto margins = (st.textMargins + st.placeholderMargins);
const auto available = width - margins.left() - margins.right();
const auto skip = st::historySendDisabledIconSkip;
label->resizeToWidth(available - skip);
label->moveToLeft(margins.left() + skip, margins.top(), width);
}, label->lifetime());
raw->paintRequest(
) | rpl::start_with_next([=] {
auto p = QPainter(raw);
const auto &st = st::historyComposeField;
const auto margins = (st.textMargins + st.placeholderMargins);
const auto &icon = st::historySendDisabledIcon;
icon.paint(
p,
margins.left() + st::historySendDisabledPosition.x(),
margins.top() + st::historySendDisabledPosition.y(),
raw->width());
}, raw->lifetime());
using WeakToast = base::weak_ptr<Ui::Toast::Instance>;
const auto toast = raw->lifetime().make_state<WeakToast>();
raw->setClickedCallback([=] {
if (toast->get()) {
return;
}
using Flag = ChatRestriction;
const auto map = base::flat_map<Flag, tr::phrase<>>{
{ Flag::SendPhotos, tr::lng_send_text_type_photos },
{ Flag::SendVideos, tr::lng_send_text_type_videos },
{
Flag::SendVideoMessages,
tr::lng_send_text_type_video_messages,
},
{ Flag::SendMusic, tr::lng_send_text_type_music },
{
Flag::SendVoiceMessages,
tr::lng_send_text_type_voice_messages,
},
{ Flag::SendFiles, tr::lng_send_text_type_files },
{ Flag::SendStickers, tr::lng_send_text_type_stickers },
{ Flag::SendPolls, tr::lng_send_text_type_polls },
};
auto list = QStringList();
for (const auto &[flag, phrase] : map) {
if (Data::CanSend(peer, flag, false)) {
list.append(phrase(tr::now));
}
}
if (list.empty()) {
return;
}
const auto types = (list.size() > 1)
? tr::lng_send_text_type_and_last(
tr::now,
lt_types,
list.mid(0, list.size() - 1).join(", "),
lt_last,
list.back())
: list.back();
*toast = Ui::Toast::Show(parent, {
.text = { tr::lng_send_text_no_about(tr::now, lt_types, types) },
.st = &st::defaultMultilineToast,
.durationMs = kTypesDuration,
.multiline = true,
.slideSide = RectPart::Bottom,
});
});
return result;
}

View file

@ -122,3 +122,7 @@ private:
base::qt_connection _connection; base::qt_connection _connection;
}; };
[[nodiscard]] base::unique_qptr<Ui::RpWidget> CreateDisabledFieldView(
QWidget *parent,
not_null<PeerData*> peer);

View file

@ -918,9 +918,9 @@ void TabbedSelector::checkRestrictedPeer() {
_currentPeer, _currentPeer,
ChatRestriction::SendGifs) ChatRestriction::SendGifs)
: (_currentTabType == SelectorTab::Emoji && _mode == Mode::Full) : (_currentTabType == SelectorTab::Emoji && _mode == Mode::Full)
? (Data::RestrictionError( ? ((true || Data::RestrictionError(
_currentPeer, _currentPeer, // We don't allow input if texts are forbidden.
ChatRestriction::SendInline) ChatRestriction::SendInline))
? Data::RestrictionError( ? Data::RestrictionError(
_currentPeer, _currentPeer,
ChatRestriction::SendOther) ChatRestriction::SendOther)

View file

@ -1737,7 +1737,7 @@ void HistoryWidget::setInnerFocus() {
|| isRecording() || isRecording()
|| isBotStart() || isBotStart()
|| isBlocked() || isBlocked()
|| !_canSendMessages) { || !_canSendTexts) {
_list->setFocus(); _list->setFocus();
} else { } else {
_field->setFocus(); _field->setFocus();
@ -1870,7 +1870,7 @@ void HistoryWidget::fastShowAtEnd(not_null<History*> history) {
void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) { void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
InvokeQueued(this, [=] { updateStickersByEmoji(); }); InvokeQueued(this, [=] { updateStickersByEmoji(); });
if (_voiceRecordBar->isActive()) { if (_voiceRecordBar->isActive() || !_canSendTexts) {
return; return;
} }
@ -1884,7 +1884,7 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
if (!draft || (!_history->localEditDraft({}) && !fieldAvailable)) { if (!draft || (!_history->localEditDraft({}) && !fieldAvailable)) {
auto fieldWillBeHiddenAfterEdit = (!fieldAvailable && _editMsgId != 0); auto fieldWillBeHiddenAfterEdit = (!fieldAvailable && _editMsgId != 0);
clearFieldText(0, fieldHistoryAction); clearFieldText(0, fieldHistoryAction);
_field->setFocus(); setInnerFocus();
_processingReplyItem = _replyEditMsg = nullptr; _processingReplyItem = _replyEditMsg = nullptr;
_processingReplyId = _replyToId = 0; _processingReplyId = _replyToId = 0;
setEditMsgId(0); setEditMsgId(0);
@ -1898,7 +1898,7 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
_textUpdateEvents = 0; _textUpdateEvents = 0;
setFieldText(draft->textWithTags, 0, fieldHistoryAction); setFieldText(draft->textWithTags, 0, fieldHistoryAction);
_field->setFocus(); setInnerFocus();
draft->cursor.applyTo(_field); draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft _textUpdateEvents = TextUpdateEvent::SaveDraft
| TextUpdateEvent::SendTyping; | TextUpdateEvent::SendTyping;
@ -2110,6 +2110,8 @@ void HistoryWidget::showHistory(
_list = nullptr; _list = nullptr;
_peer = nullptr; _peer = nullptr;
_canSendMessages = false; _canSendMessages = false;
_canSendTexts = false;
_fieldDisabled = nullptr;
_silent.destroy(); _silent.destroy();
updateBotKeyboard(); updateBotKeyboard();
} else { } else {
@ -2136,7 +2138,6 @@ void HistoryWidget::showHistory(
if (peerId) { if (peerId) {
_peer = session().data().peer(peerId); _peer = session().data().peer(peerId);
_canSendMessages = Data::CanSendAnything(_peer);
_contactStatus = std::make_unique<HistoryView::ContactStatus>( _contactStatus = std::make_unique<HistoryView::ContactStatus>(
controller(), controller(),
this, this,
@ -2628,6 +2629,13 @@ std::optional<QString> HistoryWidget::writeRestriction() const {
} }
void HistoryWidget::updateControlsVisibility() { void HistoryWidget::updateControlsVisibility() {
auto fieldDisabledRemoved = (_fieldDisabled != nullptr);
const auto guard = gsl::finally([&] {
if (fieldDisabledRemoved) {
_fieldDisabled = nullptr;
}
});
if (!_showAnimation) { if (!_showAnimation) {
_topShadow->setVisible(_peer != nullptr); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr); _topBar->setVisible(_peer != nullptr);
@ -2745,7 +2753,19 @@ void HistoryWidget::updateControlsVisibility() {
_send->show(); _send->show();
updateSendButtonType(); updateSendButtonType();
_field->show(); if (_canSendTexts) {
_field->show();
} else {
fieldDisabledRemoved = false;
if (!_fieldDisabled) {
_fieldDisabled = CreateDisabledFieldView(this, _peer);
orderWidgets();
updateControlsGeometry();
update();
}
_fieldDisabled->show();
hideFieldIfVisible();
}
if (_kbShown) { if (_kbShown) {
_kbScroll->show(); _kbScroll->show();
_tabbedSelectorToggle->hide(); _tabbedSelectorToggle->hide();
@ -3696,7 +3716,7 @@ void HistoryWidget::saveEditMsg() {
cancelEdit(); cancelEdit();
} else if (error == u"MESSAGE_EMPTY"_q) { } else if (error == u"MESSAGE_EMPTY"_q) {
_field->selectAll(); _field->selectAll();
_field->setFocus(); setInnerFocus();
} else { } else {
controller()->showToast({ tr::lng_edit_error(tr::now) }); controller()->showToast({ tr::lng_edit_error(tr::now) });
} }
@ -3819,7 +3839,7 @@ void HistoryWidget::send(Api::SendOptions options) {
hideSelectorControlsAnimated(); hideSelectorControlsAnimated();
if (_previewData && _previewData->pendingTill) previewCancel(); if (_previewData && _previewData->pendingTill) previewCancel();
_field->setFocus(); setInnerFocus();
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) { if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) {
toggleKeyboard(); toggleKeyboard();
@ -4260,7 +4280,7 @@ void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) {
} }
} }
_field->setFocus(); setInnerFocus();
} }
void HistoryWidget::hideSingleUseKeyboard(PeerData *peer, MsgId replyTo) { void HistoryWidget::hideSingleUseKeyboard(PeerData *peer, MsgId replyTo) {
@ -4281,7 +4301,7 @@ void HistoryWidget::hideSingleUseKeyboard(PeerData *peer, MsgId replyTo) {
} }
bool HistoryWidget::insertBotCommand(const QString &cmd) { bool HistoryWidget::insertBotCommand(const QString &cmd) {
if (!canWriteMessage()) { if (!_canSendTexts) {
return false; return false;
} }
@ -4327,7 +4347,7 @@ bool HistoryWidget::insertBotCommand(const QString &cmd) {
{ toInsert, TextWithTags::Tags() }, { toInsert, TextWithTags::Tags() },
TextUpdateEvent::SaveDraft, TextUpdateEvent::SaveDraft,
Ui::InputField::HistoryAction::NewEntry); Ui::InputField::HistoryAction::NewEntry);
_field->setFocus(); setInnerFocus();
return true; return true;
} }
return false; return false;
@ -4808,10 +4828,20 @@ void HistoryWidget::recountChatWidth() {
controller()->adaptive().setChatLayout(layout); controller()->adaptive().setChatLayout(layout);
} }
int HistoryWidget::fieldHeight() const {
return _canSendTexts
? _field->height()
: (st::historySendSize.height() - 2 * st::historySendPadding);
}
bool HistoryWidget::fieldOrDisabledShown() const {
return !_field->isHidden() || _fieldDisabled;
}
void HistoryWidget::moveFieldControls() { void HistoryWidget::moveFieldControls() {
auto keyboardHeight = 0; auto keyboardHeight = 0;
auto bottom = height(); auto bottom = height();
auto maxKeyboardHeight = computeMaxFieldHeight() - _field->height(); auto maxKeyboardHeight = computeMaxFieldHeight() - fieldHeight();
_keyboard->resizeToWidth(width(), maxKeyboardHeight); _keyboard->resizeToWidth(width(), maxKeyboardHeight);
if (_kbShown) { if (_kbShown) {
keyboardHeight = qMin(_keyboard->height(), maxKeyboardHeight); keyboardHeight = qMin(_keyboard->height(), maxKeyboardHeight);
@ -4834,6 +4864,11 @@ void HistoryWidget::moveFieldControls() {
_sendAs->moveToLeft(left, buttonsBottom); left += _sendAs->width(); _sendAs->moveToLeft(left, buttonsBottom); left += _sendAs->width();
} }
_field->moveToLeft(left, bottom - _field->height() - st::historySendPadding); _field->moveToLeft(left, bottom - _field->height() - st::historySendPadding);
if (_fieldDisabled) {
_fieldDisabled->moveToLeft(
left,
bottom - fieldHeight() - st::historySendPadding);
}
auto right = st::historySendRight; auto right = st::historySendRight;
_send->moveToRight(right, buttonsBottom); right += _send->width(); _send->moveToRight(right, buttonsBottom); right += _send->width();
_voiceRecordBar->moveToLeft(0, bottom - _voiceRecordBar->height()); _voiceRecordBar->moveToLeft(0, bottom - _voiceRecordBar->height());
@ -4896,6 +4931,9 @@ void HistoryWidget::updateFieldSize() {
if (_scheduled) fieldWidth -= _scheduled->width(); if (_scheduled) fieldWidth -= _scheduled->width();
if (_ttlInfo) fieldWidth -= _ttlInfo->width(); if (_ttlInfo) fieldWidth -= _ttlInfo->width();
if (_fieldDisabled) {
_fieldDisabled->resize(fieldWidth, fieldHeight());
}
if (_field->width() != fieldWidth) { if (_field->width() != fieldWidth) {
_field->resize(fieldWidth, _field->height()); _field->resize(fieldWidth, _field->height());
} else { } else {
@ -5552,7 +5590,7 @@ void HistoryWidget::updateHistoryGeometry(
newScrollHeight -= _unblock->height(); newScrollHeight -= _unblock->height();
} else { } else {
if (editingMessage() || _canSendMessages) { if (editingMessage() || _canSendMessages) {
newScrollHeight -= (_field->height() + 2 * st::historySendPadding); newScrollHeight -= (fieldHeight() + 2 * st::historySendPadding);
} else if (writeRestriction().has_value()) { } else if (writeRestriction().has_value()) {
newScrollHeight -= _unblock->height(); newScrollHeight -= _unblock->height();
} }
@ -6197,7 +6235,7 @@ void HistoryWidget::sendInlineResult(InlineBots::ResultSelected result) {
hideSelectorControlsAnimated(); hideSelectorControlsAnimated();
_field->setFocus(); setInnerFocus();
} }
void HistoryWidget::updatePinnedViewer() { void HistoryWidget::updatePinnedViewer() {
@ -6690,7 +6728,7 @@ bool HistoryWidget::sendExistingDocument(
hideSelectorControlsAnimated(); hideSelectorControlsAnimated();
_field->setFocus(); setInnerFocus();
return true; return true;
} }
@ -6715,7 +6753,7 @@ bool HistoryWidget::sendExistingPhoto(
hideSelectorControlsAnimated(); hideSelectorControlsAnimated();
_field->setFocus(); setInnerFocus();
return true; return true;
} }
@ -6889,9 +6927,7 @@ void HistoryWidget::setReplyFieldsFromProcessing() {
_saveDraftStart = crl::now(); _saveDraftStart = crl::now();
saveDraft(); saveDraft();
if (!_field->isHidden()) { setInnerFocus();
_field->setFocus();
}
} }
void HistoryWidget::editMessage(FullMsgId itemId) { void HistoryWidget::editMessage(FullMsgId itemId) {
@ -6961,7 +6997,9 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
updateBotKeyboard(); updateBotKeyboard();
if (!_field->isHidden()) _fieldBarCancel->show(); if (fieldOrDisabledShown()) {
_fieldBarCancel->show();
}
updateFieldPlaceholder(); updateFieldPlaceholder();
updateMouseTracking(); updateMouseTracking();
updateReplyToName(); updateReplyToName();
@ -6972,7 +7010,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
_saveDraftStart = crl::now(); _saveDraftStart = crl::now();
saveDraft(); saveDraft();
_field->setFocus(); setInnerFocus();
} }
void HistoryWidget::hidePinnedMessage() { void HistoryWidget::hidePinnedMessage() {
@ -7328,10 +7366,15 @@ bool HistoryWidget::updateCanSendMessage() {
const auto newCanSendMessages = topic const auto newCanSendMessages = topic
? Data::CanSendAnyOf(topic, allWithoutPolls) ? Data::CanSendAnyOf(topic, allWithoutPolls)
: Data::CanSendAnyOf(_peer, allWithoutPolls); : Data::CanSendAnyOf(_peer, allWithoutPolls);
if (_canSendMessages == newCanSendMessages) { const auto newCanSendTexts = topic
? Data::CanSend(topic, ChatRestriction::SendOther)
: Data::CanSend(_peer, ChatRestriction::SendOther);
if (_canSendMessages == newCanSendMessages
&& _canSendTexts == newCanSendTexts) {
return false; return false;
} }
_canSendMessages = newCanSendMessages; _canSendMessages = newCanSendMessages;
_canSendTexts = newCanSendTexts;
if (!_canSendMessages) { if (!_canSendMessages) {
cancelReply(); cancelReply();
} }
@ -7474,7 +7517,7 @@ void HistoryWidget::updateTopBarSelection() {
|| isRecording() || isRecording()
|| isBotStart() || isBotStart()
|| isBlocked() || isBlocked()
|| !_canSendMessages) { || !_canSendTexts) {
_list->setFocus(); _list->setFocus();
} else { } else {
_field->setFocus(); _field->setFocus();
@ -7504,7 +7547,7 @@ void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
item->inReplyText(), item->inReplyText(),
Ui::DialogTextOptions(), Ui::DialogTextOptions(),
context); context);
if (!_field->isHidden() || isRecording()) { if (fieldOrDisabledShown() || isRecording()) {
_fieldBarCancel->show(); _fieldBarCancel->show();
updateMouseTracking(); updateMouseTracking();
} }
@ -7581,7 +7624,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
_repaintFieldScheduled = false; _repaintFieldScheduled = false;
auto backy = _field->y() - st::historySendPadding; auto backy = _field->y() - st::historySendPadding;
auto backh = _field->height() + 2 * st::historySendPadding; auto backh = fieldHeight() + 2 * st::historySendPadding;
auto hasForward = readyToForward(); auto hasForward = readyToForward();
auto drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo; auto drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo;
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) { if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
@ -7801,7 +7844,8 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
const auto clip = e->rect(); const auto clip = e->rect();
if (_list) { if (_list) {
const auto restrictionHidden = !_field->isHidden() || isRecording(); const auto restrictionHidden = fieldOrDisabledShown()
|| isRecording();
if (restrictionHidden if (restrictionHidden
|| replyToId() || replyToId()
|| readyToForward() || readyToForward()
@ -7824,7 +7868,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
const auto tr = QRect( const auto tr = QRect(
(width() - w) / 2, (width() - w) / 2,
st::msgServiceMargin.top() + (height() st::msgServiceMargin.top() + (height()
- _field->height() - fieldHeight()
- 2 * st::historySendPadding - 2 * st::historySendPadding
- h - h
- st::msgServiceMargin.top() - st::msgServiceMargin.top()

View file

@ -569,6 +569,8 @@ private:
void clearFieldText( void clearFieldText(
TextUpdateEvents events = 0, TextUpdateEvents events = 0,
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear); FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
[[nodiscard]] int fieldHeight() const;
[[nodiscard]] bool fieldOrDisabledShown() const;
void unregisterDraftSources(); void unregisterDraftSources();
void registerDraftSource(); void registerDraftSource();
@ -589,8 +591,8 @@ private:
void checkReplyReturns(); void checkReplyReturns();
void scrollToAnimationCallback(FullMsgId attachToId, int relativeTo); void scrollToAnimationCallback(FullMsgId attachToId, int relativeTo);
bool readyToForward() const; [[nodiscard]] bool readyToForward() const;
bool hasSilentToggle() const; [[nodiscard]] bool hasSilentToggle() const;
void checkSupportPreload(bool force = false); void checkSupportPreload(bool force = false);
void handleSupportSwitch(not_null<History*> updated); void handleSupportSwitch(not_null<History*> updated);
@ -676,6 +678,7 @@ private:
PeerData *_peer = nullptr; PeerData *_peer = nullptr;
bool _canSendMessages = false; bool _canSendMessages = false;
bool _canSendTexts = false;
MsgId _showAtMsgId = ShowAtUnreadMsgId; MsgId _showAtMsgId = ShowAtUnreadMsgId;
int _firstLoadRequest = 0; // Not real mtpRequestId. int _firstLoadRequest = 0; // Not real mtpRequestId.
@ -742,6 +745,7 @@ private:
std::unique_ptr<HistoryView::ComposeSearch> _composeSearch; std::unique_ptr<HistoryView::ComposeSearch> _composeSearch;
bool _cmdStartShown = false; bool _cmdStartShown = false;
object_ptr<Ui::InputField> _field; object_ptr<Ui::InputField> _field;
base::unique_qptr<Ui::RpWidget> _fieldDisabled;
bool _inReplyEditForward = false; bool _inReplyEditForward = false;
bool _inClickable = false; bool _inClickable = false;

View file

@ -1247,3 +1247,12 @@ historyTranslateSettings: IconButton(defaultIconButton) {
ripple: defaultRippleAnimation; ripple: defaultRippleAnimation;
} }
historyTranslateMenuPosition: point(-6px, 40px); historyTranslateMenuPosition: point(-6px, 40px);
historySendDisabled: FlatLabel(defaultFlatLabel) {
minWidth: 10px;
maxHeight: 20px;
textFg: placeholderFg;
}
historySendDisabledIcon: icon {{ "emoji/premium_lock", placeholderFgActive }};
historySendDisabledIconSkip: 20px;
historySendDisabledPosition: point(0px, 0px);