Added counter label of characters limit for long media captions.

This commit is contained in:
23rd 2024-02-14 19:57:39 +03:00
parent 113c8a797f
commit 5cd0d82ffb
11 changed files with 188 additions and 26 deletions

View File

@ -676,8 +676,6 @@ PRIVATE
history/view/controls/history_view_ttl_button.h
history/view/controls/history_view_voice_record_bar.cpp
history/view/controls/history_view_voice_record_bar.h
history/view/controls/history_view_voice_record_button.cpp
history/view/controls/history_view_voice_record_button.h
history/view/controls/history_view_webpage_processor.cpp
history/view/controls/history_view_webpage_processor.h
history/view/media/history_view_call.cpp

View File

@ -1071,6 +1071,13 @@ historyMessagesTTLLabel: FlatLabel(defaultFlatLabel) {
textFg: windowSubTextFg;
}
historyCharsLimitationLabel: FlatLabel(defaultFlatLabel) {
// The same as a width of the historySendSize.
minWidth: 44px;
align: align(center);
textFg: attentionButtonFg;
}
historyRecordVoiceFg: historyComposeIconFg;
historyRecordVoiceFgOver: historyComposeIconFgOver;
historyRecordVoiceFgInactive: attentionButtonFg;

View File

@ -71,6 +71,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "data/data_group_call.h"
#include "data/data_peer_values.h" // Data::AmPremiumValue.
#include "data/data_premium_limits.h" // Data::PremiumLimits.
#include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h"
#include "history/history.h"
@ -80,6 +82,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_inner_widget.h"
#include "history/history_item_components.h"
#include "history/history_unread_things.h"
#include "history/view/controls/history_view_characters_limit.h"
#include "history/view/controls/history_view_compose_search.h"
#include "history/view/controls/history_view_forward_panel.h"
#include "history/view/controls/history_view_draft_options.h"
@ -1622,6 +1625,8 @@ void HistoryWidget::fieldChanged() {
}
});
checkCharsLimitation();
updateSendButtonType();
if (!HasSendText(_field)) {
_fieldIsEmpty = true;
@ -3836,6 +3841,18 @@ void HistoryWidget::windowIsVisibleChanged() {
});
}
TextWithEntities HistoryWidget::prepareTextForEditMsg() const {
const auto textWithTags = _field->getTextWithAppliedMarkdown();
const auto prepareFlags = Ui::ItemTextOptions(
_history,
session().user()).flags;
auto left = TextWithEntities {
textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
TextUtilities::PrepareForSending(left, prepareFlags);
return left;
}
void HistoryWidget::saveEditMsg() {
Expects(_history != nullptr);
@ -3849,15 +3866,8 @@ void HistoryWidget::saveEditMsg() {
return;
}
const auto webPageDraft = _preview->draft();
const auto textWithTags = _field->getTextWithAppliedMarkdown();
const auto prepareFlags = Ui::ItemTextOptions(
_history,
session().user()).flags;
auto left = prepareTextForEditMsg();
auto sending = TextWithEntities();
auto left = TextWithEntities {
textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
TextUtilities::PrepareForSending(left, prepareFlags);
const auto media = item->media();
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)
@ -7291,6 +7301,36 @@ void HistoryWidget::showPremiumToast(not_null<DocumentData*> document) {
_stickerToast->showFor(document);
}
void HistoryWidget::checkCharsLimitation() {
if (!_history || !_editMsgId) {
if (_charsLimitation) {
_charsLimitation = nullptr;
}
return;
}
const auto limits = Data::PremiumLimits(&session());
const auto left = prepareTextForEditMsg();
const auto remove = left.text.size() - limits.captionLengthCurrent();
if (remove > 0) {
if (!_charsLimitation) {
_charsLimitation = base::make_unique_q<CharactersLimitLabel>(
this,
_send.get());
_charsLimitation->show();
Data::AmPremiumValue(
&session()
) | rpl::start_with_next([=] {
checkCharsLimitation();
}, _charsLimitation->lifetime());
}
_charsLimitation->setLeft(remove);
} else {
if (_charsLimitation) {
_charsLimitation = nullptr;
}
}
}
void HistoryWidget::setFieldText(
const TextWithTags &textWithTags,
TextUpdateEvents events,
@ -7303,6 +7343,8 @@ void HistoryWidget::setFieldText(
_textUpdateEvents = TextUpdateEvent::SaveDraft
| TextUpdateEvent::SendTyping;
checkCharsLimitation();
if (_preview) {
_preview->checkNow(false);
}

View File

@ -101,6 +101,7 @@ class VoiceRecordBar;
class ForwardPanel;
class TTLButton;
class WebpageProcessor;
class CharactersLimitLabel;
} // namespace HistoryView::Controls
class BotKeyboard;
@ -543,6 +544,7 @@ private:
[[nodiscard]] bool insideJumpToEndInsteadOfToUnread() const;
void createUnreadBarAndResize();
[[nodiscard]] TextWithEntities prepareTextForEditMsg() const;
void saveEditMsg();
void setupPreview();
@ -643,6 +645,8 @@ private:
void switchToSearch(QString query);
void checkCharsLimitation();
MTP::Sender _api;
FullReplyTo _replyTo;
Ui::Text::String _replyToName;
@ -763,6 +767,8 @@ private:
object_ptr<Ui::InputField> _field;
base::unique_qptr<Ui::RpWidget> _fieldDisabled;
base::unique_qptr<Ui::RpWidget> _sendRestriction;
using CharactersLimitLabel = HistoryView::Controls::CharactersLimitLabel;
base::unique_qptr<CharactersLimitLabel> _charsLimitation;
QString _sendRestrictionKey;
Ui::Animations::Simple _inPhotoEditOver;
bool _inDetails = false;

View File

@ -0,0 +1,35 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/controls/history_view_characters_limit.h"
#include "styles/style_chat_helpers.h"
namespace HistoryView::Controls {
CharactersLimitLabel::CharactersLimitLabel(
not_null<Ui::RpWidget*> parent,
not_null<Ui::RpWidget*> widgetBelow)
: Ui::FlatLabel(parent, st::historyCharsLimitationLabel) {
rpl::combine(
Ui::RpWidget::heightValue(),
widgetBelow->positionValue()
) | rpl::start_with_next([=](int height, const QPoint &p) {
move(p.x(), p.y() - height);
}, lifetime());
}
void CharactersLimitLabel::setLeft(int value) {
if (value <= 0) {
return;
}
constexpr auto kMinus = QChar(0x2212);
constexpr auto kLimit = int(999);
Ui::FlatLabel::setText(kMinus + QString::number(std::min(value, kLimit)));
}
} // namespace HistoryView::Controls

View File

@ -0,0 +1,24 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/widgets/labels.h"
namespace HistoryView::Controls {
class CharactersLimitLabel final : public Ui::FlatLabel {
public:
CharactersLimitLabel(
not_null<Ui::RpWidget*> parent,
not_null<Ui::RpWidget*> widgetBelow);
void setLeft(int value);
};
} // namespace HistoryView::Controls

View File

@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum_topic.h"
#include "data/data_peer_values.h"
#include "data/data_photo_media.h"
#include "data/data_premium_limits.h" // Data::PremiumLimits.
#include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_web_page.h"
@ -47,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/power_saving.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/view/controls/history_view_characters_limit.h"
#include "history/view/controls/history_view_forward_panel.h"
#include "history/view/controls/history_view_draft_options.h"
#include "history/view/controls/history_view_voice_record_bar.h"
@ -63,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/audio/media_audio_capture.h"
#include "media/audio/media_audio.h"
#include "settings/settings_premium.h"
#include "ui/item_text_options.h"
#include "ui/text/text_options.h"
#include "ui/text/text_utilities.h"
#include "ui/ui_utility.h"
@ -1205,6 +1208,8 @@ void ComposeControls::setFieldText(
_textUpdateEvents = TextUpdateEvent::SaveDraft
| TextUpdateEvent::SendTyping;
checkCharsLimitation();
if (_preview) {
_preview->checkNow(false);
}
@ -1788,6 +1793,8 @@ void ComposeControls::fieldChanged() {
}
});
checkCharsLimitation();
_saveCloudDraftTimer.cancel();
if (!(_textUpdateEvents & TextUpdateEvent::SaveDraft)) {
return;
@ -2021,6 +2028,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
_preview->setDisabled(false);
}
}
checkCharsLimitation();
}
void ComposeControls::cancelForward() {
@ -3284,4 +3292,50 @@ Fn<void()> ComposeControls::restoreTextCallback(
});
}
TextWithEntities ComposeControls::prepareTextForEditMsg() const {
if (!_history) {
return {};
}
const auto textWithTags = getTextWithAppliedMarkdown();
const auto prepareFlags = Ui::ItemTextOptions(
_history,
session().user()).flags;
auto left = TextWithEntities {
textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
TextUtilities::PrepareForSending(left, prepareFlags);
return left;
}
void ComposeControls::checkCharsLimitation() {
if (!_history || !isEditingMessage()) {
if (_charsLimitation) {
_charsLimitation = nullptr;
}
return;
}
const auto limits = Data::PremiumLimits(&session());
const auto left = prepareTextForEditMsg();
const auto remove = left.text.size() - limits.captionLengthCurrent();
if (remove > 0) {
if (!_charsLimitation) {
using namespace Controls;
_charsLimitation = base::make_unique_q<CharactersLimitLabel>(
_wrap.get(),
_send.get());
_charsLimitation->show();
Data::AmPremiumValue(
&session()
) | rpl::start_with_next([=] {
checkCharsLimitation();
}, _charsLimitation->lifetime());
}
_charsLimitation->setLeft(remove);
} else {
if (_charsLimitation) {
_charsLimitation = nullptr;
}
}
}
} // namespace HistoryView

