diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 17cffd96e7..450fea2451 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -634,11 +634,13 @@ HistoryWidget::HistoryWidget( } }, lifetime()); - subscribe(Media::Player::instance()->switchToNextNotifier(), [this](const Media::Player::Instance::Switch &pair) { - if (pair.from.type() == AudioMsgId::Type::Voice) { - scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to); - } - }); + using MediaSwitch = Media::Player::Instance::Switch; + Media::Player::instance()->switchToNextEvents( + ) | rpl::filter([=](const MediaSwitch &pair) { + return (pair.from.type() == AudioMsgId::Type::Voice); + }) | rpl::start_with_next([=](const MediaSwitch &pair) { + scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to); + }, lifetime()); using PeerUpdateFlag = Data::PeerUpdate::Flag; session().changes().peerUpdates( diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f2f776d764..6d1109ac07 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -333,20 +333,8 @@ MainWidget::MainWidget( QCoreApplication::instance()->installEventFilter(this); - subscribe(Media::Player::instance()->playerWidgetOver(), [this](bool over) { - if (over) { - if (_playerPlaylist->isHidden()) { - auto position = mapFromGlobal(QCursor::pos()).x(); - auto bestPosition = _playerPlaylist->bestPositionFor(position); - if (rtl()) bestPosition = position + 2 * (position - bestPosition) - _playerPlaylist->width(); - updateMediaPlaylistPosition(bestPosition); - } - _playerPlaylist->showFromOther(); - } else { - _playerPlaylist->hideFromOther(); - } - }); - subscribe(Media::Player::instance()->tracksFinishedNotifier(), [this](AudioMsgId::Type type) { + Media::Player::instance()->tracksFinished( + ) | rpl::start_with_next([=](AudioMsgId::Type type) { if (type == AudioMsgId::Type::Voice) { const auto songState = Media::Player::instance()->getState(AudioMsgId::Type::Song); if (!songState.id || IsStoppedOrStopping(songState.state)) { @@ -358,7 +346,7 @@ MainWidget::MainWidget( closeBothPlayers(); } } - }); + }, lifetime()); _controller->adaptive().changes( ) | rpl::start_with_next([=] { @@ -846,6 +834,21 @@ void MainWidget::createPlayer() { not_null item) { _controller->showPeerHistoryAtItem(item); }); + + _player->entity()->togglePlaylistRequests( + ) | rpl::start_with_next([=](bool shown) { + if (!shown) { + _playerPlaylist->hideFromOther(); + return; + } else if (_playerPlaylist->isHidden()) { + auto position = mapFromGlobal(QCursor::pos()).x(); + auto bestPosition = _playerPlaylist->bestPositionFor(position); + if (rtl()) bestPosition = position + 2 * (position - bestPosition) - _playerPlaylist->width(); + updateMediaPlaylistPosition(bestPosition); + } + _playerPlaylist->showFromOther(); + }, _player->lifetime()); + _playerVolume.create(this); Media::Player::PrepareVolumeDropdown( _playerVolume.data(), diff --git a/Telegram/SourceFiles/media/player/media_player_float.cpp b/Telegram/SourceFiles/media/player/media_player_float.cpp index bcd25405b5..e1899950f1 100644 --- a/Telegram/SourceFiles/media/player/media_player_float.cpp +++ b/Telegram/SourceFiles/media/player/media_player_float.cpp @@ -299,12 +299,12 @@ FloatController::Item::Item( FloatController::FloatController(not_null delegate) : _delegate(delegate) , _parent(_delegate->floatPlayerWidget()) { - subscribe(Media::Player::instance()->trackChangedNotifier(), [=]( - AudioMsgId::Type type) { - if (type == AudioMsgId::Type::Voice) { - checkCurrent(); - } - }); + Media::Player::instance()->trackChanged( + ) | rpl::filter([=](AudioMsgId::Type type) { + return (type == AudioMsgId::Type::Voice); + }) | rpl::start_with_next([=] { + checkCurrent(); + }, _lifetime); startDelegateHandling(); } diff --git a/Telegram/SourceFiles/media/player/media_player_float.h b/Telegram/SourceFiles/media/player/media_player_float.h index 9edb4af416..6c3b0109e4 100644 --- a/Telegram/SourceFiles/media/player/media_player_float.h +++ b/Telegram/SourceFiles/media/player/media_player_float.h @@ -262,6 +262,8 @@ private: rpl::event_stream _closeEvents; rpl::lifetime _delegateLifetime; + rpl::lifetime _lifetime; + }; } // namespace Player diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 099feec2ee..617d4b189a 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -182,7 +182,7 @@ void Instance::setCurrent(const AudioMsgId &audioId) { data->migrated = nullptr; data->session = nullptr; } - _trackChangedNotifier.notify(data->type, true); + _trackChanged.fire_copy(data->type); refreshPlaylist(data); } } @@ -369,7 +369,7 @@ bool Instance::moveInPlaylist( if (const auto media = item->media()) { if (const auto document = media->document()) { if (autonext) { - _switchToNextNotifier.notify({ + _switchToNextStream.fire({ data->current, item->fullId() }); @@ -558,8 +558,8 @@ void Instance::stop(AudioMsgId::Type type) { void Instance::stopAndClear(not_null data) { stop(data->type); - _tracksFinishedNotifier.notify(data->type); *data = Data(data->type, data->overview); + _tracksFinished.fire_copy(data->type); } void Instance::playPause(AudioMsgId::Type type) { @@ -744,15 +744,19 @@ void Instance::emitUpdate(AudioMsgId::Type type, CheckCallback check) { streamed->progress.updateState(state); } } + auto finished = false; _updatedNotifier.fire_copy({state}); if (data->isPlaying && state.state == State::StoppedAtEnd) { if (data->repeat.current() == RepeatMode::One) { play(data->current); } else if (!moveInPlaylist(data, 1, true)) { - _tracksFinishedNotifier.notify(type); + finished = true; } } data->isPlaying = !IsStopped(state.state); + if (finished) { + _tracksFinished.fire_copy(type); + } } } diff --git a/Telegram/SourceFiles/media/player/media_player_instance.h b/Telegram/SourceFiles/media/player/media_player_instance.h index 39b9ce5133..9645c3ec50 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.h +++ b/Telegram/SourceFiles/media/player/media_player_instance.h @@ -188,31 +188,30 @@ public: FullMsgId to; }; - base::Observable &switchToNextNotifier() { - return _switchToNextNotifier; + [[nodiscard]] rpl::producer switchToNextEvents() const { + return _switchToNextStream.events(); } - base::Observable &playerWidgetOver() { - return _playerWidgetOver; + [[nodiscard]] rpl::producer tracksFinished() const { + return _tracksFinished.events(); } - base::Observable &tracksFinishedNotifier() { - return _tracksFinishedNotifier; - } - base::Observable &trackChangedNotifier() { - return _trackChangedNotifier; + [[nodiscard]] rpl::producer trackChanged() const { + return _trackChanged.events(); } - rpl::producer<> playlistChanges(AudioMsgId::Type type) const; + [[nodiscard]] rpl::producer<> playlistChanges( + AudioMsgId::Type type) const; - rpl::producer updatedNotifier() const { + [[nodiscard]] rpl::producer updatedNotifier() const { return _updatedNotifier.events(); } - rpl::producer<> stops(AudioMsgId::Type type) const; - rpl::producer<> startsPlay(AudioMsgId::Type type) const; + [[nodiscard]] rpl::producer<> stops(AudioMsgId::Type type) const; + [[nodiscard]] rpl::producer<> startsPlay(AudioMsgId::Type type) const; - rpl::producer seekingChanges(AudioMsgId::Type type) const; + [[nodiscard]] rpl::producer seekingChanges( + AudioMsgId::Type type) const; - bool pauseGifByRoundVideo() const; + [[nodiscard]] bool pauseGifByRoundVideo() const; void documentLoadProgress(DocumentData *document); @@ -323,11 +322,9 @@ private: Data _voiceData; bool _roundPlaying = false; - base::Observable _switchToNextNotifier; - base::Observable _playerWidgetOver; - base::Observable _tracksFinishedNotifier; - base::Observable _trackChangedNotifier; - + rpl::event_stream _switchToNextStream; + rpl::event_stream _tracksFinished; + rpl::event_stream _trackChanged; rpl::event_stream _playerStopped; rpl::event_stream _playerStartedPlay; rpl::event_stream _updatedNotifier; diff --git a/Telegram/SourceFiles/media/player/media_player_widget.cpp b/Telegram/SourceFiles/media/player/media_player_widget.cpp index 5083f83a64..c0c5836bcb 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.cpp +++ b/Telegram/SourceFiles/media/player/media_player_widget.cpp @@ -324,23 +324,26 @@ Widget::Widget(QWidget *parent, not_null session) instance()->updateVoicePlaybackSpeed(); }, lifetime()); - subscribe(instance()->trackChangedNotifier(), [this](AudioMsgId::Type type) { - if (type == _type) { - handleSongChange(); - updateControlsVisibility(); - updateLabelsGeometry(); + instance()->trackChanged( + ) | rpl::filter([=](AudioMsgId::Type type) { + return (type == _type); + }) | rpl::start_with_next([=](AudioMsgId::Type type) { + handleSongChange(); + updateControlsVisibility(); + updateLabelsGeometry(); + }, lifetime()); + + instance()->tracksFinished( + ) | rpl::filter([=](AudioMsgId::Type type) { + return (type == AudioMsgId::Type::Voice); + }) | rpl::start_with_next([=](AudioMsgId::Type type) { + _voiceIsActive = false; + const auto currentSong = instance()->current(AudioMsgId::Type::Song); + const auto songState = instance()->getState(AudioMsgId::Type::Song); + if (currentSong == songState.id && !IsStoppedOrStopping(songState.state)) { + setType(AudioMsgId::Type::Song); } - }); - subscribe(instance()->tracksFinishedNotifier(), [this](AudioMsgId::Type type) { - if (type == AudioMsgId::Type::Voice) { - _voiceIsActive = false; - const auto currentSong = instance()->current(AudioMsgId::Type::Song); - const auto songState = instance()->getState(AudioMsgId::Type::Song); - if (currentSong == songState.id && !IsStoppedOrStopping(songState.state)) { - setType(AudioMsgId::Type::Song); - } - } - }); + }, lifetime()); instance()->updatedNotifier( ) | rpl::start_with_next([=](const TrackState &state) { @@ -521,8 +524,7 @@ void Widget::updateOverLabelsState(bool over) { _labelsOver = over; auto pressShowsItem = _labelsOver && (_type == AudioMsgId::Type::Voice); setCursor(pressShowsItem ? style::cur_pointer : style::cur_default); - auto showPlaylist = over && (_type == AudioMsgId::Type::Song); - instance()->playerWidgetOver().notify(showPlaylist, true); + _togglePlaylistRequests.fire(over && (_type == AudioMsgId::Type::Song)); } void Widget::updatePlayPrevNextPositions() { diff --git a/Telegram/SourceFiles/media/player/media_player_widget.h b/Telegram/SourceFiles/media/player/media_player_widget.h index 7b8f91301b..aeb8131f9d 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.h +++ b/Telegram/SourceFiles/media/player/media_player_widget.h @@ -50,12 +50,16 @@ public: void showShadow(); void hideShadow(); - QPoint getPositionForVolumeWidget() const; + [[nodiscard]] QPoint getPositionForVolumeWidget() const; void volumeWidgetCreated(Dropdown *widget); - QPoint getPositionForRepeatWidget() const; + [[nodiscard]] QPoint getPositionForRepeatWidget() const; void repeatWidgetCreated(Dropdown *widget); + [[nodiscard]] rpl::producer togglePlaylistRequests() const { + return _togglePlaylistRequests.events(); + } + ~Widget(); protected: @@ -114,6 +118,7 @@ private: bool _labelsOver = false; bool _labelsDown = false; + rpl::event_stream _togglePlaylistRequests; class PlayButton; class SpeedButton; diff --git a/Telegram/SourceFiles/media/system_media_controls_manager.cpp b/Telegram/SourceFiles/media/system_media_controls_manager.cpp index 43a25de588..5e37f2f049 100644 --- a/Telegram/SourceFiles/media/system_media_controls_manager.cpp +++ b/Telegram/SourceFiles/media/system_media_controls_manager.cpp @@ -96,8 +96,7 @@ SystemMediaControlsManager::SystemMediaControlsManager( _lifetimeDownload.destroy(); }, _lifetime); - auto trackChanged = base::ObservableViewer( - mediaPlayer->trackChangedNotifier() + auto trackChanged = mediaPlayer->trackChanged( ) | rpl::filter([=](AudioMsgId::Type audioType) { return audioType == type; });