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