View File

@ -83,6 +83,7 @@ namespace HistoryView::Controls {
class VoiceRecordBar;
class TTLButton;
class WebpageProcessor;
class CharactersLimitLabel;
} // namespace HistoryView::Controls
namespace HistoryView {
@ -228,6 +229,8 @@ public:
[[nodiscard]] rpl::producer<bool> fieldMenuShownValue() const;
[[nodiscard]] not_null<Ui::RpWidget*> likeAnimationTarget() const;
[[nodiscard]] TextWithEntities prepareTextForEditMsg() const;
void applyCloudDraft();
void applyDraft(
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
@ -334,6 +337,8 @@ private:
void registerDraftSource();
void changeFocusedControl();
void checkCharsLimitation();
const style::ComposeControls &_st;
const ChatHelpers::ComposeFeatures _features;
const not_null<QWidget*> _parent;
@ -373,6 +378,7 @@ private:
std::unique_ptr<Ui::SendAsButton> _sendAs;
std::unique_ptr<Ui::SilentToggle> _silent;
std::unique_ptr<Controls::TTLButton> _ttlInfo;
base::unique_qptr<Controls::CharactersLimitLabel> _charsLimitation;
std::unique_ptr<InlineBots::Layout::Widget> _inlineResults;
std::unique_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;

View File

@ -1229,16 +1229,9 @@ void RepliesWidget::edit(
if (*saveEditMsgRequestId) {
return;
}
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
const auto webpage = _composeControls->webPageDraft();
const auto prepareFlags = Ui::ItemTextOptions(
_history,
session().user()).flags;
auto sending = TextWithEntities();
auto left = TextWithEntities {
textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
TextUtilities::PrepareForSending(left, prepareFlags);
auto left = _composeControls->prepareTextForEditMsg();
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)
&& (!item

View File

@ -649,16 +649,9 @@ void ScheduledWidget::edit(
if (*saveEditMsgRequestId) {
return;
}
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
const auto webpage = _composeControls->webPageDraft();
const auto prepareFlags = Ui::ItemTextOptions(
_history,
session().user()).flags;
auto sending = TextWithEntities();
auto left = TextWithEntities {
textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
TextUtilities::PrepareForSending(left, prepareFlags);
auto left = _composeControls->prepareTextForEditMsg();
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)
&& (!item

View File

@ -100,6 +100,10 @@ PRIVATE
history/history_view_top_toast.cpp
history/history_view_top_toast.h
history/view/controls/history_view_characters_limit.cpp
history/view/controls/history_view_characters_limit.h
history/view/controls/history_view_voice_record_button.cpp
history/view/controls/history_view_voice_record_button.h
info/profile/info_profile_icon.cpp
info/profile/info_profile_icon.h