mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Better track paused story state.
This commit is contained in:
parent
b8cf00a0b2
commit
8b22f9dcac
14 changed files with 149 additions and 61 deletions
|
@ -588,7 +588,7 @@ void Stories::loadAround(FullStoryId id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stories::markAsRead(FullStoryId id) {
|
void Stories::markAsRead(FullStoryId id, bool viewed) {
|
||||||
const auto i = ranges::find(_all, id.peer, [](const StoriesList &list) {
|
const auto i = ranges::find(_all, id.peer, [](const StoriesList &list) {
|
||||||
return list.user->id;
|
return list.user->id;
|
||||||
});
|
});
|
||||||
|
|
|
@ -115,7 +115,7 @@ public:
|
||||||
void resolve(FullStoryId id, Fn<void()> done);
|
void resolve(FullStoryId id, Fn<void()> done);
|
||||||
|
|
||||||
[[nodiscard]] bool isQuitPrevent();
|
[[nodiscard]] bool isQuitPrevent();
|
||||||
void markAsRead(FullStoryId id);
|
void markAsRead(FullStoryId id, bool viewed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] StoriesList parse(const MTPUserStories &stories);
|
[[nodiscard]] StoriesList parse(const MTPUserStories &stories);
|
||||||
|
|
|
@ -1135,6 +1135,10 @@ rpl::producer<bool> ComposeControls::focusedValue() const {
|
||||||
| rpl::then(_focusChanges.events());
|
| rpl::then(_focusChanges.events());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> ComposeControls::tabbedPanelShownValue() const {
|
||||||
|
return _tabbedPanel ? _tabbedPanel->shownValue() : rpl::single(false);
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<> ComposeControls::cancelRequests() const {
|
rpl::producer<> ComposeControls::cancelRequests() const {
|
||||||
return _cancelRequests.events();
|
return _cancelRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -2013,9 +2017,12 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
updateControlsGeometry(_wrap->size());
|
updateControlsGeometry(_wrap->size());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const auto hadFocus = Ui::InFocusChain(_field);
|
||||||
if (!draft) {
|
if (!draft) {
|
||||||
clearFieldText(0, fieldHistoryAction);
|
clearFieldText(0, fieldHistoryAction);
|
||||||
_field->setFocus();
|
if (hadFocus) {
|
||||||
|
_field->setFocus();
|
||||||
|
}
|
||||||
_header->editMessage({});
|
_header->editMessage({});
|
||||||
_header->replyToMessage({});
|
_header->replyToMessage({});
|
||||||
_canReplaceMedia = false;
|
_canReplaceMedia = false;
|
||||||
|
@ -2025,7 +2032,9 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
|
|
||||||
_textUpdateEvents = 0;
|
_textUpdateEvents = 0;
|
||||||
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
|
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
|
||||||
_field->setFocus();
|
if (hadFocus) {
|
||||||
|
_field->setFocus();
|
||||||
|
}
|
||||||
draft->cursor.applyTo(_field);
|
draft->cursor.applyTo(_field);
|
||||||
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
||||||
if (_preview) {
|
if (_preview) {
|
||||||
|
@ -2253,11 +2262,13 @@ void ComposeControls::initVoiceRecordBar() {
|
||||||
_voiceRecordBar->recordingStateChanges(
|
_voiceRecordBar->recordingStateChanges(
|
||||||
) | rpl::start_with_next([=](bool active) {
|
) | rpl::start_with_next([=](bool active) {
|
||||||
if (active) {
|
if (active) {
|
||||||
|
_recording = true;
|
||||||
changeFocusedControl();
|
changeFocusedControl();
|
||||||
}
|
}
|
||||||
_field->setVisible(!active);
|
_field->setVisible(!active);
|
||||||
if (!active) {
|
if (!active) {
|
||||||
changeFocusedControl();
|
changeFocusedControl();
|
||||||
|
_recording = false;
|
||||||
}
|
}
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
|
|
||||||
|
@ -2938,6 +2949,10 @@ bool ComposeControls::isRecording() const {
|
||||||
return _voiceRecordBar->isRecording();
|
return _voiceRecordBar->isRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> ComposeControls::recordingValue() const {
|
||||||
|
return _recording.value();
|
||||||
|
}
|
||||||
|
|
||||||
bool ComposeControls::preventsClose(Fn<void()> &&continueCallback) const {
|
bool ComposeControls::preventsClose(Fn<void()> &&continueCallback) const {
|
||||||
if (_voiceRecordBar->isActive()) {
|
if (_voiceRecordBar->isActive()) {
|
||||||
_voiceRecordBar->showDiscardBox(std::move(continueCallback));
|
_voiceRecordBar->showDiscardBox(std::move(continueCallback));
|
||||||
|
|
|
@ -146,6 +146,7 @@ public:
|
||||||
|
|
||||||
bool focus();
|
bool focus();
|
||||||
[[nodiscard]] rpl::producer<bool> focusedValue() const;
|
[[nodiscard]] rpl::producer<bool> focusedValue() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> tabbedPanelShownValue() const;
|
||||||
[[nodiscard]] rpl::producer<> cancelRequests() const;
|
[[nodiscard]] rpl::producer<> cancelRequests() const;
|
||||||
[[nodiscard]] rpl::producer<Api::SendOptions> sendRequests() const;
|
[[nodiscard]] rpl::producer<Api::SendOptions> sendRequests() const;
|
||||||
[[nodiscard]] rpl::producer<VoiceToSend> sendVoiceRequests() const;
|
[[nodiscard]] rpl::producer<VoiceToSend> sendVoiceRequests() const;
|
||||||
|
@ -213,6 +214,7 @@ public:
|
||||||
[[nodiscard]] rpl::producer<bool> lockShowStarts() const;
|
[[nodiscard]] rpl::producer<bool> lockShowStarts() const;
|
||||||
[[nodiscard]] bool isLockPresent() const;
|
[[nodiscard]] bool isLockPresent() const;
|
||||||
[[nodiscard]] bool isRecording() const;
|
[[nodiscard]] bool isRecording() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> recordingValue() const;
|
||||||
|
|
||||||
void applyCloudDraft();
|
void applyCloudDraft();
|
||||||
void applyDraft(
|
void applyDraft(
|
||||||
|
@ -379,6 +381,7 @@ private:
|
||||||
rpl::event_stream<std::optional<bool>> _attachRequests;
|
rpl::event_stream<std::optional<bool>> _attachRequests;
|
||||||
rpl::event_stream<ReplyNextRequest> _replyNextRequests;
|
rpl::event_stream<ReplyNextRequest> _replyNextRequests;
|
||||||
rpl::event_stream<> _focusRequests;
|
rpl::event_stream<> _focusRequests;
|
||||||
|
rpl::variable<bool> _recording;
|
||||||
|
|
||||||
TextUpdateEvents _textUpdateEvents = TextUpdateEvents()
|
TextUpdateEvents _textUpdateEvents = TextUpdateEvents()
|
||||||
| TextUpdateEvent::SaveDraft
|
| TextUpdateEvent::SaveDraft
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "base/power_save_blocker.h"
|
#include "base/power_save_blocker.h"
|
||||||
|
#include "base/qt_signal_producer.h"
|
||||||
#include "chat_helpers/compose/compose_show.h"
|
#include "chat_helpers/compose/compose_show.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
|
@ -29,6 +30,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_boxes.h" // UserpicButton
|
#include "styles/style_boxes.h" // UserpicButton
|
||||||
|
|
||||||
|
#include <QtGui/QWindow>
|
||||||
|
|
||||||
namespace Media::Stories {
|
namespace Media::Stories {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -123,27 +126,52 @@ Controller::Controller(not_null<Delegate*> delegate)
|
||||||
, _replyArea(std::make_unique<ReplyArea>(this)) {
|
, _replyArea(std::make_unique<ReplyArea>(this)) {
|
||||||
initLayout();
|
initLayout();
|
||||||
|
|
||||||
_replyArea->focusedValue(
|
_replyArea->activeValue(
|
||||||
) | rpl::start_with_next([=](bool focused) {
|
) | rpl::start_with_next([=](bool active) {
|
||||||
if (focused) {
|
if (active) {
|
||||||
_captionFullView = nullptr;
|
_captionFullView = nullptr;
|
||||||
}
|
}
|
||||||
_contentFaded = focused;
|
_replyActive = active;
|
||||||
_contentFadeAnimation.start(
|
updateContentFaded();
|
||||||
[=] { _delegate->storiesRepaint(); },
|
|
||||||
focused ? 0. : 1.,
|
|
||||||
focused ? 1. : 0.,
|
|
||||||
st::fadeWrapDuration);
|
|
||||||
if (_started) {
|
|
||||||
togglePaused(focused);
|
|
||||||
}
|
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
_replyArea->focusedValue(
|
||||||
|
) | rpl::start_with_next([=](bool focused) {
|
||||||
|
_replyFocused = focused;
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
_delegate->storiesLayerShown(
|
||||||
|
) | rpl::start_with_next([=](bool shown) {
|
||||||
|
_layerShown = shown;
|
||||||
|
updatePlayingAllowed();
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
const auto window = _wrap->window()->windowHandle();
|
||||||
|
Assert(window != nullptr);
|
||||||
|
base::qt_signal_producer(
|
||||||
|
window,
|
||||||
|
&QWindow::activeChanged
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
_windowActive = window->isActive();
|
||||||
|
updatePlayingAllowed();
|
||||||
|
}, _lifetime);
|
||||||
|
_windowActive = window->isActive();
|
||||||
|
|
||||||
_contentFadeAnimation.stop();
|
_contentFadeAnimation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::~Controller() = default;
|
Controller::~Controller() = default;
|
||||||
|
|
||||||
|
void Controller::updateContentFaded() {
|
||||||
|
_contentFaded = _replyActive;
|
||||||
|
_contentFadeAnimation.start(
|
||||||
|
[=] { _delegate->storiesRepaint(); },
|
||||||
|
_contentFaded ? 0. : 1.,
|
||||||
|
_contentFaded ? 1. : 0.,
|
||||||
|
st::fadeWrapDuration);
|
||||||
|
updatePlayingAllowed();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::initLayout() {
|
void Controller::initLayout() {
|
||||||
const auto headerHeight = st::storiesHeaderMargin.top()
|
const auto headerHeight = st::storiesHeaderMargin.top()
|
||||||
+ st::storiesHeaderPhoto.photoSize
|
+ st::storiesHeaderPhoto.photoSize
|
||||||
|
@ -373,6 +401,7 @@ void Controller::show(
|
||||||
}
|
}
|
||||||
const auto story = *maybeStory;
|
const auto story = *maybeStory;
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
|
_paused = false;
|
||||||
_started = false;
|
_started = false;
|
||||||
if (story->photo()) {
|
if (story->photo()) {
|
||||||
_photoPlayback = std::make_unique<PhotoPlayback>(this);
|
_photoPlayback = std::make_unique<PhotoPlayback>(this);
|
||||||
|
@ -421,10 +450,33 @@ void Controller::show(
|
||||||
}
|
}
|
||||||
stories.loadAround(storyId);
|
stories.loadAround(storyId);
|
||||||
|
|
||||||
list.user->updateFull();
|
if (_replyFocused) {
|
||||||
|
unfocusReply();
|
||||||
|
}
|
||||||
|
updatePlayingAllowed();
|
||||||
|
|
||||||
if (_contentFaded) {
|
list.user->updateFull();
|
||||||
togglePaused(true);
|
}
|
||||||
|
|
||||||
|
void Controller::updatePlayingAllowed() {
|
||||||
|
if (!_shown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPlayingAllowed(_started
|
||||||
|
&& _windowActive
|
||||||
|
&& !_paused
|
||||||
|
&& !_replyActive
|
||||||
|
&& !_layerShown);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::setPlayingAllowed(bool allowed) {
|
||||||
|
if (allowed) {
|
||||||
|
_captionFullView = nullptr;
|
||||||
|
}
|
||||||
|
if (_photoPlayback) {
|
||||||
|
_photoPlayback->togglePaused(!allowed);
|
||||||
|
} else {
|
||||||
|
_delegate->storiesTogglePaused(!allowed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,9 +504,7 @@ void Controller::ready() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_started = true;
|
_started = true;
|
||||||
if (!_contentFaded && _photoPlayback) {
|
updatePlayingAllowed();
|
||||||
_photoPlayback->togglePaused(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::updateVideoPlayback(const Player::TrackState &state) {
|
void Controller::updateVideoPlayback(const Player::TrackState &state) {
|
||||||
|
@ -493,7 +543,7 @@ void Controller::maybeMarkAsRead(const Player::TrackState &state) {
|
||||||
void Controller::markAsRead() {
|
void Controller::markAsRead() {
|
||||||
Expects(_list.has_value());
|
Expects(_list.has_value());
|
||||||
|
|
||||||
_list->user->owner().stories().markAsRead(_shown);
|
_list->user->owner().stories().markAsRead(_shown, _started);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::subjumpAvailable(int delta) const {
|
bool Controller::subjumpAvailable(int delta) const {
|
||||||
|
@ -551,21 +601,11 @@ void Controller::checkWaitingFor() {
|
||||||
Expects(_list.has_value());
|
Expects(_list.has_value());
|
||||||
|
|
||||||
auto &stories = _list->user->owner().stories();
|
auto &stories = _list->user->owner().stories();
|
||||||
const auto &all = stories.all();
|
|
||||||
const auto i = ranges::find_if(all, [&](const Data::StoriesList &data) {
|
|
||||||
return data.user->id == _waitingForId.peer;
|
|
||||||
});
|
|
||||||
if (i == end(all)) {
|
|
||||||
_waitingForId = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto j = ranges::find(i->ids, _waitingForId.story);
|
|
||||||
if (j == end(i->ids)) {
|
|
||||||
_waitingForId = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto maybe = stories.lookup(_waitingForId);
|
const auto maybe = stories.lookup(_waitingForId);
|
||||||
if (!maybe) {
|
if (!maybe) {
|
||||||
|
if (maybe.error() == Data::NoStory::Deleted) {
|
||||||
|
_waitingForId = {};
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_delegate->storiesJumpTo(
|
_delegate->storiesJumpTo(
|
||||||
|
@ -596,19 +636,13 @@ bool Controller::jumpFor(int delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::paused() const {
|
bool Controller::paused() const {
|
||||||
return _photoPlayback
|
return _paused;
|
||||||
? _photoPlayback->paused()
|
|
||||||
: _delegate->storiesPaused();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::togglePaused(bool paused) {
|
void Controller::togglePaused(bool paused) {
|
||||||
if (!paused) {
|
if (_paused != paused) {
|
||||||
_captionFullView = nullptr;
|
_paused = paused;
|
||||||
}
|
updatePlayingAllowed();
|
||||||
if (_photoPlayback) {
|
|
||||||
_photoPlayback->togglePaused(paused);
|
|
||||||
} else {
|
|
||||||
_delegate->storiesTogglePaused(paused);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,10 @@ private:
|
||||||
void maybeMarkAsRead(const Player::TrackState &state);
|
void maybeMarkAsRead(const Player::TrackState &state);
|
||||||
void markAsRead();
|
void markAsRead();
|
||||||
|
|
||||||
|
void updateContentFaded();
|
||||||
|
void updatePlayingAllowed();
|
||||||
|
void setPlayingAllowed(bool allowed);
|
||||||
|
|
||||||
void showSiblings(
|
void showSiblings(
|
||||||
const std::vector<Data::StoriesList> &lists,
|
const std::vector<Data::StoriesList> &lists,
|
||||||
int index);
|
int index);
|
||||||
|
@ -150,6 +154,12 @@ private:
|
||||||
Ui::Animations::Simple _contentFadeAnimation;
|
Ui::Animations::Simple _contentFadeAnimation;
|
||||||
bool _contentFaded = false;
|
bool _contentFaded = false;
|
||||||
|
|
||||||
|
bool _windowActive = false;
|
||||||
|
bool _replyFocused = false;
|
||||||
|
bool _replyActive = false;
|
||||||
|
bool _layerShown = false;
|
||||||
|
bool _paused = false;
|
||||||
|
|
||||||
FullStoryId _shown;
|
FullStoryId _shown;
|
||||||
TextWithEntities _captionText;
|
TextWithEntities _captionText;
|
||||||
std::optional<Data::StoriesList> _list;
|
std::optional<Data::StoriesList> _list;
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
FullStoryId id) = 0;
|
FullStoryId id) = 0;
|
||||||
virtual void storiesClose() = 0;
|
virtual void storiesClose() = 0;
|
||||||
[[nodiscard]] virtual bool storiesPaused() = 0;
|
[[nodiscard]] virtual bool storiesPaused() = 0;
|
||||||
|
[[nodiscard]] virtual rpl::producer<bool> storiesLayerShown() = 0;
|
||||||
[[nodiscard]] virtual float64 storiesSiblingOver(SiblingType type) = 0;
|
[[nodiscard]] virtual float64 storiesSiblingOver(SiblingType type) = 0;
|
||||||
virtual void storiesTogglePaused(bool paused) = 0;
|
virtual void storiesTogglePaused(bool paused) = 0;
|
||||||
virtual void storiesRepaint() = 0;
|
virtual void storiesRepaint() = 0;
|
||||||
|
|
|
@ -299,11 +299,11 @@ Api::SendAction ReplyArea::prepareSendAction(
|
||||||
|
|
||||||
void ReplyArea::chooseAttach(
|
void ReplyArea::chooseAttach(
|
||||||
std::optional<bool> overrideSendImagesAsPhotos) {
|
std::optional<bool> overrideSendImagesAsPhotos) {
|
||||||
|
_chooseAttachRequest = false;
|
||||||
if (!_data.user) {
|
if (!_data.user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto user = not_null(_data.user);
|
const auto user = not_null(_data.user);
|
||||||
_choosingAttach = false;
|
|
||||||
if (const auto error = Data::AnyFileRestrictionError(user)) {
|
if (const auto error = Data::AnyFileRestrictionError(user)) {
|
||||||
_controller->uiShow()->showToast(*error);
|
_controller->uiShow()->showToast(*error);
|
||||||
return;
|
return;
|
||||||
|
@ -312,15 +312,18 @@ void ReplyArea::chooseAttach(
|
||||||
const auto filter = (overrideSendImagesAsPhotos == true)
|
const auto filter = (overrideSendImagesAsPhotos == true)
|
||||||
? FileDialog::ImagesOrAllFilter()
|
? FileDialog::ImagesOrAllFilter()
|
||||||
: FileDialog::AllOrImagesFilter();
|
: FileDialog::AllOrImagesFilter();
|
||||||
|
const auto weak = make_weak(&_shownUserGuard);
|
||||||
const auto callback = [=](FileDialog::OpenResult &&result) {
|
const auto callback = [=](FileDialog::OpenResult &&result) {
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
const auto guard = gsl::finally([&] {
|
||||||
|
_choosingAttach = false;
|
||||||
|
});
|
||||||
|
if (!weak
|
||||||
|
|| (result.paths.isEmpty() && result.remoteContent.isEmpty())) {
|
||||||
return;
|
return;
|
||||||
}
|
} else if (!result.remoteContent.isEmpty()) {
|
||||||
|
|
||||||
if (!result.remoteContent.isEmpty()) {
|
|
||||||
auto read = Images::Read({
|
auto read = Images::Read({
|
||||||
.content = result.remoteContent,
|
.content = result.remoteContent,
|
||||||
});
|
});
|
||||||
if (!read.image.isNull() && !read.animated) {
|
if (!read.image.isNull() && !read.animated) {
|
||||||
confirmSendingFiles(
|
confirmSendingFiles(
|
||||||
std::move(read.image),
|
std::move(read.image),
|
||||||
|
@ -339,12 +342,14 @@ void ReplyArea::chooseAttach(
|
||||||
confirmSendingFiles(std::move(list));
|
confirmSendingFiles(std::move(list));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_choosingAttach = true;
|
||||||
FileDialog::GetOpenPaths(
|
FileDialog::GetOpenPaths(
|
||||||
_controller->wrap().get(),
|
_controller->wrap().get(),
|
||||||
tr::lng_choose_files(tr::now),
|
tr::lng_choose_files(tr::now),
|
||||||
filter,
|
filter,
|
||||||
crl::guard(&_shownUserGuard, callback),
|
crl::guard(this, callback),
|
||||||
nullptr);
|
crl::guard(this, [=] { _choosingAttach = false; }));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReplyArea::confirmSendingFiles(
|
bool ReplyArea::confirmSendingFiles(
|
||||||
|
@ -488,9 +493,9 @@ void ReplyArea::initActions() {
|
||||||
|
|
||||||
_controls->attachRequests(
|
_controls->attachRequests(
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
return !_choosingAttach;
|
return !_chooseAttachRequest;
|
||||||
}) | rpl::start_with_next([=](std::optional<bool> overrideCompress) {
|
}) | rpl::start_with_next([=](std::optional<bool> overrideCompress) {
|
||||||
_choosingAttach = true;
|
_chooseAttachRequest = true;
|
||||||
base::call_delayed(
|
base::call_delayed(
|
||||||
st::storiesAttach.ripple.hideDuration,
|
st::storiesAttach.ripple.hideDuration,
|
||||||
this,
|
this,
|
||||||
|
@ -569,6 +574,17 @@ rpl::producer<bool> ReplyArea::focusedValue() const {
|
||||||
return _controls->focusedValue();
|
return _controls->focusedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> ReplyArea::activeValue() const {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
return rpl::combine(
|
||||||
|
_controls->focusedValue(),
|
||||||
|
_controls->recordingValue(),
|
||||||
|
_controls->tabbedPanelShownValue(),
|
||||||
|
_choosingAttach.value(),
|
||||||
|
_1 || _2 || _3 || _4
|
||||||
|
) | rpl::distinct_until_changed();
|
||||||
|
}
|
||||||
|
|
||||||
void ReplyArea::showPremiumToast(not_null<DocumentData*> emoji) {
|
void ReplyArea::showPremiumToast(not_null<DocumentData*> emoji) {
|
||||||
// #TODO stories
|
// #TODO stories
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
void show(ReplyAreaData data);
|
void show(ReplyAreaData data);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<bool> focusedValue() const;
|
[[nodiscard]] rpl::producer<bool> focusedValue() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> activeValue() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using VoiceToSend = HistoryView::Controls::VoiceToSend;
|
using VoiceToSend = HistoryView::Controls::VoiceToSend;
|
||||||
|
@ -130,7 +131,8 @@ private:
|
||||||
|
|
||||||
ReplyAreaData _data;
|
ReplyAreaData _data;
|
||||||
base::has_weak_ptr _shownUserGuard;
|
base::has_weak_ptr _shownUserGuard;
|
||||||
bool _choosingAttach = false;
|
bool _chooseAttachRequest = false;
|
||||||
|
rpl::variable<bool> _choosingAttach;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
|
|
@ -599,6 +599,7 @@ storiesComposeControls: ComposeControls(defaultComposeControls) {
|
||||||
fadeLeft: icon {{ "fade_horizontal-flip_horizontal", storiesComposeBgOver }};
|
fadeLeft: icon {{ "fade_horizontal-flip_horizontal", storiesComposeBgOver }};
|
||||||
fadeRight: icon {{ "fade_horizontal", storiesComposeBgOver }};
|
fadeRight: icon {{ "fade_horizontal", storiesComposeBgOver }};
|
||||||
field: InputField(defaultTabbedSearchField) {
|
field: InputField(defaultTabbedSearchField) {
|
||||||
|
textFg: storiesComposeWhiteText;
|
||||||
placeholderFg: storiesComposeGrayText;
|
placeholderFg: storiesComposeGrayText;
|
||||||
placeholderFgActive: storiesComposeGrayText;
|
placeholderFgActive: storiesComposeGrayText;
|
||||||
placeholderFgError: storiesComposeGrayText;
|
placeholderFgError: storiesComposeGrayText;
|
||||||
|
|
|
@ -431,9 +431,10 @@ void OverlayWidget::RendererGL::paintTransformedStaticContent(
|
||||||
Ui::GL::kFormatRGBA,
|
Ui::GL::kFormatRGBA,
|
||||||
Ui::GL::kFormatRGBA,
|
Ui::GL::kFormatRGBA,
|
||||||
QSize(2, 2),
|
QSize(2, 2),
|
||||||
_rgbaSize,
|
_rgbaSize[index],
|
||||||
stride,
|
stride,
|
||||||
data);
|
data);
|
||||||
|
_rgbaSize[index] = QSize(2, 2);
|
||||||
} else {
|
} else {
|
||||||
const auto stride = image.bytesPerLine() / 4;
|
const auto stride = image.bytesPerLine() / 4;
|
||||||
const auto data = image.constBits();
|
const auto data = image.constBits();
|
||||||
|
@ -441,10 +442,10 @@ void OverlayWidget::RendererGL::paintTransformedStaticContent(
|
||||||
Ui::GL::kFormatRGBA,
|
Ui::GL::kFormatRGBA,
|
||||||
Ui::GL::kFormatRGBA,
|
Ui::GL::kFormatRGBA,
|
||||||
image.size(),
|
image.size(),
|
||||||
_rgbaSize,
|
_rgbaSize[index],
|
||||||
stride,
|
stride,
|
||||||
data);
|
data);
|
||||||
_rgbaSize = image.size();
|
_rgbaSize[index] = image.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ private:
|
||||||
std::optional<QOpenGLShaderProgram> _controlsProgram;
|
std::optional<QOpenGLShaderProgram> _controlsProgram;
|
||||||
std::optional<QOpenGLShaderProgram> _roundedCornersProgram;
|
std::optional<QOpenGLShaderProgram> _roundedCornersProgram;
|
||||||
Ui::GL::Textures<6> _textures; // image, sibling, right sibling, y, u, v
|
Ui::GL::Textures<6> _textures; // image, sibling, right sibling, y, u, v
|
||||||
QSize _rgbaSize;
|
QSize _rgbaSize[3];
|
||||||
QSize _lumaSize;
|
QSize _lumaSize;
|
||||||
QSize _chromaSize;
|
QSize _chromaSize;
|
||||||
qint64 _cacheKeys[3] = { 0 }; // image, sibling, right sibling
|
qint64 _cacheKeys[3] = { 0 }; // image, sibling, right sibling
|
||||||
|
|
|
@ -4053,6 +4053,10 @@ bool OverlayWidget::storiesPaused() {
|
||||||
&& _streamed->instance.player().paused();
|
&& _streamed->instance.player().paused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> OverlayWidget::storiesLayerShown() {
|
||||||
|
return _layerBg->layerShownValue();
|
||||||
|
}
|
||||||
|
|
||||||
void OverlayWidget::storiesTogglePaused(bool paused) {
|
void OverlayWidget::storiesTogglePaused(bool paused) {
|
||||||
if (!_streamed
|
if (!_streamed
|
||||||
|| _streamed->instance.player().failed()
|
|| _streamed->instance.player().failed()
|
||||||
|
|
|
@ -247,6 +247,7 @@ private:
|
||||||
FullStoryId id) override;
|
FullStoryId id) override;
|
||||||
void storiesClose() override;
|
void storiesClose() override;
|
||||||
bool storiesPaused() override;
|
bool storiesPaused() override;
|
||||||
|
rpl::producer<bool> storiesLayerShown() override;
|
||||||
void storiesTogglePaused(bool paused) override;
|
void storiesTogglePaused(bool paused) override;
|
||||||
float64 storiesSiblingOver(Stories::SiblingType type) override;
|
float64 storiesSiblingOver(Stories::SiblingType type) override;
|
||||||
void storiesRepaint() override;
|
void storiesRepaint() override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue