mirror of https://github.com/procxx/kepka.git
				
				
				
			Hide floating player if video message is visible.
This commit is contained in:
		
							parent
							
								
									b7550f63c9
								
							
						
					
					
						commit
						c58a48276f
					
				|  | @ -662,16 +662,10 @@ void HistoryWidget::scrollToCurrentVoiceMessage(FullMsgId fromId, FullMsgId toId | ||||||
| 	// And the scrollTop will be reset back to scrollTopItem + scrollTopOffset.
 | 	// And the scrollTop will be reset back to scrollTopItem + scrollTopOffset.
 | ||||||
| 	notify_handlePendingHistoryUpdate(); | 	notify_handlePendingHistoryUpdate(); | ||||||
| 
 | 
 | ||||||
| 	auto fromTop = _list->itemTop(from); |  | ||||||
| 	auto toTop = _list->itemTop(to); | 	auto toTop = _list->itemTop(to); | ||||||
| 	if (fromTop < 0 || toTop < 0) { | 	if (toTop >= 0 && !isItemCompletelyHidden(from)) { | ||||||
| 		return; | 		auto scrollTop = _scroll->scrollTop(); | ||||||
| 	} | 		auto scrollBottom = scrollTop + _scroll->height(); | ||||||
| 
 |  | ||||||
| 	auto scrollTop = _scroll->scrollTop(); |  | ||||||
| 	auto scrollBottom = scrollTop + _scroll->height(); |  | ||||||
| 	auto fromBottom = fromTop + from->height(); |  | ||||||
| 	if (fromTop < scrollBottom && fromBottom > scrollTop) { |  | ||||||
| 		auto toBottom = toTop + to->height(); | 		auto toBottom = toTop + to->height(); | ||||||
| 		if ((toTop < scrollTop && toBottom < scrollBottom) || (toTop > scrollTop && toBottom > scrollBottom)) { | 		if ((toTop < scrollTop && toBottom < scrollBottom) || (toTop > scrollTop && toBottom > scrollBottom)) { | ||||||
| 			auto scrollTo = snap(itemTopForHighlight(to), 0, _scroll->scrollTopMax()); | 			auto scrollTo = snap(itemTopForHighlight(to), 0, _scroll->scrollTopMax()); | ||||||
|  | @ -2636,10 +2630,22 @@ void HistoryWidget::onScroll() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool HistoryWidget::isItemCompletelyHidden(HistoryItem *item) const { | ||||||
|  | 	auto top = _list->itemTop(item); | ||||||
|  | 	if (top < 0) { | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	auto bottom = top + item->height(); | ||||||
|  | 	auto scrollTop = _scroll->scrollTop(); | ||||||
|  | 	auto scrollBottom = scrollTop + _scroll->height(); | ||||||
|  | 	return (top >= scrollBottom || bottom <= scrollTop); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void HistoryWidget::visibleAreaUpdated() { | void HistoryWidget::visibleAreaUpdated() { | ||||||
| 	if (_list && !_scroll->isHidden()) { | 	if (_list && !_scroll->isHidden()) { | ||||||
| 		int scrollTop = _scroll->scrollTop(); | 		auto scrollTop = _scroll->scrollTop(); | ||||||
| 		int scrollBottom = scrollTop + _scroll->height(); | 		auto scrollBottom = scrollTop + _scroll->height(); | ||||||
| 		_list->visibleAreaUpdated(scrollTop, scrollBottom); | 		_list->visibleAreaUpdated(scrollTop, scrollBottom); | ||||||
| 		if (_history->loadedAtBottom() && (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0))) { | 		if (_history->loadedAtBottom() && (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0))) { | ||||||
| 			auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr); | 			auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr); | ||||||
|  | @ -2647,6 +2653,7 @@ void HistoryWidget::visibleAreaUpdated() { | ||||||
| 				historyWasRead(ReadServerHistoryChecks::OnlyIfUnread); | 				historyWasRead(ReadServerHistoryChecks::OnlyIfUnread); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		controller()->floatPlayerAreaUpdated().notify(true); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -180,6 +180,7 @@ public: | ||||||
| 	void dragLeaveEvent(QDragLeaveEvent *e) override; | 	void dragLeaveEvent(QDragLeaveEvent *e) override; | ||||||
|     void dropEvent(QDropEvent *e) override; |     void dropEvent(QDropEvent *e) override; | ||||||
| 
 | 
 | ||||||
|  | 	bool isItemCompletelyHidden(HistoryItem *item) const; | ||||||
| 	void updateTopBarSelection(); | 	void updateTopBarSelection(); | ||||||
| 
 | 
 | ||||||
| 	bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms); | 	bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms); | ||||||
|  |  | ||||||
|  | @ -152,6 +152,9 @@ MainWidget::MainWidget(QWidget *parent, gsl::not_null<Window::Controller*> contr | ||||||
| 	subscribe(_controller->dialogsWidthRatio(), [this](float64) { | 	subscribe(_controller->dialogsWidthRatio(), [this](float64) { | ||||||
| 		updateControlsGeometry(); | 		updateControlsGeometry(); | ||||||
| 	}); | 	}); | ||||||
|  | 	subscribe(_controller->floatPlayerAreaUpdated(), [this] { | ||||||
|  | 		checkFloatPlayerVisibility(); | ||||||
|  | 	}); | ||||||
| 
 | 
 | ||||||
| 	QCoreApplication::instance()->installEventFilter(this); | 	QCoreApplication::instance()->installEventFilter(this); | ||||||
| 
 | 
 | ||||||
|  | @ -234,7 +237,7 @@ void MainWidget::checkCurrentFloatPlayer() { | ||||||
| 	auto state = Media::Player::instance()->current(AudioMsgId::Type::Voice); | 	auto state = Media::Player::instance()->current(AudioMsgId::Type::Voice); | ||||||
| 	auto fullId = state.contextId(); | 	auto fullId = state.contextId(); | ||||||
| 	auto last = currentFloatPlayer(); | 	auto last = currentFloatPlayer(); | ||||||
| 	if (!last || last->widget->itemId() != fullId) { | 	if (!last || last->widget->detached() || last->widget->item()->fullId() != fullId) { | ||||||
| 		if (last) { | 		if (last) { | ||||||
| 			last->widget->detach(); | 			last->widget->detach(); | ||||||
| 		} | 		} | ||||||
|  | @ -243,9 +246,10 @@ void MainWidget::checkCurrentFloatPlayer() { | ||||||
| 				if (auto document = media->getDocument()) { | 				if (auto document = media->getDocument()) { | ||||||
| 					if (document->isRoundVideo()) { | 					if (document->isRoundVideo()) { | ||||||
| 						_playerFloats.push_back(std::make_unique<Float>(this, item, [this](Float *instance, bool visible) { | 						_playerFloats.push_back(std::make_unique<Float>(this, item, [this](Float *instance, bool visible) { | ||||||
| 							toggleFloatPlayer(instance, visible); | 							instance->hiddenByWidget = !visible; | ||||||
|  | 							toggleFloatPlayer(instance); | ||||||
| 						})); | 						})); | ||||||
| 						toggleFloatPlayer(currentFloatPlayer(), true); | 						checkFloatPlayerVisibility(); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -253,8 +257,10 @@ void MainWidget::checkCurrentFloatPlayer() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MainWidget::toggleFloatPlayer(Float *instance, bool visible) { | void MainWidget::toggleFloatPlayer(Float *instance) { | ||||||
|  | 	auto visible = !instance->hiddenByHistory && !instance->hiddenByWidget && !instance->widget->detached(); | ||||||
| 	if (instance->visible != visible) { | 	if (instance->visible != visible) { | ||||||
|  | 		instance->widget->resetMouseState(); | ||||||
| 		instance->visible = visible; | 		instance->visible = visible; | ||||||
| 		instance->visibleAnimation.start([this, instance] { | 		instance->visibleAnimation.start([this, instance] { | ||||||
| 			updateFloatPlayerPosition(instance); | 			updateFloatPlayerPosition(instance); | ||||||
|  | @ -263,6 +269,20 @@ void MainWidget::toggleFloatPlayer(Float *instance, bool visible) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void MainWidget::checkFloatPlayerVisibility() { | ||||||
|  | 	auto instance = currentFloatPlayer(); | ||||||
|  | 	if (!instance) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (_history->isHidden() || _history->isItemCompletelyHidden(instance->widget->item())) { | ||||||
|  | 		instance->hiddenByHistory = false; | ||||||
|  | 	} else { | ||||||
|  | 		instance->hiddenByHistory = true; | ||||||
|  | 	} | ||||||
|  | 	toggleFloatPlayer(instance); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void MainWidget::updateFloatPlayerPosition(Float *instance) { | void MainWidget::updateFloatPlayerPosition(Float *instance) { | ||||||
| 	auto visible = instance->visibleAnimation.current(instance->visible ? 1. : 0.); | 	auto visible = instance->visibleAnimation.current(instance->visible ? 1. : 0.); | ||||||
| 	if (visible == 0. && !instance->visible) { | 	if (visible == 0. && !instance->visible) { | ||||||
|  | @ -755,6 +775,7 @@ void MainWidget::noHider(HistoryHider *destroyed) { | ||||||
| 				} else { | 				} else { | ||||||
| 					_history->showAnimated(Window::SlideDirection::FromRight, animationParams); | 					_history->showAnimated(Window::SlideDirection::FromRight, animationParams); | ||||||
| 				} | 				} | ||||||
|  | 				checkFloatPlayerVisibility(); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			if (_forwardConfirm) { | 			if (_forwardConfirm) { | ||||||
|  | @ -796,6 +817,7 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) { | ||||||
| 		updateControlsGeometry(); | 		updateControlsGeometry(); | ||||||
| 		_dialogs->activate(); | 		_dialogs->activate(); | ||||||
| 	} | 	} | ||||||
|  | 	checkFloatPlayerVisibility(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MainWidget::forwardLayer(int forwardSelected) { | void MainWidget::forwardLayer(int forwardSelected) { | ||||||
|  | @ -2498,6 +2520,8 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show | ||||||
| 		} | 		} | ||||||
| 		_dialogs->update(); | 		_dialogs->update(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	checkFloatPlayerVisibility(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PeerData *MainWidget::ui_getPeerForMouseAction() { | PeerData *MainWidget::ui_getPeerForMouseAction() { | ||||||
|  | @ -2625,6 +2649,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool | ||||||
| 	_history->hide(); | 	_history->hide(); | ||||||
| 	if (Adaptive::OneColumn()) _dialogs->hide(); | 	if (Adaptive::OneColumn()) _dialogs->hide(); | ||||||
| 
 | 
 | ||||||
|  | 	checkFloatPlayerVisibility(); | ||||||
| 	orderWidgets(); | 	orderWidgets(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2784,6 +2809,7 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool | ||||||
| 		_wideSection->showFast(); | 		_wideSection->showFast(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	checkFloatPlayerVisibility(); | ||||||
| 	orderWidgets(); | 	orderWidgets(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -3128,6 +3154,9 @@ void MainWidget::hideAll() { | ||||||
| 		_player->hide(); | 		_player->hide(); | ||||||
| 		_playerHeight = 0; | 		_playerHeight = 0; | ||||||
| 	} | 	} | ||||||
|  | 	for (auto &instance : _playerFloats) { | ||||||
|  | 		instance->widget->hide(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MainWidget::showAll() { | void MainWidget::showAll() { | ||||||
|  | @ -3199,6 +3228,12 @@ void MainWidget::showAll() { | ||||||
| 		_playerHeight = _player->contentHeight(); | 		_playerHeight = _player->contentHeight(); | ||||||
| 	} | 	} | ||||||
| 	updateControlsGeometry(); | 	updateControlsGeometry(); | ||||||
|  | 	if (auto instance = currentFloatPlayer()) { | ||||||
|  | 		checkFloatPlayerVisibility(); | ||||||
|  | 		if (instance->visible) { | ||||||
|  | 			instance->widget->show(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	App::wnd()->checkHistoryActivation(); | 	App::wnd()->checkHistoryActivation(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -466,6 +466,8 @@ private: | ||||||
| 		template <typename ToggleCallback> | 		template <typename ToggleCallback> | ||||||
| 		Float(QWidget *parent, HistoryItem *item, ToggleCallback callback); | 		Float(QWidget *parent, HistoryItem *item, ToggleCallback callback); | ||||||
| 
 | 
 | ||||||
|  | 		bool hiddenByWidget = false; | ||||||
|  | 		bool hiddenByHistory = false; | ||||||
| 		bool visible = false; | 		bool visible = false; | ||||||
| 		Animation visibleAnimation; | 		Animation visibleAnimation; | ||||||
| 		Window::Corner corner = Window::Corner::TopRight; | 		Window::Corner corner = Window::Corner::TopRight; | ||||||
|  | @ -574,7 +576,8 @@ private: | ||||||
| 
 | 
 | ||||||
| 	void clearCachedBackground(); | 	void clearCachedBackground(); | ||||||
| 	void checkCurrentFloatPlayer(); | 	void checkCurrentFloatPlayer(); | ||||||
| 	void toggleFloatPlayer(Float *instance, bool visible); | 	void toggleFloatPlayer(Float *instance); | ||||||
|  | 	void checkFloatPlayerVisibility(); | ||||||
| 	void updateFloatPlayerPosition(Float *instance); | 	void updateFloatPlayerPosition(Float *instance); | ||||||
| 	void removeFloatPlayer(Float *instance); | 	void removeFloatPlayer(Float *instance); | ||||||
| 	Float *currentFloatPlayer() const { | 	Float *currentFloatPlayer() const { | ||||||
|  |  | ||||||
|  | @ -887,7 +887,6 @@ void Mixer::seek(AudioMsgId::Type type, int64 position) { | ||||||
| 		resetFadeStartPosition(type, position - current->bufferedPosition); | 		resetFadeStartPosition(type, position - current->bufferedPosition); | ||||||
| 	} else { | 	} else { | ||||||
| 		setStoppedState(current); | 		setStoppedState(current); | ||||||
| 		if (streamCreated) alSourceStop(current->stream.source); |  | ||||||
| 	} | 	} | ||||||
| 	switch (current->state.state) { | 	switch (current->state.state) { | ||||||
| 	case State::Pausing: | 	case State::Pausing: | ||||||
|  | @ -1009,6 +1008,10 @@ TrackState Mixer::currentState(AudioMsgId::Type type) { | ||||||
| void Mixer::setStoppedState(Track *current, State state) { | void Mixer::setStoppedState(Track *current, State state) { | ||||||
| 	current->state.state = state; | 	current->state.state = state; | ||||||
| 	current->state.position = 0; | 	current->state.position = 0; | ||||||
|  | 	if (current->isStreamCreated()) { | ||||||
|  | 		alSourceStop(current->stream.source); | ||||||
|  | 		alSourcef(current->stream.source, AL_GAIN, 1); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Mixer::clearStoppedAtStart(const AudioMsgId &audio) { | void Mixer::clearStoppedAtStart(const AudioMsgId &audio) { | ||||||
|  | @ -1209,18 +1212,14 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF | ||||||
| 		if (fading || playing) { | 		if (fading || playing) { | ||||||
| 			fading = false; | 			fading = false; | ||||||
| 			playing = false; | 			playing = false; | ||||||
| 			if (track->isStreamCreated()) { |  | ||||||
| 				alSourceStop(track->stream.source); |  | ||||||
| 				alSourcef(track->stream.source, AL_GAIN, 1); |  | ||||||
| 				if (errorHappened()) return EmitError; |  | ||||||
| 			} |  | ||||||
| 			if (track->state.state == State::Pausing) { | 			if (track->state.state == State::Pausing) { | ||||||
| 				track->state.state = State::PausedAtEnd; | 				setStoppedState(track, State::PausedAtEnd); | ||||||
| 			} else if (track->state.state == State::Stopping) { | 			} else if (track->state.state == State::Stopping) { | ||||||
| 				setStoppedState(track, State::Stopped); | 				setStoppedState(track, State::Stopped); | ||||||
| 			} else { | 			} else { | ||||||
| 				setStoppedState(track, State::StoppedAtEnd); | 				setStoppedState(track, State::StoppedAtEnd); | ||||||
| 			} | 			} | ||||||
|  | 			if (errorHappened()) return EmitError; | ||||||
| 			emitSignals |= EmitStopped; | 			emitSignals |= EmitStopped; | ||||||
| 		} | 		} | ||||||
| 	} else if (fading && state == AL_PLAYING) { | 	} else if (fading && state == AL_PLAYING) { | ||||||
|  | @ -1232,9 +1231,6 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF | ||||||
| 
 | 
 | ||||||
| 			switch (track->state.state) { | 			switch (track->state.state) { | ||||||
| 			case State::Stopping: { | 			case State::Stopping: { | ||||||
| 				alSourceStop(track->stream.source); |  | ||||||
| 				if (errorHappened()) return EmitError; |  | ||||||
| 
 |  | ||||||
| 				setStoppedState(track); | 				setStoppedState(track); | ||||||
| 				state = AL_STOPPED; | 				state = AL_STOPPED; | ||||||
| 			} break; | 			} break; | ||||||
|  | @ -1284,8 +1280,7 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Fader::setStoppedState(Mixer::Track *track, State state) { | void Fader::setStoppedState(Mixer::Track *track, State state) { | ||||||
| 	track->state.state = state; | 	mixer()->setStoppedState(track, state); | ||||||
| 	track->state.position = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Fader::onSuppressSong() { | void Fader::onSuppressSong() { | ||||||
|  |  | ||||||
|  | @ -231,6 +231,7 @@ private: | ||||||
| 
 | 
 | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	// Thread: Any. Must be locked: AudioMutex.
 | ||||||
| 	void setStoppedState(Track *current, State state = State::Stopped); | 	void setStoppedState(Track *current, State state = State::Stopped); | ||||||
| 
 | 
 | ||||||
| 	Track *trackForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type)
 | 	Track *trackForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type)
 | ||||||
|  |  | ||||||
|  | @ -125,8 +125,7 @@ AudioMsgId Loaders::clear(AudioMsgId::Type type) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Loaders::setStoppedState(Mixer::Track *track, State state) { | void Loaders::setStoppedState(Mixer::Track *track, State state) { | ||||||
| 	track->state.state = state; | 	mixer()->setStoppedState(track, state); | ||||||
| 	track->state.position = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Loaders::emitError(AudioMsgId::Type type) { | void Loaders::emitError(AudioMsgId::Type type) { | ||||||
|  |  | ||||||
|  | @ -31,8 +31,8 @@ class Float : public TWidget, private base::Subscriber { | ||||||
| public: | public: | ||||||
| 	Float(QWidget *parent, HistoryItem *item, base::lambda<void(bool visible)> toggleCallback); | 	Float(QWidget *parent, HistoryItem *item, base::lambda<void(bool visible)> toggleCallback); | ||||||
| 
 | 
 | ||||||
| 	FullMsgId itemId() const { | 	HistoryItem *item() const { | ||||||
| 		return _item ? _item->fullId() : FullMsgId(); | 		return _item; | ||||||
| 	} | 	} | ||||||
| 	void setOpacity(float64 opacity) { | 	void setOpacity(float64 opacity) { | ||||||
| 		_opacity = opacity; | 		_opacity = opacity; | ||||||
|  |  | ||||||
|  | @ -65,6 +65,9 @@ public: | ||||||
| 		return _gifPauseLevelChanged; | 		return _gifPauseLevelChanged; | ||||||
| 	} | 	} | ||||||
| 	bool isGifPausedAtLeastFor(GifPauseReason reason) const; | 	bool isGifPausedAtLeastFor(GifPauseReason reason) const; | ||||||
|  | 	base::Observable<void> &floatPlayerAreaUpdated() { | ||||||
|  | 		return _floatPlayerAreaUpdated; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	struct ColumnLayout { | 	struct ColumnLayout { | ||||||
| 		int bodyWidth; | 		int bodyWidth; | ||||||
|  | @ -104,6 +107,7 @@ private: | ||||||
| 
 | 
 | ||||||
| 	GifPauseReasons _gifPauseReasons = { 0 }; | 	GifPauseReasons _gifPauseReasons = { 0 }; | ||||||
| 	base::Observable<void> _gifPauseLevelChanged; | 	base::Observable<void> _gifPauseLevelChanged; | ||||||
|  | 	base::Observable<void> _floatPlayerAreaUpdated; | ||||||
| 
 | 
 | ||||||
| 	base::Variable<float64> _dialogsWidthRatio = { kDefaultDialogsWidthRatio }; | 	base::Variable<float64> _dialogsWidthRatio = { kDefaultDialogsWidthRatio }; | ||||||
| 	base::Variable<bool> _dialogsListFocused = { false }; | 	base::Variable<bool> _dialogsListFocused = { false }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue