Add Expand compose button to open the rich editor

This commit is contained in:
John Preston
2026-06-27 03:59:52 +04:00
parent 7e3ab2e280
commit 2e72ebe2f2
5 changed files with 119 additions and 0 deletions
@@ -1537,6 +1537,10 @@ historySendAsFileButton: IconButton(historyAiComposeButton) {
icon: icon {{ "chat/text_to_file-18x18", historyComposeIconFg }};
iconOver: icon {{ "chat/text_to_file-18x18", historyComposeIconFgOver }};
}
historyExpandComposeButton: IconButton(historyAiComposeButton) {
icon: icon {{ "menu/expand", historyComposeIconFg }};
iconOver: icon {{ "menu/expand", historyComposeIconFgOver }};
}
historyAiComposeTooltipSkip: 8px;
importantTooltipHide: IconButton(defaultIconButton) {
width: 34px;
@@ -288,6 +288,9 @@ HistoryWidget::HistoryWidget(
, _sendAsFile(Ui::CreateChild<Ui::IconButton>(
this,
st::historySendAsFileButton))
, _expand(Ui::CreateChild<Ui::IconButton>(
this,
st::historyExpandComposeButton))
, _unblock(
this,
tr::lng_unblock_button(tr::now).toUpper(),
@@ -467,6 +470,7 @@ HistoryWidget::HistoryWidget(
checkCharsLimitation();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, lifetime());
#ifdef Q_OS_MAC
// Removed an ability to insert text from the menu bar
@@ -537,6 +541,7 @@ HistoryWidget::HistoryWidget(
setupFastButtonMode();
initAiButton();
initSendAsFileButton();
initExpandButton();
_fieldCharsCountManager.limitExceeds(
) | rpl::on_next([=] {
@@ -1349,6 +1354,7 @@ void HistoryWidget::initVoiceRecordBar() {
controller()->widget()->setInnerFocus();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, lifetime());
_voiceRecordBar->hideFast();
@@ -1392,6 +1398,25 @@ void HistoryWidget::initSendAsFileButton() {
[=] { return width(); });
}
void HistoryWidget::initExpandButton() {
_expand->hide();
_expand->setAccessibleName(tr::lng_article_menu_item(tr::now));
_expand->setClickedCallback([=] {
if (!_history) {
return;
}
const auto window = controller();
if (!Iv::Editor::CheckRichMessagesPremium(window)) {
return;
}
Iv::Editor::ShowComposeBox(
window,
_history->peer,
prepareSendAction({}),
[=] { return sendMenuDetails(); });
});
}
void HistoryWidget::sendTextAsFile(
const QString &fileText,
TextWithTags restoreText,
@@ -1946,6 +1971,7 @@ void HistoryWidget::orderWidgets() {
_send->raise();
_aiButton->raise();
_sendAsFile->raise();
_expand->raise();
_richDraftPreview->raise();
_topBars->raise();
if (_businessBotStatus) {
@@ -2078,6 +2104,7 @@ void HistoryWidget::fieldChanged() {
}
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
_saveCloudDraftTimer.cancel();
if (bypassNormalDraftHandling()) {
@@ -4160,6 +4187,7 @@ void HistoryWidget::updateControlsVisibility() {
}
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
updateMouseTracking();
}
@@ -6658,6 +6686,7 @@ void HistoryWidget::toggleKeyboard(bool manual) {
updateControlsGeometry();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
updateFieldPlaceholder();
if (_botKeyboardHide->isHidden()
&& canWriteMessage()
@@ -6847,6 +6876,29 @@ void HistoryWidget::updateAiButtonVisibility() {
}
}
void HistoryWidget::updateExpandButtonVisibility() {
const auto hidden = !_send->isVisible()
|| !_field->isVisible()
|| _voiceRecordBar->isActive()
|| (textExceedsMaxSize() && !editingMessage());
if (_expand->isHidden() != hidden) {
_expand->setVisible(!hidden);
}
updateExpandButtonGeometry();
}
void HistoryWidget::updateExpandButtonGeometry() {
if (_expand->isHidden()) {
return;
}
const auto aiShown = !_aiButton->isHidden();
const auto anchorX = aiShown
? (_tabbedSelectorToggle->x() + _tabbedSelectorToggle->width())
: (_send->x() + _send->width());
const auto x = anchorX - _expand->width();
_expand->move(QPoint(x, _field->y()) + st::historyAiComposeButtonPosition);
}
void HistoryWidget::updateAiButtonGeometry() {
if (_aiButton->isHidden()) {
return;
@@ -6957,6 +7009,7 @@ void HistoryWidget::moveFieldControls() {
}
updateAiButtonGeometry();
updateSendAsFileGeometry();
updateExpandButtonGeometry();
_fieldBarCancel->moveToRight(
0,
@@ -7065,6 +7118,7 @@ void HistoryWidget::fieldResized() {
moveFieldControls();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
updateHistoryGeometry();
updateField();
}
@@ -561,6 +561,9 @@ private:
int restoreAnchor);
void updateSendAsFileVisibility();
void updateSendAsFileGeometry();
void initExpandButton();
void updateExpandButtonVisibility();
void updateExpandButtonGeometry();
[[nodiscard]] bool canSendAiComposeDirect() const;
[[nodiscard]] MsgId resolveReplyToTopicRootId();
@@ -880,6 +883,7 @@ private:
const std::shared_ptr<Ui::SendButton> _send;
HistoryView::Controls::ComposeAiButton * const _aiButton = nullptr;
Ui::IconButton * const _sendAsFile = nullptr;
Ui::IconButton * const _expand = nullptr;
object_ptr<Ui::FlatButton> _unblock;
object_ptr<Ui::FlatButton> _botStart;
object_ptr<Ui::FlatButton> _joinChannel;
@@ -1067,6 +1067,9 @@ ComposeControls::ComposeControls(
_wrap.get(),
st::historySendAsFileButton)
: nullptr)
, _expand(Ui::CreateChild<Ui::IconButton>(
_wrap.get(),
st::historyExpandComposeButton))
, _like(_features.likes
? Ui::CreateChild<Ui::IconButton>(_wrap.get(), _st.like)
: nullptr)
@@ -1988,6 +1991,7 @@ void ComposeControls::showFinished() {
if (_sendAsFile) {
_sendAsFile->raise();
}
_expand->raise();
if (_aiTooltipManager) {
_aiTooltipManager->raise();
}
@@ -2206,6 +2210,7 @@ void ComposeControls::init() {
initSendButton();
initAiButton();
initSendAsFileButton();
initExpandButton();
initWriteRestriction();
initVoiceRecordBar();
initKeyHandler();
@@ -2517,17 +2522,20 @@ void ComposeControls::initField() {
updateHeight();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, _field->lifetime());
_field->changes(
) | rpl::on_next([=] {
fieldChanged();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, _field->lifetime());
Data::AmPremiumValue(&session()) | rpl::on_next([=] {
checkCharsLimitation();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, _wrap->lifetime());
#ifdef Q_OS_MAC
// Removed an ability to insert text from the menu bar
@@ -3530,6 +3538,7 @@ void ComposeControls::initVoiceRecordBar() {
}
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}, _wrap->lifetime());
_voiceRecordBar->setStartRecordingFilter([=] {
@@ -3675,6 +3684,24 @@ void ComposeControls::initSendAsFileButton() {
[=] { return _wrap->width(); });
}
void ComposeControls::initExpandButton() {
_expand->hide();
_expand->setAccessibleName(tr::lng_article_menu_item(tr::now));
_expand->setClickedCallback([=] {
if (!_regularWindow || !_history || !_sendActionFactory) {
return;
}
if (!Iv::Editor::CheckRichMessagesPremium(_regularWindow)) {
return;
}
Iv::Editor::ShowComposeBox(
_regularWindow,
_history->peer,
_sendActionFactory(),
[=] { return sendMenuDetails(); });
});
}
void ComposeControls::setSendAsFileConfirmed(
Fn<void(std::shared_ptr<Ui::PreparedBundle>, Api::SendOptions)> confirmed) {
_sendAsFileConfirmed = std::move(confirmed);
@@ -3746,6 +3773,7 @@ void ComposeControls::updateWrappingVisibility() {
updateControlsParents();
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
if (!hidden && !restricted) {
updateControlsGeometry(_wrap->size());
_wrap->raise();
@@ -3960,6 +3988,7 @@ void ComposeControls::updateControlsGeometry(QSize size) {
}
updateAiButtonGeometry();
updateSendAsFileGeometry();
updateExpandButtonGeometry();
_voiceRecordBar->resizeToWidth(size.width());
_voiceRecordBar->moveToLeft(
@@ -4004,6 +4033,7 @@ void ComposeControls::updateControlsVisibility() {
}
updateAiButtonVisibility();
updateSendAsFileVisibility();
updateExpandButtonVisibility();
}
void ComposeControls::updateAiButtonVisibility() {
@@ -4024,6 +4054,29 @@ void ComposeControls::updateAiButtonVisibility() {
}
}
void ComposeControls::updateExpandButtonVisibility() {
const auto hidden = !_wrap->isVisible()
|| _recording.current()
|| !_field->isVisible()
|| textExceedsMaxSize();
if (_expand->isHidden() != hidden) {
_expand->setVisible(!hidden);
}
updateExpandButtonGeometry();
}
void ComposeControls::updateExpandButtonGeometry() {
if (_expand->isHidden()) {
return;
}
const auto aiShown = !_aiButton->isHidden();
const auto anchorX = aiShown
? (_tabbedSelectorToggle->x() + _tabbedSelectorToggle->width())
: (_send->x() + _send->width());
const auto x = anchorX - _expand->width();
_expand->move(QPoint(x, _field->y()) + st::historyAiComposeButtonPosition);
}
void ComposeControls::updateAiButtonGeometry() {
if (_aiButton->isHidden()) {
return;
@@ -350,6 +350,9 @@ private:
Ui::InputField::MimeAction action);
void updateSendAsFileVisibility();
void updateSendAsFileGeometry();
void initExpandButton();
void updateExpandButtonVisibility();
void updateExpandButtonGeometry();
void setupSendMenu(
not_null<Ui::RpWidget*> button,
Fn<void(Api::SendOptions)> send);
@@ -481,6 +484,7 @@ private:
const std::shared_ptr<Ui::SendButton> _send;
Controls::ComposeAiButton * const _aiButton = nullptr;
Ui::IconButton * const _sendAsFile = nullptr;
Ui::IconButton * const _expand = nullptr;
Ui::IconButton *_editStars = nullptr;
Ui::IconButton *_like = nullptr;
rpl::variable<int> _minStarsCount;