diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 008b0dc232..3b5233c25b 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/unread_badge.h" #include "ui/widgets/buttons.h" #include "ui/widgets/dropdown_menu.h" +#include "ui/effects/radial_animation.h" #include "window/window_controller.h" #include "window/window_peer_menu.h" #include "calls/calls_instance.h" @@ -124,10 +125,38 @@ TopBarWidget::TopBarWidget( [this] { updateInfoToggleActive(); }, lifetime()); + rpl::single(rpl::empty_value()) | rpl::then( + base::ObservableViewer(Global::RefConnectionTypeChanged()) + ) | rpl::start_with_next( + [=] { updateConnectingState(); }, + lifetime()); + setCursor(style::cur_pointer); updateControlsVisibility(); } +void TopBarWidget::updateConnectingState() { + const auto mtp = MTP::dcstate(); + if (mtp == MTP::ConnectedState) { + if (_connecting) { + _connecting = nullptr; + update(); + } + } else if (!_connecting) { + _connecting = std::make_unique( + animation(this, &TopBarWidget::step_connecting), + st::topBarConnectingAnimation); + _connecting->start(); + update(); + } +} + +void TopBarWidget::step_connecting(TimeMs ms, bool timer) { + if (timer) { + update(); + } +} + void TopBarWidget::refreshLang() { InvokeQueued(this, [this] { updateControlsGeometry(); }); } @@ -300,24 +329,71 @@ void TopBarWidget::paintTopBar(Painter &p, TimeMs ms) { history->peer->dialogName().drawElided(p, nameleft, nametop, namewidth); p.setFont(st::dialogsTextFont); - if (!history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) { - auto statustext = _titlePeerText; - auto statuswidth = _titlePeerTextWidth; - if (statuswidth > namewidth) { - statustext = st::dialogsTextFont->elided( - statustext, - namewidth, - Qt::ElideLeft); - statuswidth = st::dialogsTextFont->width(statustext); - } - p.setPen(_titlePeerTextOnline - ? st::historyStatusFgActive - : st::historyStatusFg); - p.drawTextLeft(nameleft, statustop, width(), statustext, statuswidth); + if (paintConnectingState(p, nameleft, statustop, width(), ms)) { + return; + } else if (history->paintSendAction( + p, + nameleft, + statustop, + namewidth, + width(), + st::historyStatusFgTyping, + ms)) { + return; + } else { + paintStatus(p, nameleft, statustop, namewidth, width()); } } } +bool TopBarWidget::paintConnectingState( + Painter &p, + int left, + int top, + int outerWidth, + TimeMs ms) { + if (_connecting) { + _connecting->step(ms); + } + if (!_connecting) { + return false; + } + _connecting->draw( + p, + { + st::topBarConnectingPosition.x() + left, + st::topBarConnectingPosition.y() + top + }, + outerWidth); + left += st::topBarConnectingPosition.x() + + st::topBarConnectingAnimation.size.width() + + st::topBarConnectingSkip; + p.setPen(st::historyStatusFg); + p.drawTextLeft(left, top, outerWidth, lang(lng_status_connecting)); + return true; +} + +void TopBarWidget::paintStatus( + Painter &p, + int left, + int top, + int availableWidth, + int outerWidth) { + auto statustext = _titlePeerText; + auto statuswidth = _titlePeerTextWidth; + if (statuswidth > availableWidth) { + statustext = st::dialogsTextFont->elided( + statustext, + availableWidth, + Qt::ElideLeft); + statuswidth = st::dialogsTextFont->width(statustext); + } + p.setPen(_titlePeerTextOnline + ? st::historyStatusFgActive + : st::historyStatusFg); + p.drawTextLeft(left, top, outerWidth, statustext, statuswidth); +} + QRect TopBarWidget::getMembersShowAreaGeometry() const { int membersTextLeft = _leftTaken; int membersTextTop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height; @@ -765,4 +841,6 @@ void TopBarWidget::updateOnlineDisplayIn(TimeMs timeout) { _onlineUpdater.callOnce(timeout); } +TopBarWidget::~TopBarWidget() = default; + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h index 000f23d902..8ee0347264 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h @@ -17,6 +17,7 @@ class RoundButton; class IconButton; class DropdownMenu; class UnreadBadge; +class InfiniteRadialAnimation; } // namespace Ui namespace Window { @@ -38,6 +39,8 @@ public: int canForwardCount = 0; }; + ~TopBarWidget(); + void updateControlsVisibility(); void finishAnimating(); void showSelected(SelectedState state); @@ -78,10 +81,24 @@ private: void showMenu(); void toggleInfoSection(); + void updateConnectingState(); void updateAdaptiveLayout(); int countSelectedButtonsTop(float64 selectedShown); + void step_connecting(TimeMs ms, bool timer); void paintTopBar(Painter &p, TimeMs ms); + void paintStatus( + Painter &p, + int left, + int top, + int availableWidth, + int outerWidth); + bool paintConnectingState( + Painter &p, + int left, + int top, + int outerWidth, + TimeMs ms); QRect getMembersShowAreaGeometry() const; void updateMembersShowArea(); void updateOnlineDisplay(); @@ -125,6 +142,7 @@ private: int _leftTaken = 0; int _rightTaken = 0; bool _animatingMode = false; + std::unique_ptr _connecting; int _unreadCounterSubscription = 0; base::Timer _onlineUpdater; diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index e7cf9f4b4d..8756f2c790 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -704,5 +704,12 @@ topBarFeedInfoButton: FeedUserpicButton(defaultFeedUserpicButton) { photoSize: 20px; } } +topBarConnectingPosition: point(2px, 5px); +topBarConnectingSkip: 6px; +topBarConnectingAnimation: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) { + color: windowSubTextFg; + thickness: 1px; + size: size(8px, 8px); +} infoFeedLeaveIconMargins: margins(10px, 12px, 20px, 10px);