mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show root as pinned when not visible as message.
This commit is contained in:
parent
22dc7601f5
commit
7f928a92ea
5 changed files with 112 additions and 52 deletions
|
@ -29,6 +29,7 @@ struct RepliesList::Viewer {
|
||||||
MsgId around = 0;
|
MsgId around = 0;
|
||||||
int limitBefore = 0;
|
int limitBefore = 0;
|
||||||
int limitAfter = 0;
|
int limitAfter = 0;
|
||||||
|
base::has_weak_ptr guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
RepliesList::RepliesList(not_null<History*> history, MsgId rootId)
|
RepliesList::RepliesList(not_null<History*> history, MsgId rootId)
|
||||||
|
@ -80,12 +81,12 @@ rpl::producer<MessagesSlice> RepliesList::sourceFromServer(
|
||||||
) | rpl::filter([=](const MessageUpdate &update) {
|
) | rpl::filter([=](const MessageUpdate &update) {
|
||||||
return applyUpdate(viewer, update);
|
return applyUpdate(viewer, update);
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
crl::on_main(this, push);
|
crl::on_main(&viewer->guard, push);
|
||||||
}, lifetime);
|
}, lifetime);
|
||||||
|
|
||||||
_partLoaded.events(
|
_partLoaded.events(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
crl::on_main(this, push);
|
crl::on_main(&viewer->guard, push);
|
||||||
}, lifetime);
|
}, lifetime);
|
||||||
|
|
||||||
push();
|
push();
|
||||||
|
|
|
@ -606,6 +606,13 @@ void ListWidget::updateAroundPositionFromRows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Element *ListWidget::viewByPosition(Data::MessagePosition position) const {
|
||||||
|
const auto index = findNearestItem(position);
|
||||||
|
return (index < 0 || _items[index]->data()->position() != position)
|
||||||
|
? nullptr
|
||||||
|
: _items[index].get();
|
||||||
|
}
|
||||||
|
|
||||||
int ListWidget::findNearestItem(Data::MessagePosition position) const {
|
int ListWidget::findNearestItem(Data::MessagePosition position) const {
|
||||||
if (_items.empty()) {
|
if (_items.empty()) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -162,6 +162,7 @@ public:
|
||||||
void restoreState(not_null<ListMemento*> memento);
|
void restoreState(not_null<ListMemento*> memento);
|
||||||
std::optional<int> scrollTopForPosition(
|
std::optional<int> scrollTopForPosition(
|
||||||
Data::MessagePosition position) const;
|
Data::MessagePosition position) const;
|
||||||
|
Element *viewByPosition(Data::MessagePosition position) const;
|
||||||
std::optional<int> scrollTopForView(not_null<Element*> view) const;
|
std::optional<int> scrollTopForView(not_null<Element*> view) const;
|
||||||
enum class AnimatedScroll {
|
enum class AnimatedScroll {
|
||||||
Full,
|
Full,
|
||||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "chat_helpers/send_context_menu.h" // SendMenu::Type.
|
#include "chat_helpers/send_context_menu.h" // SendMenu::Type.
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
@ -129,18 +130,21 @@ RepliesWidget::RepliesWidget(
|
||||||
this,
|
this,
|
||||||
controller,
|
controller,
|
||||||
ComposeControls::Mode::Normal))
|
ComposeControls::Mode::Normal))
|
||||||
|
, _rootView(this, object_ptr<Ui::RpWidget>(this))
|
||||||
, _rootShadow(this)
|
, _rootShadow(this)
|
||||||
, _scrollDown(_scroll, st::historyToDown)
|
, _scrollDown(_scroll, st::historyToDown)
|
||||||
, _readRequestTimer([=] { sendReadTillRequest(); }) {
|
, _readRequestTimer([=] { sendReadTillRequest(); }) {
|
||||||
setupRoot();
|
setupRoot();
|
||||||
|
setupRootView();
|
||||||
|
|
||||||
_rootHeight = st::historyReplyHeight;
|
|
||||||
_topBar->setActiveChat(_history, TopBarWidget::Section::Replies);
|
_topBar->setActiveChat(_history, TopBarWidget::Section::Replies);
|
||||||
|
|
||||||
_topBar->move(0, 0);
|
_topBar->move(0, 0);
|
||||||
_topBar->resizeToWidth(width());
|
_topBar->resizeToWidth(width());
|
||||||
_topBar->show();
|
_topBar->show();
|
||||||
|
|
||||||
|
_rootView->move(0, _topBar->height());
|
||||||
|
|
||||||
_topBar->sendNowSelectionRequest(
|
_topBar->sendNowSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmSendNowSelected();
|
confirmSendNowSelected();
|
||||||
|
@ -167,7 +171,7 @@ RepliesWidget::RepliesWidget(
|
||||||
this,
|
this,
|
||||||
controller,
|
controller,
|
||||||
static_cast<ListDelegate*>(this)));
|
static_cast<ListDelegate*>(this)));
|
||||||
_scroll->move(0, _topBar->height() + _rootHeight);
|
_scroll->move(0, _topBar->height());
|
||||||
_scroll->show();
|
_scroll->show();
|
||||||
connect(_scroll, &Ui::ScrollArea::scrolled, [=] { onScroll(); });
|
connect(_scroll, &Ui::ScrollArea::scrolled, [=] { onScroll(); });
|
||||||
|
|
||||||
|
@ -195,6 +199,7 @@ RepliesWidget::RepliesWidget(
|
||||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||||
if (update.item == _root) {
|
if (update.item == _root) {
|
||||||
_root = nullptr;
|
_root = nullptr;
|
||||||
|
updatePinnedVisibility();
|
||||||
}
|
}
|
||||||
if (update.item == _commentsRoot) {
|
if (update.item == _commentsRoot) {
|
||||||
_commentsRoot = nullptr;
|
_commentsRoot = nullptr;
|
||||||
|
@ -245,12 +250,68 @@ void RepliesWidget::setupRoot() {
|
||||||
_areComments = computeAreComments();
|
_areComments = computeAreComments();
|
||||||
setupCommentsRoot();
|
setupCommentsRoot();
|
||||||
}
|
}
|
||||||
|
updatePinnedVisibility();
|
||||||
refreshRootView();
|
refreshRootView();
|
||||||
});
|
});
|
||||||
_history->session().api().requestMessageData(channel, _rootId, done);
|
_history->session().api().requestMessageData(channel, _rootId, done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RepliesWidget::setupRootView() {
|
||||||
|
const auto raw = _rootView->entity();
|
||||||
|
raw->resize(raw->width(), st::historyReplyHeight);
|
||||||
|
raw->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
auto p = Painter(_rootView->entity());
|
||||||
|
p.fillRect(clip, st::historyPinnedBg);
|
||||||
|
|
||||||
|
auto top = st::msgReplyPadding.top();
|
||||||
|
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||||
|
p.fillRect(rbar, st::msgInReplyBarColor);
|
||||||
|
|
||||||
|
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
|
if (!_rootTitle.isEmpty()) {
|
||||||
|
const auto media = _root ? _root->media() : nullptr;
|
||||||
|
if (media && media->hasReplyPreview()) {
|
||||||
|
if (const auto image = media->replyPreview()) {
|
||||||
|
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
||||||
|
p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
|
||||||
|
}
|
||||||
|
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||||
|
}
|
||||||
|
p.setPen(st::historyReplyNameFg);
|
||||||
|
p.setFont(st::msgServiceNameFont);
|
||||||
|
const auto poll = media ? media->poll() : nullptr;
|
||||||
|
const auto pinnedHeader = !poll
|
||||||
|
? tr::lng_pinned_message(tr::now)
|
||||||
|
: poll->quiz()
|
||||||
|
? tr::lng_pinned_quiz(tr::now)
|
||||||
|
: tr::lng_pinned_poll(tr::now);
|
||||||
|
_rootTitle.drawElided(p, left, top, width() - left - st::msgReplyPadding.right());
|
||||||
|
|
||||||
|
p.setPen(st::historyComposeAreaFg);
|
||||||
|
p.setTextPalette(st::historyComposeAreaPalette);
|
||||||
|
_rootMessage.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - st::msgReplyPadding.right());
|
||||||
|
p.restoreTextPalette();
|
||||||
|
} else {
|
||||||
|
p.setFont(st::msgDateFont);
|
||||||
|
p.setPen(st::historyComposeAreaFgService);
|
||||||
|
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - left - st::msgReplyPadding.right()));
|
||||||
|
}
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
_rootView->geometryValue(
|
||||||
|
) | rpl::start_with_next([=](QRect rect) {
|
||||||
|
_rootShadow->moveToLeft(
|
||||||
|
_rootShadow->x(),
|
||||||
|
rect.y() + rect.height());
|
||||||
|
}, _rootView->lifetime());
|
||||||
|
|
||||||
|
_rootShadow->showOn(_rootView->shownValue());
|
||||||
|
|
||||||
|
_rootView->hide(anim::type::instant);
|
||||||
|
}
|
||||||
|
|
||||||
void RepliesWidget::setupCommentsRoot() {
|
void RepliesWidget::setupCommentsRoot() {
|
||||||
Expects(_root != nullptr);
|
Expects(_root != nullptr);
|
||||||
|
|
||||||
|
@ -1105,7 +1166,7 @@ void RepliesWidget::updateAdaptiveLayout() {
|
||||||
_topBar->height());
|
_topBar->height());
|
||||||
_rootShadow->moveToLeft(
|
_rootShadow->moveToLeft(
|
||||||
Adaptive::OneColumn() ? 0 : st::lineWidth,
|
Adaptive::OneColumn() ? 0 : st::lineWidth,
|
||||||
_topBar->height() + _rootHeight);
|
_rootShadow->y());
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<History*> RepliesWidget::history() const {
|
not_null<History*> RepliesWidget::history() const {
|
||||||
|
@ -1210,6 +1271,12 @@ void RepliesWidget::saveState(not_null<RepliesMemento*> memento) {
|
||||||
void RepliesWidget::restoreState(not_null<RepliesMemento*> memento) {
|
void RepliesWidget::restoreState(not_null<RepliesMemento*> memento) {
|
||||||
const auto setReplies = [&](std::shared_ptr<Data::RepliesList> replies) {
|
const auto setReplies = [&](std::shared_ptr<Data::RepliesList> replies) {
|
||||||
_replies = std::move(replies);
|
_replies = std::move(replies);
|
||||||
|
_replies->fullCount(
|
||||||
|
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||||
|
_loaded = true;
|
||||||
|
updatePinnedVisibility();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
_topBar->setCustomTitle(tr::lng_manage_discussion_group(tr::now));
|
_topBar->setCustomTitle(tr::lng_manage_discussion_group(tr::now));
|
||||||
};
|
};
|
||||||
if (auto replies = memento->getReplies()) {
|
if (auto replies = memento->getReplies()) {
|
||||||
|
@ -1238,10 +1305,11 @@ void RepliesWidget::updateControlsGeometry() {
|
||||||
_topBar->resizeToWidth(contentWidth);
|
_topBar->resizeToWidth(contentWidth);
|
||||||
_topBarShadow->resize(contentWidth, st::lineWidth);
|
_topBarShadow->resize(contentWidth, st::lineWidth);
|
||||||
_rootShadow->resize(contentWidth, st::lineWidth);
|
_rootShadow->resize(contentWidth, st::lineWidth);
|
||||||
|
_rootView->resizeToWidth(contentWidth);
|
||||||
|
|
||||||
const auto bottom = height();
|
const auto bottom = height();
|
||||||
const auto controlsHeight = _composeControls->heightCurrent();
|
const auto controlsHeight = _composeControls->heightCurrent();
|
||||||
const auto scrollHeight = bottom - _topBar->height() - _rootHeight - controlsHeight;
|
const auto scrollHeight = bottom - _topBar->height() - controlsHeight;
|
||||||
const auto scrollSize = QSize(contentWidth, scrollHeight);
|
const auto scrollSize = QSize(contentWidth, scrollHeight);
|
||||||
if (_scroll->size() != scrollSize) {
|
if (_scroll->size() != scrollSize) {
|
||||||
_skipScrollEvent = true;
|
_skipScrollEvent = true;
|
||||||
|
@ -1268,52 +1336,10 @@ void RepliesWidget::paintEvent(QPaintEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto aboveHeight = _topBar->height() + _rootHeight;
|
const auto aboveHeight = _topBar->height();
|
||||||
const auto bg = e->rect().intersected(
|
const auto bg = e->rect().intersected(
|
||||||
QRect(0, aboveHeight, width(), height() - aboveHeight));
|
QRect(0, aboveHeight, width(), height() - aboveHeight));
|
||||||
SectionWidget::PaintBackground(controller(), this, bg);
|
SectionWidget::PaintBackground(controller(), this, bg);
|
||||||
|
|
||||||
auto p = Painter(this);
|
|
||||||
paintRoot(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::paintRoot(Painter &p) {
|
|
||||||
auto top = _topBar->bottomNoMargins();
|
|
||||||
p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
|
||||||
|
|
||||||
top += st::msgReplyPadding.top();
|
|
||||||
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
|
||||||
p.fillRect(rbar, st::msgInReplyBarColor);
|
|
||||||
|
|
||||||
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
|
||||||
if (!_rootTitle.isEmpty()) {
|
|
||||||
const auto media = _root ? _root->media() : nullptr;
|
|
||||||
if (media && media->hasReplyPreview()) {
|
|
||||||
if (const auto image = media->replyPreview()) {
|
|
||||||
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
|
||||||
p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
|
|
||||||
}
|
|
||||||
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
|
||||||
}
|
|
||||||
p.setPen(st::historyReplyNameFg);
|
|
||||||
p.setFont(st::msgServiceNameFont);
|
|
||||||
const auto poll = media ? media->poll() : nullptr;
|
|
||||||
const auto pinnedHeader = !poll
|
|
||||||
? tr::lng_pinned_message(tr::now)
|
|
||||||
: poll->quiz()
|
|
||||||
? tr::lng_pinned_quiz(tr::now)
|
|
||||||
: tr::lng_pinned_poll(tr::now);
|
|
||||||
_rootTitle.drawElided(p, left, top, width() - left - st::msgReplyPadding.right());
|
|
||||||
|
|
||||||
p.setPen(st::historyComposeAreaFg);
|
|
||||||
p.setTextPalette(st::historyComposeAreaPalette);
|
|
||||||
_rootMessage.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - st::msgReplyPadding.right());
|
|
||||||
p.restoreTextPalette();
|
|
||||||
} else {
|
|
||||||
p.setFont(st::msgDateFont);
|
|
||||||
p.setPen(st::historyComposeAreaFgService);
|
|
||||||
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - left - st::msgReplyPadding.right()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::onScroll() {
|
void RepliesWidget::onScroll() {
|
||||||
|
@ -1329,9 +1355,28 @@ void RepliesWidget::updateInnerVisibleArea() {
|
||||||
}
|
}
|
||||||
const auto scrollTop = _scroll->scrollTop();
|
const auto scrollTop = _scroll->scrollTop();
|
||||||
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
||||||
|
updatePinnedVisibility();
|
||||||
updateScrollDownVisibility();
|
updateScrollDownVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RepliesWidget::updatePinnedVisibility() {
|
||||||
|
if (!_loaded) {
|
||||||
|
return;
|
||||||
|
} else if (!_root) {
|
||||||
|
setPinnedVisibility(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto view = _inner->viewByPosition(_root->position());
|
||||||
|
setPinnedVisibility(!view
|
||||||
|
|| (view->y() + view->height() <= _scroll->scrollTop()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepliesWidget::setPinnedVisibility(bool shown) {
|
||||||
|
if (!animating()) {
|
||||||
|
_rootView->toggle(shown, anim::type::normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RepliesWidget::showAnimatedHook(
|
void RepliesWidget::showAnimatedHook(
|
||||||
const Window::SectionSlideParams ¶ms) {
|
const Window::SectionSlideParams ¶ms) {
|
||||||
_topBar->setAnimatingMode(true);
|
_topBar->setAnimatingMode(true);
|
||||||
|
@ -1349,6 +1394,7 @@ void RepliesWidget::showFinishedHook() {
|
||||||
// the section animation is finished,
|
// the section animation is finished,
|
||||||
// because after that the method showChildren() is called.
|
// because after that the method showChildren() is called.
|
||||||
setupDragArea();
|
setupDragArea();
|
||||||
|
updatePinnedVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RepliesWidget::floatPlayerHandleWheelEvent(QEvent *e) {
|
bool RepliesWidget::floatPlayerHandleWheelEvent(QEvent *e) {
|
||||||
|
|
|
@ -35,6 +35,8 @@ class ScrollArea;
|
||||||
class PlainShadow;
|
class PlainShadow;
|
||||||
class FlatButton;
|
class FlatButton;
|
||||||
class HistoryDownButton;
|
class HistoryDownButton;
|
||||||
|
template <typename Widget>
|
||||||
|
class SlideWrap;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
@ -151,6 +153,7 @@ private:
|
||||||
void setupComposeControls();
|
void setupComposeControls();
|
||||||
|
|
||||||
void setupRoot();
|
void setupRoot();
|
||||||
|
void setupRootView();
|
||||||
void setupCommentsRoot();
|
void setupCommentsRoot();
|
||||||
void refreshRootView();
|
void refreshRootView();
|
||||||
void setupDragArea();
|
void setupDragArea();
|
||||||
|
@ -162,11 +165,13 @@ private:
|
||||||
void scrollDownAnimationFinish();
|
void scrollDownAnimationFinish();
|
||||||
void updateScrollDownVisibility();
|
void updateScrollDownVisibility();
|
||||||
void updateScrollDownPosition();
|
void updateScrollDownPosition();
|
||||||
|
void updatePinnedVisibility();
|
||||||
|
|
||||||
void confirmSendNowSelected();
|
void confirmSendNowSelected();
|
||||||
void confirmDeleteSelected();
|
void confirmDeleteSelected();
|
||||||
void confirmForwardSelected();
|
void confirmForwardSelected();
|
||||||
void clearSelected();
|
void clearSelected();
|
||||||
|
void setPinnedVisibility(bool shown);
|
||||||
|
|
||||||
void send();
|
void send();
|
||||||
void send(Api::SendOptions options);
|
void send(Api::SendOptions options);
|
||||||
|
@ -226,8 +231,6 @@ private:
|
||||||
not_null<UserData*> bot,
|
not_null<UserData*> bot,
|
||||||
Api::SendOptions options);
|
Api::SendOptions options);
|
||||||
|
|
||||||
void paintRoot(Painter &p);
|
|
||||||
|
|
||||||
const not_null<History*> _history;
|
const not_null<History*> _history;
|
||||||
const MsgId _rootId = 0;
|
const MsgId _rootId = 0;
|
||||||
HistoryItem *_root = nullptr;
|
HistoryItem *_root = nullptr;
|
||||||
|
@ -243,8 +246,8 @@ private:
|
||||||
|
|
||||||
Ui::Text::String _rootTitle;
|
Ui::Text::String _rootTitle;
|
||||||
Ui::Text::String _rootMessage;
|
Ui::Text::String _rootMessage;
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::RpWidget>> _rootView;
|
||||||
object_ptr<Ui::PlainShadow> _rootShadow;
|
object_ptr<Ui::PlainShadow> _rootShadow;
|
||||||
int _rootHeight = 0;
|
|
||||||
|
|
||||||
std::vector<MsgId> _replyReturns;
|
std::vector<MsgId> _replyReturns;
|
||||||
HistoryItem *_replyReturn = nullptr;
|
HistoryItem *_replyReturn = nullptr;
|
||||||
|
@ -260,6 +263,8 @@ private:
|
||||||
bool _readRequestPending = false;
|
bool _readRequestPending = false;
|
||||||
mtpRequestId _readRequestId = 0;
|
mtpRequestId _readRequestId = 0;
|
||||||
|
|
||||||
|
bool _loaded = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue