mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show length limit in chat intro fields.
This commit is contained in:
parent
98ce91df39
commit
0887348611
5 changed files with 113 additions and 89 deletions
|
@ -1019,14 +1019,8 @@ void EditTagBox(
|
||||||
struct State {
|
struct State {
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
||||||
QImage image;
|
QImage image;
|
||||||
rpl::variable<int> length;
|
|
||||||
};
|
};
|
||||||
const auto state = field->lifetime().make_state<State>();
|
const auto state = field->lifetime().make_state<State>();
|
||||||
state->length = rpl::single(
|
|
||||||
int(title.size())
|
|
||||||
) | rpl::then(field->changes() | rpl::map([=] {
|
|
||||||
return int(field->getLastText().size());
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (const auto customId = id.custom()) {
|
if (const auto customId = id.custom()) {
|
||||||
state->custom = owner->customEmojiManager().create(
|
state->custom = owner->customEmojiManager().create(
|
||||||
|
@ -1059,28 +1053,8 @@ void EditTagBox(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, field->lifetime());
|
}, field->lifetime());
|
||||||
const auto warning = Ui::CreateChild<Ui::FlatLabel>(
|
|
||||||
field,
|
AddLengthLimitLabel(field, kTagNameLimit);
|
||||||
state->length.value() | rpl::map([](int count) {
|
|
||||||
return (count > kTagNameLimit / 2)
|
|
||||||
? QString::number(kTagNameLimit - count)
|
|
||||||
: QString();
|
|
||||||
}),
|
|
||||||
st::editTagLimit);
|
|
||||||
state->length.value() | rpl::map(
|
|
||||||
rpl::mappers::_1 > kTagNameLimit
|
|
||||||
) | rpl::start_with_next([=](bool exceeded) {
|
|
||||||
warning->setTextColorOverride(exceeded
|
|
||||||
? st::attentionButtonFg->c
|
|
||||||
: std::optional<QColor>());
|
|
||||||
}, warning->lifetime());
|
|
||||||
rpl::combine(
|
|
||||||
field->sizeValue(),
|
|
||||||
warning->sizeValue()
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
warning->moveToRight(0, st::editTagField.textMargins.top());
|
|
||||||
}, warning->lifetime());
|
|
||||||
warning->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
const auto save = [=] {
|
const auto save = [=] {
|
||||||
const auto text = field->getLastText();
|
const auto text = field->getLastText();
|
||||||
|
@ -1840,4 +1814,40 @@ bool ItemHasTtl(HistoryItem *item) {
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddLengthLimitLabel(not_null<Ui::InputField*> field, int limit) {
|
||||||
|
struct State {
|
||||||
|
rpl::variable<int> length;
|
||||||
|
};
|
||||||
|
const auto state = field->lifetime().make_state<State>();
|
||||||
|
state->length = rpl::single(
|
||||||
|
rpl::empty
|
||||||
|
) | rpl::then(field->changes()) | rpl::map([=] {
|
||||||
|
return int(field->getLastText().size());
|
||||||
|
});
|
||||||
|
auto warningText = state->length.value() | rpl::map([=](int count) {
|
||||||
|
const auto threshold = std::min(limit / 2, 9);
|
||||||
|
const auto left = limit - count;
|
||||||
|
return (left < threshold) ? QString::number(left) : QString();
|
||||||
|
});
|
||||||
|
const auto warning = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
field.get(),
|
||||||
|
std::move(warningText),
|
||||||
|
st::editTagLimit);
|
||||||
|
state->length.value() | rpl::map(
|
||||||
|
rpl::mappers::_1 > limit
|
||||||
|
) | rpl::start_with_next([=](bool exceeded) {
|
||||||
|
warning->setTextColorOverride(exceeded
|
||||||
|
? st::attentionButtonFg->c
|
||||||
|
: std::optional<QColor>());
|
||||||
|
}, warning->lifetime());
|
||||||
|
rpl::combine(
|
||||||
|
field->sizeValue(),
|
||||||
|
warning->sizeValue()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
warning->moveToRight(0, 0);
|
||||||
|
}, warning->lifetime());
|
||||||
|
warning->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -123,4 +123,6 @@ void AddEmojiPacksAction(
|
||||||
|
|
||||||
[[nodiscard]] bool ItemHasTtl(HistoryItem *item);
|
[[nodiscard]] bool ItemHasTtl(HistoryItem *item);
|
||||||
|
|
||||||
|
void AddLengthLimitLabel(not_null<Ui::InputField*> field, int limit);
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -16,9 +16,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "history/view/history_view_about_view.h"
|
#include "history/view/history_view_about_view.h"
|
||||||
|
#include "history/view/history_view_context_menu.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_app_config.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "settings/business/settings_recipients_helper.h"
|
#include "settings/business/settings_recipients_helper.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
|
@ -141,6 +144,30 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] int PartLimit(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const QString &key,
|
||||||
|
int defaultValue) {
|
||||||
|
return session->account().appConfig().get<int>(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<Ui::InputField*> AddPartInput(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
rpl::producer<QString> placeholder,
|
||||||
|
QString current,
|
||||||
|
int limit) {
|
||||||
|
const auto field = container->add(
|
||||||
|
object_ptr<Ui::InputField>(
|
||||||
|
container,
|
||||||
|
st::settingsChatIntroField,
|
||||||
|
tr::lng_chat_intro_enter_title(),
|
||||||
|
current),
|
||||||
|
st::settingsChatIntroFieldMargins);
|
||||||
|
field->setMaxLength(limit);
|
||||||
|
HistoryView::AddLengthLimitLabel(field, limit);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::SettingsButton> CreateIntroStickerButton(
|
[[nodiscard]] object_ptr<Ui::SettingsButton> CreateIntroStickerButton(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
@ -266,6 +293,10 @@ PreviewWrap::PreviewWrap(
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
session->downloaderTaskFinished() | rpl::start_with_next([=] {
|
||||||
|
update();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
prepare(std::move(value));
|
prepare(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,19 +469,28 @@ rpl::producer<QString> ChatIntro::title() {
|
||||||
[[nodiscard]] rpl::producer<Data::ChatIntro> IntroWithRandomSticker(
|
[[nodiscard]] rpl::producer<Data::ChatIntro> IntroWithRandomSticker(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<Data::ChatIntro> intro) {
|
rpl::producer<Data::ChatIntro> intro) {
|
||||||
return std::move(intro) | rpl::map([=](Data::ChatIntro intro)
|
auto random = rpl::single(
|
||||||
-> rpl::producer<Data::ChatIntro> {
|
Api::RandomHelloStickerValue(session)
|
||||||
if (intro.sticker) {
|
) | rpl::then(rpl::duplicate(
|
||||||
return rpl::single(std::move(intro));
|
intro
|
||||||
|
) | rpl::map([=](const Data::ChatIntro &intro) {
|
||||||
|
return intro.sticker;
|
||||||
|
}) | rpl::distinct_until_changed(
|
||||||
|
) | rpl::filter([](DocumentData *sticker) {
|
||||||
|
return !sticker;
|
||||||
|
}) | rpl::map([=] {
|
||||||
|
return Api::RandomHelloStickerValue(session);
|
||||||
|
})) | rpl::flatten_latest();
|
||||||
|
|
||||||
|
return rpl::combine(
|
||||||
|
std::move(intro),
|
||||||
|
std::move(random)
|
||||||
|
) | rpl::map([=](Data::ChatIntro intro, DocumentData *hello) {
|
||||||
|
if (!intro.sticker) {
|
||||||
|
intro.sticker = hello;
|
||||||
}
|
}
|
||||||
return Api::RandomHelloStickerValue(
|
return intro;
|
||||||
session
|
});
|
||||||
) | rpl::map([=](DocumentData *sticker) {
|
|
||||||
auto copy = intro;
|
|
||||||
copy.sticker = sticker;
|
|
||||||
return copy;
|
|
||||||
});
|
|
||||||
}) | rpl::flatten_latest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatIntro::setupContent(
|
void ChatIntro::setupContent(
|
||||||
|
@ -458,7 +498,8 @@ void ChatIntro::setupContent(
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
const auto info = &controller->session().data().businessInfo();
|
const auto session = &controller->session();
|
||||||
|
const auto info = &session->data().businessInfo();
|
||||||
const auto current = info->chatIntro();
|
const auto current = info->chatIntro();
|
||||||
|
|
||||||
_intro = info->chatIntro();
|
_intro = info->chatIntro();
|
||||||
|
@ -471,24 +512,20 @@ void ChatIntro::setupContent(
|
||||||
const auto preview = content->add(
|
const auto preview = content->add(
|
||||||
object_ptr<PreviewWrap>(
|
object_ptr<PreviewWrap>(
|
||||||
content,
|
content,
|
||||||
&controller->session(),
|
session,
|
||||||
IntroWithRandomSticker(&controller->session(), _intro.value())),
|
IntroWithRandomSticker(session, _intro.value())),
|
||||||
{});
|
{});
|
||||||
|
|
||||||
const auto title = content->add(
|
const auto title = AddPartInput(
|
||||||
object_ptr<Ui::InputField>(
|
content,
|
||||||
content,
|
tr::lng_chat_intro_enter_title(),
|
||||||
st::settingsChatIntroField,
|
current.title,
|
||||||
tr::lng_chat_intro_enter_title(),
|
PartLimit(session, u"intro_title_length_limit"_q, 32));
|
||||||
current.title),
|
const auto description = AddPartInput(
|
||||||
st::settingsChatIntroFieldMargins);
|
content,
|
||||||
const auto description = content->add(
|
tr::lng_chat_intro_enter_message(),
|
||||||
object_ptr<Ui::InputField>(
|
current.description,
|
||||||
content,
|
PartLimit(session, u"intro_description_length_limit"_q, 70));
|
||||||
st::settingsChatIntroField,
|
|
||||||
tr::lng_chat_intro_enter_message(),
|
|
||||||
current.description),
|
|
||||||
st::settingsChatIntroFieldMargins);
|
|
||||||
content->add(CreateIntroStickerButton(
|
content->add(CreateIntroStickerButton(
|
||||||
content,
|
content,
|
||||||
controller->uiShow(),
|
controller->uiShow(),
|
||||||
|
@ -538,6 +575,9 @@ void ChatIntro::setupContent(
|
||||||
}));
|
}));
|
||||||
resetWrap->entity()->setClickedCallback([=] {
|
resetWrap->entity()->setClickedCallback([=] {
|
||||||
_intro = Data::ChatIntro();
|
_intro = Data::ChatIntro();
|
||||||
|
title->clear();
|
||||||
|
description->clear();
|
||||||
|
title->setFocus();
|
||||||
});
|
});
|
||||||
|
|
||||||
Ui::ResizeFitChild(this, content);
|
Ui::ResizeFitChild(this, content);
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/business/data_shortcut_messages.h"
|
#include "data/business/data_shortcut_messages.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "history/view/history_view_context_menu.h" // AddLengthLimitLabel.
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -211,37 +212,7 @@ void EditShortcutNameBox(
|
||||||
field->selectAll();
|
field->selectAll();
|
||||||
field->setMaxLength(kShortcutLimit * 2);
|
field->setMaxLength(kShortcutLimit * 2);
|
||||||
|
|
||||||
struct State {
|
HistoryView::AddLengthLimitLabel(field, kShortcutLimit);
|
||||||
rpl::variable<int> length;
|
|
||||||
};
|
|
||||||
const auto state = field->lifetime().make_state<State>();
|
|
||||||
state->length = rpl::single(
|
|
||||||
int(name.size())
|
|
||||||
) | rpl::then(field->changes() | rpl::map([=] {
|
|
||||||
return int(field->getLastText().size());
|
|
||||||
}));
|
|
||||||
const auto warning = Ui::CreateChild<Ui::FlatLabel>(
|
|
||||||
field,
|
|
||||||
state->length.value() | rpl::map([](int count) {
|
|
||||||
return (count > kShortcutLimit * 3 / 4)
|
|
||||||
? QString::number(kShortcutLimit - count)
|
|
||||||
: QString();
|
|
||||||
}),
|
|
||||||
st::editTagLimit);
|
|
||||||
state->length.value() | rpl::map(
|
|
||||||
rpl::mappers::_1 > kShortcutLimit
|
|
||||||
) | rpl::start_with_next([=](bool exceeded) {
|
|
||||||
warning->setTextColorOverride(exceeded
|
|
||||||
? st::attentionButtonFg->c
|
|
||||||
: std::optional<QColor>());
|
|
||||||
}, warning->lifetime());
|
|
||||||
rpl::combine(
|
|
||||||
field->sizeValue(),
|
|
||||||
warning->sizeValue()
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
warning->moveToRight(0, 0);
|
|
||||||
}, warning->lifetime());
|
|
||||||
warning->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
const auto callback = [=] {
|
const auto callback = [=] {
|
||||||
const auto name = field->getLastText().trimmed();
|
const auto name = field->getLastText().trimmed();
|
||||||
|
|
|
@ -641,5 +641,6 @@ settingsChatbotsDeleteIcon: icon {{ "dialogs/dialogs_cancel_search", dialogsMenu
|
||||||
settingsChatbotsDeleteIconOver: icon {{ "dialogs/dialogs_cancel_search", dialogsMenuIconFgOver }};
|
settingsChatbotsDeleteIconOver: icon {{ "dialogs/dialogs_cancel_search", dialogsMenuIconFgOver }};
|
||||||
|
|
||||||
settingsChatIntroField: InputField(defaultMultiSelectSearchField) {
|
settingsChatIntroField: InputField(defaultMultiSelectSearchField) {
|
||||||
|
textMargins: margins(2px, 0px, 32px, 0px);
|
||||||
}
|
}
|
||||||
settingsChatIntroFieldMargins: margins(20px, 8px, 20px, 8px);
|
settingsChatIntroFieldMargins: margins(20px, 15px, 20px, 8px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue