/* 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 "boxes/create_poll_box.h" #include "lang/lang_keys.h" #include "data/data_poll.h" #include "ui/toast/toast.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/fade_wrap.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/shadow.h" #include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" #include "ui/toast/toast.h" #include "main/main_session.h" #include "core/application.h" #include "core/core_settings.h" #include "chat_helpers/emoji_suggestions_widget.h" #include "chat_helpers/message_field.h" #include "chat_helpers/send_context_menu.h" #include "history/view/history_view_schedule_box.h" #include "settings/settings_common.h" #include "base/unique_qptr.h" #include "base/event_filter.h" #include "base/call_delayed.h" #include "window/window_session_controller.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_settings.h" namespace { constexpr auto kQuestionLimit = 255; constexpr auto kMaxOptionsCount = PollData::kMaxOptions; constexpr auto kOptionLimit = 100; constexpr auto kWarnQuestionLimit = 80; constexpr auto kWarnOptionLimit = 30; constexpr auto kSolutionLimit = 200; constexpr auto kWarnSolutionLimit = 60; constexpr auto kErrorLimit = 99; class Options { public: Options( not_null outer, not_null container, not_null session, bool chooseCorrectEnabled); [[nodiscard]] bool hasOptions() const; [[nodiscard]] bool isValid() const; [[nodiscard]] bool hasCorrect() const; [[nodiscard]] std::vector toPollAnswers() const; void focusFirst(); void enableChooseCorrect(bool enabled); [[nodiscard]] rpl::producer usedCount() const; [[nodiscard]] rpl::producer> scrollToWidget() const; [[nodiscard]] rpl::producer<> backspaceInFront() const; [[nodiscard]] rpl::producer<> tabbed() const; private: class Option { public: Option( not_null outer, not_null container, not_null session, int position, std::shared_ptr group); Option(const Option &other) = delete; Option &operator=(const Option &other) = delete; void toggleRemoveAlways(bool toggled); void enableChooseCorrect( std::shared_ptr group); void show(anim::type animated); void destroy(FnMut done); [[nodiscard]] bool hasShadow() const; void createShadow(); void destroyShadow(); [[nodiscard]] bool isEmpty() const; [[nodiscard]] bool isGood() const; [[nodiscard]] bool isTooLong() const; [[nodiscard]] bool isCorrect() const; [[nodiscard]] bool hasFocus() const; void setFocus() const; void clearValue(); void setPlaceholder() const; void removePlaceholder() const; not_null field() const; [[nodiscard]] PollAnswer toPollAnswer(int index) const; [[nodiscard]] rpl::producer removeClicks() const; private: void createRemove(); void createWarning(); void toggleCorrectSpace(bool visible); void updateFieldGeometry(); base::unique_qptr> _wrap; not_null _content; base::unique_qptr> _correct; Ui::Animations::Simple _correctShown; bool _hasCorrect = false; Ui::InputField *_field = nullptr; base::unique_qptr _shadow; base::unique_qptr _remove; rpl::variable *_removeAlways = nullptr; }; [[nodiscard]] bool full() const; [[nodiscard]] bool correctShadows() const; void fixShadows(); void removeEmptyTail(); void addEmptyOption(); void checkLastOption(); void validateState(); void fixAfterErase(); void destroy(std::unique_ptr