diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 10e3a9064..829025603 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -3914,6 +3914,14 @@ void HistoryWidget::setTabbedPanel(std::unique_ptr panel) { } } +bool HistoryWidget::preventsClose(Fn &&continueCallback) const { + if (isRecording()) { + _voiceRecordBar->showDiscardRecordingBox(std::move(continueCallback)); + return true; + } + return false; +} + void HistoryWidget::toggleTabbedSelectorMode() { if (!_peer) { return; diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 62e61c5e7..163b9ac01 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -119,6 +119,8 @@ public: void historyLoaded(); + [[nodiscard]] bool preventsClose(Fn &&continueCallback) const; + // When resizing the widget with top edge moved up or down and we // want to add this top movement to the scroll position, so inner // content will not move. 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 c848c00d7..8b0d40b03 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -2138,6 +2138,14 @@ bool ComposeControls::isRecording() const { return _voiceRecordBar->isRecording(); } +bool ComposeControls::preventsClose(Fn &&continueCallback) const { + if (isRecording()) { + _voiceRecordBar->showDiscardRecordingBox(std::move(continueCallback)); + return true; + } + return false; +} + void ComposeControls::updateInlineBotQuery() { if (!_history) { return; 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 8ca65f62b..30201f1ac 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -135,6 +135,8 @@ public: [[nodiscard]] bool isEditingMessage() const; [[nodiscard]] FullMsgId replyingToMessage() const; + [[nodiscard]] bool preventsClose(Fn &&continueCallback) const; + void showForGrab(); void showStarted(); void showFinished(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index 485fba028..5866a8ad5 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp @@ -1536,9 +1536,10 @@ void VoiceRecordBar::installClickOutsideFilter() { } else if (type == QEvent::ContextMenu || type == QEvent::Shortcut) { return Type::ShowBox; } else if (type == QEvent::MouseButtonPress) { - return (noBox && !_inField.current() && !_lock->underMouse()) - ? Type::ShowBox - : Type::Continue; + return Type::Continue; + // return (noBox && !_inField.current() && !_lock->underMouse()) + // ? Type::ShowBox + // : Type::Continue; } return Type::Continue; }; @@ -1609,4 +1610,22 @@ void VoiceRecordBar::installListenStateFilter() { std::move(keyFilter)); } +void VoiceRecordBar::showDiscardRecordingBox(Fn &&callback) { + if (!isRecording()) { + return; + } + auto sure = [=, callback = std::move(callback)](Fn &&close) { + hideFast(); + close(); + if (callback) { + callback(); + } + }; + Ui::show(Box( + tr::lng_record_lock_cancel_sure(tr::now), + tr::lng_record_lock_discard(tr::now), + st::attentionBoxButton, + std::move(sure))); +} + } // namespace HistoryView::Controls diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h index cb1fc1cfd..ff25e279f 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h @@ -47,6 +47,8 @@ public: int recorderHeight); ~VoiceRecordBar(); + void showDiscardRecordingBox(Fn &&callback); + void startRecording(); void finishAnimating(); void hideAnimated(); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 1787f399b..dc8a02bac 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -1315,6 +1315,10 @@ Dialogs::RowDescriptor RepliesWidget::activeChat() const { }; } +bool RepliesWidget::preventsClose(Fn &&continueCallback) const { + return _composeControls->preventsClose(std::move(continueCallback)); +} + QPixmap RepliesWidget::grabForShowAnimation(const Window::SectionSlideParams ¶ms) { _topBar->updateControlsVisibility(); if (params.withTopBarShadow) _topBarShadow->hide(); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index 93ea4fbb1..fd36d703d 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -75,6 +75,7 @@ public: [[nodiscard]] not_null history() const; Dialogs::RowDescriptor activeChat() const override; + bool preventsClose(Fn &&continueCallback) const override; bool hasTopBarShadow() const override { return true; diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 484fbd69b..fdd6c5cc7 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -894,6 +894,10 @@ Dialogs::RowDescriptor ScheduledWidget::activeChat() const { }; } +bool ScheduledWidget::preventsClose(Fn &&continueCallback) const { + return _composeControls->preventsClose(std::move(continueCallback)); +} + QPixmap ScheduledWidget::grabForShowAnimation(const Window::SectionSlideParams ¶ms) { _topBar->updateControlsVisibility(); if (params.withTopBarShadow) _topBarShadow->hide(); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 31716aaee..0d65a09fd 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -60,6 +60,7 @@ public: not_null history() const; Dialogs::RowDescriptor activeChat() const override; + bool preventsClose(Fn &&continueCallback) const override; bool hasTopBarShadow() const override { return true; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 1d83b39ae..ec111f0e0 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1403,6 +1403,7 @@ void MainWidget::ui_showPeerHistory( PeerId peerId, const SectionShow ¶ms, MsgId showAtMsgId) { + if (auto peer = session().data().peerLoaded(peerId)) { if (peer->migrateTo()) { peer = peer->migrateTo(); @@ -1423,6 +1424,13 @@ void MainWidget::ui_showPeerHistory( return; } + if (!(_history->peer() && _history->peer()->id == peerId) + && preventsCloseSection( + [=] { ui_showPeerHistory(peerId, params, showAtMsgId); }, + params)) { + return; + } + using OriginMessage = SectionShow::OriginMessage; if (const auto origin = std::get_if(¶ms.origin)) { if (const auto returnTo = session().data().message(origin->id)) { @@ -1618,13 +1626,22 @@ void MainWidget::showSection( // return; } + using MementoPtr = std::unique_ptr; + const auto sharedMemento = std::make_shared( + std::move(memento)); + if (preventsCloseSection( + [=] { showSection(base::take(*sharedMemento), params); }, + params)) { + return; + } + // If the window was not resized, but we've enabled // tabbedSelectorSectionEnabled or thirdSectionInfoEnabled // we need to update adaptive layout to Adaptive::ThirdColumn(). updateColumnLayout(); showNewSection( - std::move(memento), + std::move(*sharedMemento), params); } @@ -1880,8 +1897,24 @@ bool MainWidget::stackIsEmpty() const { return _stack.empty(); } +bool MainWidget::preventsCloseSection( + Fn callback, + const SectionShow ¶ms) const { + if (params.thirdColumn || Core::App().passcodeLocked()) { + return false; + } + auto copy = callback; + return (_mainSection && _mainSection->preventsClose(std::move(copy))) + || (_history && _history->preventsClose(std::move(callback))); +} + void MainWidget::showBackFromStack( const SectionShow ¶ms) { + + if (preventsCloseSection([=] { showBackFromStack(params); }, params)) { + return; + } + if (selectingPeer()) { return; } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 3575dea9e..41956098a 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -274,6 +274,9 @@ private: std::unique_ptr &&memento, const SectionShow ¶ms); void dropMainSection(Window::SectionWidget *widget); + bool preventsCloseSection( + Fn callback, + const SectionShow ¶ms) const; Window::SectionSlideParams prepareThirdSectionAnimation(Window::SectionWidget *section); diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h index 6d5f3b7fd..472d5e2b4 100644 --- a/Telegram/SourceFiles/window/section_widget.h +++ b/Telegram/SourceFiles/window/section_widget.h @@ -129,6 +129,10 @@ public: return false; } + virtual bool preventsClose(Fn &&continueCallback) const { + return false; + } + // Create a memento of that section to store it in the history stack. // This method may modify the section ("take" heavy items). virtual std::unique_ptr createMemento();