diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 0f3a21055b..d3f51ae454 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -2137,6 +2137,14 @@ void HistoryWidget::fileChosen(ChatHelpers::FileChosen &&data) { } } +bool HistoryWidget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + if (!_peer) { + return false; + } + fileChosen(std::move(chosen)); + return true; +} + void HistoryWidget::saveCloudDraft() { controller()->session().api().saveCurrentDraftToCloud(); } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 3f79a66915..5730a121ce 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -295,7 +295,8 @@ public: void confirmDeleteSelected(); void clearSelected(); - [[nodiscard]] SendMenu::Details sendMenuDetails() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; [[nodiscard]] SendMenu::Details saveMenuDetails() const; bool sendExistingDocument( not_null document, diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index e376e72623..413440d7da 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -1879,6 +1879,10 @@ bool ComposeControls::confirmMediaEdit(Ui::PreparedList &list) { return true; } +void ComposeControls::processChosenSticker(FileChosen &&chosen) { + _stickerOrEmojiChosen.fire(std::move(chosen)); +} + rpl::producer ComposeControls::fileChosen() const { return _fileChosen.events(); } diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h index 2adc246881..cfd792d62c 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -202,6 +202,7 @@ public: Fn, Api::SendOptions)> confirmed); + void processChosenSticker(FileChosen &&chosen); [[nodiscard]] rpl::producer fileChosen() const; [[nodiscard]] rpl::producer photoChosen() const; [[nodiscard]] rpl::producer jumpToItemRequests() const; diff --git a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp index 138dd8f110..92f92f2a0c 100644 --- a/Telegram/SourceFiles/history/view/history_view_chat_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_chat_section.cpp @@ -1822,6 +1822,11 @@ SendMenu::Details ChatWidget::sendMenuDetails() const { return SendMenu::Details{ .type = type }; } +bool ChatWidget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + _composeControls->processChosenSticker(std::move(chosen)); + return true; +} + FullReplyTo ChatWidget::replyTo() const { if (auto custom = _composeControls->replyingToMessage()) { const auto item = custom.messageId diff --git a/Telegram/SourceFiles/history/view/history_view_chat_section.h b/Telegram/SourceFiles/history/view/history_view_chat_section.h index 997e4f09d9..355659d39e 100644 --- a/Telegram/SourceFiles/history/view/history_view_chat_section.h +++ b/Telegram/SourceFiles/history/view/history_view_chat_section.h @@ -312,7 +312,8 @@ private: mtpRequestId *const saveEditMsgRequestId, bool spoilered); void chooseAttach(std::optional overrideSendImagesAsPhotos); - [[nodiscard]] SendMenu::Details sendMenuDetails() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; [[nodiscard]] FullReplyTo replyTo() const; [[nodiscard]] HistoryItem *lookupRepliesRoot() const; [[nodiscard]] Data::ForumTopic *lookupTopic(); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index cae8dc159e..1d0133f9d8 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -940,6 +940,11 @@ SendMenu::Details ScheduledWidget::sendMenuDetails() const { return { .type = type, .effectAllowed = effectAllowed }; } +bool ScheduledWidget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + _composeControls->processChosenSticker(std::move(chosen)); + return true; +} + void ScheduledWidget::cornerButtonsShowAtPosition( Data::MessagePosition position) { showAtPosition(position); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 3d03c52a37..82ee98d3eb 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -239,7 +239,8 @@ private: bool spoilered); void highlightSingleNewMessage(const Data::MessagesSlice &slice); void chooseAttach(); - [[nodiscard]] SendMenu::Details sendMenuDetails() const; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; void pushReplyReturn(not_null item); void checkReplyReturns(); diff --git a/Telegram/SourceFiles/info/info_content_widget.cpp b/Telegram/SourceFiles/info/info_content_widget.cpp index de6dad657d..b41b18d85d 100644 --- a/Telegram/SourceFiles/info/info_content_widget.cpp +++ b/Telegram/SourceFiles/info/info_content_widget.cpp @@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_controller.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "menu/menu_send.h" #include "ui/controls/swipe_handler.h" #include "ui/widgets/scroll_area.h" #include "ui/widgets/fields/input_field.h" @@ -426,6 +427,14 @@ void ContentWidget::saveChanges(FnMut done) { done(); } +SendMenu::Details ContentWidget::sendMenuDetails() const { + return {}; +} + +bool ContentWidget::processChosenSticker(ChatHelpers::FileChosen &&) { + return false; +} + void ContentWidget::refreshSearchField(bool shown) { auto search = _controller->searchFieldController(); if (search && shown) { diff --git a/Telegram/SourceFiles/info/info_content_widget.h b/Telegram/SourceFiles/info/info_content_widget.h index 3b89c10c6a..4f064c969d 100644 --- a/Telegram/SourceFiles/info/info_content_widget.h +++ b/Telegram/SourceFiles/info/info_content_widget.h @@ -40,6 +40,14 @@ namespace Ui::Menu { struct MenuCallback; } // namespace Ui::Menu +namespace ChatHelpers { +struct FileChosen; +} // namespace ChatHelpers + +namespace SendMenu { +struct Details; +} // namespace SendMenu + namespace Info::Settings { struct Tag; } // namespace Info::Settings @@ -141,6 +149,8 @@ public: -> rpl::producer; virtual void saveChanges(FnMut done); + [[nodiscard]] virtual SendMenu::Details sendMenuDetails() const; + virtual bool processChosenSticker(ChatHelpers::FileChosen &&chosen); [[nodiscard]] int scrollBottomSkip() const; [[nodiscard]] rpl::producer scrollBottomSkipValue() const; diff --git a/Telegram/SourceFiles/info/info_layer_widget.cpp b/Telegram/SourceFiles/info/info_layer_widget.cpp index 845ab1b778..2c98bc987b 100644 --- a/Telegram/SourceFiles/info/info_layer_widget.cpp +++ b/Telegram/SourceFiles/info/info_layer_widget.cpp @@ -31,6 +31,7 @@ LayerWidget::LayerWidget( not_null memento) : _controller(controller) , _contentWrap(this, controller, Wrap::Layer, memento) { + controller->registerActiveLayerSection(_contentWrap.data()); setupHeightConsumers(); controller->window().replaceFloatPlayerDelegate(floatPlayerDelegate()); } @@ -40,6 +41,7 @@ LayerWidget::LayerWidget( not_null memento) : _controller(controller) , _contentWrap(memento->takeContent(this, Wrap::Layer)) { + controller->registerActiveLayerSection(_contentWrap.data()); setupHeightConsumers(); controller->window().replaceFloatPlayerDelegate(floatPlayerDelegate()); } @@ -161,6 +163,7 @@ void LayerWidget::parentResized() { if (parentWidth < MinimalSupportedWidth()) { Ui::FocusPersister persister(this); restoreFloatPlayerDelegate(); + unregisterActiveLayerSection(); auto memento = std::make_shared(std::move(_contentWrap)); @@ -374,11 +377,19 @@ void LayerWidget::restoreFloatPlayerDelegate() { } } +void LayerWidget::unregisterActiveLayerSection() { + if (_contentWrap) { + _controller->unregisterActiveLayerSection(_contentWrap.data()); + } +} + void LayerWidget::closeHook() { + unregisterActiveLayerSection(); restoreFloatPlayerDelegate(); } LayerWidget::~LayerWidget() { + unregisterActiveLayerSection(); if (!Core::Quitting()) { restoreFloatPlayerDelegate(); } diff --git a/Telegram/SourceFiles/info/info_layer_widget.h b/Telegram/SourceFiles/info/info_layer_widget.h index df8bc2726d..403c04271c 100644 --- a/Telegram/SourceFiles/info/info_layer_widget.h +++ b/Telegram/SourceFiles/info/info_layer_widget.h @@ -70,6 +70,7 @@ private: void setupHeightConsumers(); void setContentHeight(int height); + void unregisterActiveLayerSection(); [[nodiscard]] QRect countGeometry(int newWidth); not_null _controller; diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index b7c909927a..a2f15f1418 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -50,6 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "lang/lang_keys.h" #include "lang/lang_numbers_animation.h" +#include "menu/menu_send.h" #include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_info.h" #include "styles/style_profile.h" @@ -900,6 +901,16 @@ std::shared_ptr WrapWidget::createMemento() { return std::make_shared(std::move(stack)); } +SendMenu::Details WrapWidget::sendMenuDetails() const { + return _content ? _content->sendMenuDetails() : SendMenu::Details(); +} + +bool WrapWidget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + return _content + ? _content->processChosenSticker(std::move(chosen)) + : false; +} + rpl::producer WrapWidget::desiredHeightValue() const { return _desiredHeights.events_starting_with(desiredHeightForContent()) | rpl::flatten_latest(); diff --git a/Telegram/SourceFiles/info/info_wrap_widget.h b/Telegram/SourceFiles/info/info_wrap_widget.h index fdfe5e8348..1924368169 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.h +++ b/Telegram/SourceFiles/info/info_wrap_widget.h @@ -119,6 +119,8 @@ public: bool showBackFromStackInternal(const Window::SectionShow ¶ms); void removeFromStack(const std::vector
§ions); std::shared_ptr createMemento() override; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; rpl::producer desiredHeightValue() const override; diff --git a/Telegram/SourceFiles/info/settings/info_settings_widget.cpp b/Telegram/SourceFiles/info/settings/info_settings_widget.cpp index 9764d2f269..0cb5aa3161 100644 --- a/Telegram/SourceFiles/info/settings/info_settings_widget.cpp +++ b/Telegram/SourceFiles/info/settings/info_settings_widget.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/sections/settings_main.h" #include "settings/sections/settings_information.h" #include "settings/settings_common_session.h" +#include "menu/menu_send.h" #include "ui/ui_utility.h" namespace Info { @@ -187,6 +188,19 @@ void Widget::saveChanges(FnMut done) { _inner->sectionSaveChanges(std::move(done)); } +SendMenu::Details Widget::sendMenuDetails() const { + if (const auto provider + = dynamic_cast( + _inner.get())) { + return provider->sendMenuDetails(); + } + return ContentWidget::sendMenuDetails(); +} + +bool Widget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + return _inner->processChosenSticker(std::move(chosen)); +} + void Widget::showFinished() { _inner->showFinished(); diff --git a/Telegram/SourceFiles/info/settings/info_settings_widget.h b/Telegram/SourceFiles/info/settings/info_settings_widget.h index 5070a7f2a5..0acbf6acd1 100644 --- a/Telegram/SourceFiles/info/settings/info_settings_widget.h +++ b/Telegram/SourceFiles/info/settings/info_settings_widget.h @@ -80,6 +80,8 @@ public: not_null memento); void saveChanges(FnMut done) override; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; void showFinished() override; void setInnerFocus() override; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index beac8028dd..36135477ff 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1130,7 +1130,15 @@ void MainWidget::exportTopBarHeightUpdated() { } SendMenu::Details MainWidget::sendMenuDetails() const { - return _history->sendMenuDetails(); + return _mainSection + ? _mainSection->sendMenuDetails() + : _history->sendMenuDetails(); +} + +bool MainWidget::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + return _mainSection + ? _mainSection->processChosenSticker(std::move(chosen)) + : _history->processChosenSticker(std::move(chosen)); } void MainWidget::dialogsCancelled() { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 0a200c4a1d..996726c544 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -19,6 +19,10 @@ namespace Bot { struct SendCommandRequest; } // namespace Bot +namespace ChatHelpers { +struct FileChosen; +} // namespace ChatHelpers + namespace SendMenu { struct Details; } // namespace SendMenu @@ -144,6 +148,7 @@ public: void checkMainSectionToLayer(); [[nodiscard]] SendMenu::Details sendMenuDetails() const; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen); [[nodiscard]] bool animatingShow() const; diff --git a/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp b/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp index bfb96335f6..5e1ba123b0 100644 --- a/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp +++ b/Telegram/SourceFiles/settings/business/settings_shortcut_messages.cpp @@ -74,6 +74,7 @@ using namespace HistoryView; class ShortcutMessages : public AbstractSection + , public SendMenuDetailsProvider , private WindowListDelegate , private CornerButtonsDelegate { public: @@ -93,6 +94,8 @@ public: [[nodiscard]] rpl::producer title() override; [[nodiscard]] rpl::producer<> sectionShowBack() override; + [[nodiscard]] SendMenu::Details sendMenuDetails() const override; + bool processChosenSticker(ChatHelpers::FileChosen &&chosen) override; void setInnerFocus() override; rpl::producer selectedListValue() override; @@ -1447,6 +1450,18 @@ void ShortcutMessages::finishSending() { showAtEnd(); } +SendMenu::Details ShortcutMessages::sendMenuDetails() const { + return {}; +} + +bool ShortcutMessages::processChosenSticker(ChatHelpers::FileChosen &&chosen) { + if (!_composeControls) { + return false; + } + _composeControls->processChosenSticker(std::move(chosen)); + return true; +} + void ShortcutMessages::showAtEnd() { showAtPosition(Data::MaxMessagePosition); } diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp index addab0de05..e1855d81b1 100644 --- a/Telegram/SourceFiles/settings/settings_common.cpp +++ b/Telegram/SourceFiles/settings/settings_common.cpp @@ -296,6 +296,10 @@ AbstractSection::AbstractSection( : _controller(controller) { } +bool AbstractSection::processChosenSticker(ChatHelpers::FileChosen &&) { + return false; +} + void AbstractSection::build( not_null container, SectionBuildMethod method) { diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h index c55fbec289..9a62768575 100644 --- a/Telegram/SourceFiles/settings/settings_common.h +++ b/Telegram/SourceFiles/settings/settings_common.h @@ -24,6 +24,14 @@ struct SelectedItems; enum class SelectionAction; } // namespace Info +namespace ChatHelpers { +struct FileChosen; +} // namespace ChatHelpers + +namespace SendMenu { +struct Details; +} // namespace SendMenu + namespace Main { class Session; } // namespace Main @@ -126,6 +134,7 @@ public: virtual void sectionSaveChanges(FnMut done) { done(); } + virtual bool processChosenSticker(ChatHelpers::FileChosen &&chosen); virtual void showFinished() { _showFinished.fire({}); } @@ -195,6 +204,14 @@ private: }; +class SendMenuDetailsProvider { +public: + [[nodiscard]] virtual SendMenu::Details sendMenuDetails() const = 0; + + virtual ~SendMenuDetailsProvider() = default; + +}; + enum class IconType { Rounded, Round, diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp index b417c4a2bb..dc63a402a1 100644 --- a/Telegram/SourceFiles/window/section_widget.cpp +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -24,8 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer_values.h" #include "history/history.h" #include "history/history_item.h" -#include "settings/sections/settings_premium.h" +#include "lang/lang_keys.h" #include "main/main_session.h" +#include "menu/menu_send.h" +#include "settings/sections/settings_premium.h" #include "window/section_memento.h" #include "window/window_slide_animation.h" #include "window/window_session_controller.h" @@ -241,6 +243,14 @@ Main::Session &AbstractSectionWidget::session() const { return _controller->session(); } +SendMenu::Details AbstractSectionWidget::sendMenuDetails() const { + return {}; +} + +bool AbstractSectionWidget::processChosenSticker(ChatHelpers::FileChosen &&) { + return false; +} + SectionWidget::SectionWidget( QWidget *parent, not_null controller, diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h index 2d288810bf..97d23fa18d 100644 --- a/Telegram/SourceFiles/window/section_widget.h +++ b/Telegram/SourceFiles/window/section_widget.h @@ -17,9 +17,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PeerData; namespace ChatHelpers { +struct FileChosen; class Show; } // namespace ChatHelpers +namespace SendMenu { +struct Details; +} // namespace SendMenu + namespace Data { struct ReactionId; class ForumTopic; @@ -72,6 +77,8 @@ public: virtual bool returnTabbedSelector() { return false; } + [[nodiscard]] virtual SendMenu::Details sendMenuDetails() const; + virtual bool processChosenSticker(ChatHelpers::FileChosen &&chosen); private: const not_null _controller; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 2abe006229..5b3484e156 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_chat_switch_process.h" #include "window/window_controller.h" #include "window/window_filters_menu.h" +#include "window/section_widget.h" #include "window/window_separate_id.h" #include "info/channel_statistics/earn/info_channel_earn_list.h" #include "info/peer_gifts/info_peer_gifts_widget.h" @@ -297,6 +298,9 @@ SendMenu::Details MainWindowShow::sendMenuDetails() const { if (!window) { return SendMenu::Details(); } + if (const auto section = window->activeLayerSection()) { + return section->sendMenuDetails(); + } return window->content()->sendMenuDetails(); } @@ -318,7 +322,11 @@ void MainWindowShow::processChosenSticker( ChatHelpers::FileChosen &&chosen) const { if (const auto window = _window.get()) { Ui::PostponeCall(window, [=, chosen = std::move(chosen)]() mutable { - window->stickerOrEmojiChosen(std::move(chosen)); + if (const auto section = window->activeLayerSection()) { + section->processChosenSticker(std::move(chosen)); + } else { + window->content()->processChosenSticker(std::move(chosen)); + } }); } } @@ -3120,6 +3128,20 @@ bool SessionController::isLayerShown() const { return _window->isLayerShown(); } +void SessionController::registerActiveLayerSection(SectionWidget *section) { + _activeLayerSection = section; +} + +void SessionController::unregisterActiveLayerSection(SectionWidget *section) { + if (_activeLayerSection == section) { + _activeLayerSection = nullptr; + } +} + +SectionWidget *SessionController::activeLayerSection() const { + return _activeLayerSection.data(); +} + not_null SessionController::content() const { return widget()->sessionContent(); } diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index bead50cbe1..9ff7406eb2 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_type.h" #include "window/window_adaptive.h" +#include + class PhotoData; class MainWidget; class MainWindow; @@ -108,6 +110,7 @@ using GifPauseReason = ChatHelpers::PauseReason; using GifPauseReasons = ChatHelpers::PauseReasons; class SectionMemento; +class SectionWidget; class Controller; class FiltersMenu; class ChatPreviewManager; @@ -552,6 +555,9 @@ public: } void removeLayerBlackout(); [[nodiscard]] bool isLayerShown() const; + void registerActiveLayerSection(SectionWidget *section); + void unregisterActiveLayerSection(SectionWidget *section); + [[nodiscard]] SectionWidget *activeLayerSection() const; struct ShowCalendarDescriptor { Dialogs::Key chat; @@ -843,6 +849,7 @@ private: rpl::variable _connectingBottomSkip; rpl::event_stream _stickerOrEmojiChosen; + QPointer _activeLayerSection; PeerData *_showEditPeer = nullptr; rpl::variable _openedFolder;