mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show toast on share attempt to premium required.
This commit is contained in:
parent
eda7118df9
commit
f3f660a180
12 changed files with 255 additions and 64 deletions
|
@ -232,9 +232,7 @@ void PeerListBox::resizeEvent(QResizeEvent *e) {
|
||||||
void PeerListBox::paintEvent(QPaintEvent *e) {
|
void PeerListBox::paintEvent(QPaintEvent *e) {
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
|
|
||||||
const auto &bg = (_controller->listSt()
|
const auto &bg = _controller->computeListSt().bg;
|
||||||
? *_controller->listSt()
|
|
||||||
: st::peerListBox).bg;
|
|
||||||
const auto fill = QRect(
|
const auto fill = QRect(
|
||||||
0,
|
0,
|
||||||
_addedTopScrollSkip,
|
_addedTopScrollSkip,
|
||||||
|
@ -1255,6 +1253,16 @@ not_null<PeerListRow*> PeerListContent::rowAt(int index) const {
|
||||||
return _rows[index].get();
|
return _rows[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PeerListContent::searchRowsCount() const {
|
||||||
|
return _searchRows.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<PeerListRow*> PeerListContent::searchRowAt(int index) const {
|
||||||
|
Expects(index >= 0 && index < _searchRows.size());
|
||||||
|
|
||||||
|
return _searchRows[index].get();
|
||||||
|
}
|
||||||
|
|
||||||
void PeerListContent::setDescription(object_ptr<Ui::FlatLabel> description) {
|
void PeerListContent::setDescription(object_ptr<Ui::FlatLabel> description) {
|
||||||
_description = std::move(description);
|
_description = std::move(description);
|
||||||
if (_description) {
|
if (_description) {
|
||||||
|
@ -1349,6 +1357,7 @@ void PeerListContent::refreshRows() {
|
||||||
if (_mouseSelection) {
|
if (_mouseSelection) {
|
||||||
selectByMouse(QCursor::pos());
|
selectByMouse(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
loadProfilePhotos();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1903,7 +1912,9 @@ void PeerListContent::mouseLeftGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListContent::loadProfilePhotos() {
|
void PeerListContent::loadProfilePhotos() {
|
||||||
if (_visibleTop >= _visibleBottom) return;
|
if (_visibleTop >= _visibleBottom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto yFrom = _visibleTop;
|
auto yFrom = _visibleTop;
|
||||||
auto yTo = _visibleBottom + (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
auto yTo = _visibleBottom + (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
||||||
|
|
|
@ -332,6 +332,8 @@ public:
|
||||||
virtual void peerListScrollToTop() = 0;
|
virtual void peerListScrollToTop() = 0;
|
||||||
virtual int peerListFullRowsCount() = 0;
|
virtual int peerListFullRowsCount() = 0;
|
||||||
virtual PeerListRow *peerListFindRow(PeerListRowId id) = 0;
|
virtual PeerListRow *peerListFindRow(PeerListRowId id) = 0;
|
||||||
|
virtual int peerListSearchRowsCount() = 0;
|
||||||
|
virtual not_null<PeerListRow*> peerListSearchRowAt(int index) = 0;
|
||||||
virtual std::optional<QPoint> peerListLastRowMousePosition() = 0;
|
virtual std::optional<QPoint> peerListLastRowMousePosition() = 0;
|
||||||
virtual void peerListSortRows(Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) = 0;
|
virtual void peerListSortRows(Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) = 0;
|
||||||
virtual int peerListPartitionRows(Fn<bool(const PeerListRow &a)> border) = 0;
|
virtual int peerListPartitionRows(Fn<bool(const PeerListRow &a)> border) = 0;
|
||||||
|
@ -627,6 +629,8 @@ public:
|
||||||
void convertRowToSearchResult(not_null<PeerListRow*> row);
|
void convertRowToSearchResult(not_null<PeerListRow*> row);
|
||||||
int fullRowsCount() const;
|
int fullRowsCount() const;
|
||||||
not_null<PeerListRow*> rowAt(int index) const;
|
not_null<PeerListRow*> rowAt(int index) const;
|
||||||
|
int searchRowsCount() const;
|
||||||
|
not_null<PeerListRow*> searchRowAt(int index) const;
|
||||||
void setDescription(object_ptr<Ui::FlatLabel> description);
|
void setDescription(object_ptr<Ui::FlatLabel> description);
|
||||||
void setSearchLoading(object_ptr<Ui::FlatLabel> loading);
|
void setSearchLoading(object_ptr<Ui::FlatLabel> loading);
|
||||||
void setSearchNoResults(object_ptr<Ui::FlatLabel> noResults);
|
void setSearchNoResults(object_ptr<Ui::FlatLabel> noResults);
|
||||||
|
@ -908,6 +912,12 @@ public:
|
||||||
not_null<PeerListRow*> peerListRowAt(int index) override {
|
not_null<PeerListRow*> peerListRowAt(int index) override {
|
||||||
return _content->rowAt(index);
|
return _content->rowAt(index);
|
||||||
}
|
}
|
||||||
|
int peerListSearchRowsCount() override {
|
||||||
|
return _content->searchRowsCount();
|
||||||
|
}
|
||||||
|
not_null<PeerListRow*> peerListSearchRowAt(int index) override {
|
||||||
|
return _content->searchRowAt(index);
|
||||||
|
}
|
||||||
void peerListRefreshRows() override {
|
void peerListRefreshRows() override {
|
||||||
_content->refreshRows();
|
_content->refreshRows();
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,39 +271,17 @@ ChatsListBoxController::Row::Row(
|
||||||
, _delegate(delegate) {
|
, _delegate(delegate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintLock(
|
|
||||||
Painter &p,
|
|
||||||
not_null<const style::PeerListItem*> st,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int outerWidth,
|
|
||||||
int size) {
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
|
||||||
const auto &check = st->checkbox.check;
|
|
||||||
auto pen = check.border->p;
|
|
||||||
pen.setWidthF(check.width);
|
|
||||||
p.setPen(pen);
|
|
||||||
p.setBrush(st::premiumButtonBg2);
|
|
||||||
const auto &icon = st::stickersPremiumLock;
|
|
||||||
const auto width = icon.width();
|
|
||||||
const auto height = icon.height();
|
|
||||||
const auto rect = QRect(
|
|
||||||
QPoint(x + size - width, y + size - height),
|
|
||||||
icon.size());
|
|
||||||
p.drawEllipse(rect);
|
|
||||||
icon.paintInCenter(p, rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ChatsListBoxController::Row::generatePaintUserpicCallback(
|
auto ChatsListBoxController::Row::generatePaintUserpicCallback(
|
||||||
bool forceRound)
|
bool forceRound)
|
||||||
-> PaintRoundImageCallback {
|
-> PaintRoundImageCallback {
|
||||||
auto result = PeerListRow::generatePaintUserpicCallback(forceRound);
|
auto result = PeerListRow::generatePaintUserpicCallback(forceRound);
|
||||||
if (_locked) {
|
if (_locked) {
|
||||||
AssertIsDebug();
|
const auto st = _delegate
|
||||||
const auto st = /*_delegate ? _delegate->rowSt() : */&st::defaultPeerListItem;
|
? _delegate->rowSt().get()
|
||||||
|
: &st::defaultPeerListItem;
|
||||||
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
||||||
result(p, x, y, outerWidth, size);
|
result(p, x, y, outerWidth, size);
|
||||||
PaintLock(p, st, x, y, outerWidth, size);
|
PaintPremiumRequiredLock(p, st, x, y, outerWidth, size);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -475,7 +453,7 @@ void PeerListStories::process(not_null<PeerListRow*> row) {
|
||||||
|
|
||||||
bool PeerListStories::handleClick(not_null<PeerData*> peer) {
|
bool PeerListStories::handleClick(not_null<PeerData*> peer) {
|
||||||
const auto point = _delegate->peerListLastRowMousePosition();
|
const auto point = _delegate->peerListLastRowMousePosition();
|
||||||
const auto &st = _controller->listSt()->item;
|
const auto &st = _controller->computeListSt().item;
|
||||||
if (point && point->x() < st.photoPosition.x() + st.photoSize) {
|
if (point && point->x() < st.photoPosition.x() + st.photoSize) {
|
||||||
if (const auto window = peer->session().tryResolveWindow()) {
|
if (const auto window = peer->session().tryResolveWindow()) {
|
||||||
if (const auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
|
@ -492,9 +470,9 @@ bool PeerListStories::handleClick(not_null<PeerData*> peer) {
|
||||||
void PeerListStories::prepare(not_null<PeerListDelegate*> delegate) {
|
void PeerListStories::prepare(not_null<PeerListDelegate*> delegate) {
|
||||||
_delegate = delegate;
|
_delegate = delegate;
|
||||||
|
|
||||||
_unreadBrush = PeerListStoriesGradient(*_controller->listSt());
|
_unreadBrush = PeerListStoriesGradient(_controller->computeListSt());
|
||||||
style::PaletteChanged() | rpl::start_with_next([=] {
|
style::PaletteChanged() | rpl::start_with_next([=] {
|
||||||
_unreadBrush = PeerListStoriesGradient(*_controller->listSt());
|
_unreadBrush = PeerListStoriesGradient(_controller->computeListSt());
|
||||||
updateColors();
|
updateColors();
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
@ -738,9 +716,7 @@ void ChooseRecipientBoxController::prepareViewHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChooseRecipientBoxController::refreshLockedRows() {
|
void ChooseRecipientBoxController::refreshLockedRows() {
|
||||||
auto count = delegate()->peerListFullRowsCount();
|
const auto process = [&](not_null<PeerListRow*> raw) {
|
||||||
for (auto i = 0; i != count; ++i) {
|
|
||||||
const auto raw = delegate()->peerListRowAt(i);
|
|
||||||
const auto row = static_cast<Row*>(raw.get());
|
const auto row = static_cast<Row*>(raw.get());
|
||||||
if (const auto user = row->peer()->asUser()) {
|
if (const auto user = row->peer()->asUser()) {
|
||||||
const auto history = row->history();
|
const auto history = row->history();
|
||||||
|
@ -751,6 +727,14 @@ void ChooseRecipientBoxController::refreshLockedRows() {
|
||||||
delegate()->peerListUpdateRow(row);
|
delegate()->peerListUpdateRow(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
auto count = delegate()->peerListFullRowsCount();
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
process(delegate()->peerListRowAt(i));
|
||||||
|
}
|
||||||
|
count = delegate()->peerListSearchRowsCount();
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
process(delegate()->peerListSearchRowAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,6 +750,10 @@ void ChooseRecipientBoxController::rowPreloadUserpic(not_null<Row*> row) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_null<const style::PeerListItem*> ChooseRecipientBoxController::rowSt() {
|
||||||
|
return &computeListSt().item;
|
||||||
|
}
|
||||||
|
|
||||||
void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
|
void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
if (showLockedError(row)) {
|
if (showLockedError(row)) {
|
||||||
return;
|
return;
|
||||||
|
@ -845,7 +833,7 @@ auto ChooseRecipientBoxController::createRow(
|
||||||
: ((peer->isBroadcast() && !Data::CanSendAnything(peer))
|
: ((peer->isBroadcast() && !Data::CanSendAnything(peer))
|
||||||
|| peer->isRepliesChat()
|
|| peer->isRepliesChat()
|
||||||
|| (peer->isUser() && (_premiumRequiredError
|
|| (peer->isUser() && (_premiumRequiredError
|
||||||
? peer->asUser()->isInaccessible()
|
? !peer->asUser()->canSendIgnoreRequirePremium()
|
||||||
: !Data::CanSendAnything(peer))));
|
: !Data::CanSendAnything(peer))));
|
||||||
if (skip) {
|
if (skip) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1077,3 +1065,26 @@ auto ChooseTopicBoxController::createRow(not_null<Data::ForumTopic*> topic)
|
||||||
const auto skip = _filter && !_filter(topic);
|
const auto skip = _filter && !_filter(topic);
|
||||||
return skip ? nullptr : std::make_unique<Row>(topic);
|
return skip ? nullptr : std::make_unique<Row>(topic);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PaintPremiumRequiredLock(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const style::PeerListItem*> st,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int outerWidth,
|
||||||
|
int size) {
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
const auto &check = st->checkbox.check;
|
||||||
|
auto pen = check.border->p;
|
||||||
|
pen.setWidthF(check.width);
|
||||||
|
p.setPen(pen);
|
||||||
|
p.setBrush(st::premiumButtonBg2);
|
||||||
|
const auto &icon = st::stickersPremiumLock;
|
||||||
|
const auto width = icon.width();
|
||||||
|
const auto height = icon.height();
|
||||||
|
const auto rect = QRect(
|
||||||
|
QPoint(x + size - width, y + size - height),
|
||||||
|
icon.size());
|
||||||
|
p.drawEllipse(rect);
|
||||||
|
icon.paintInCenter(p, rect);
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct PeerListItem;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class Thread;
|
class Thread;
|
||||||
class Forum;
|
class Forum;
|
||||||
|
@ -95,6 +99,8 @@ public:
|
||||||
class RowDelegate {
|
class RowDelegate {
|
||||||
public:
|
public:
|
||||||
virtual void rowPreloadUserpic(not_null<Row*> row);
|
virtual void rowPreloadUserpic(not_null<Row*> row);
|
||||||
|
[[nodiscard]] virtual auto rowSt()
|
||||||
|
-> not_null<const style::PeerListItem*> = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Row : public PeerListRow {
|
class Row : public PeerListRow {
|
||||||
|
@ -266,6 +272,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
void refreshLockedRows();
|
void refreshLockedRows();
|
||||||
void rowPreloadUserpic(not_null<Row*> row) override;
|
void rowPreloadUserpic(not_null<Row*> row) override;
|
||||||
|
not_null<const style::PeerListItem*> rowSt() override;
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
FnMut<void(not_null<Data::Thread*>)> _callback;
|
FnMut<void(not_null<Data::Thread*>)> _callback;
|
||||||
|
@ -350,3 +357,11 @@ private:
|
||||||
Fn<bool(not_null<Data::ForumTopic*>)> _filter;
|
Fn<bool(not_null<Data::ForumTopic*>)> _filter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PaintPremiumRequiredLock(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const style::PeerListItem*> st,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int outerWidth,
|
||||||
|
int size);
|
||||||
|
|
|
@ -281,9 +281,7 @@ void PeerListsBox::resizeEvent(QResizeEvent *e) {
|
||||||
void PeerListsBox::paintEvent(QPaintEvent *e) {
|
void PeerListsBox::paintEvent(QPaintEvent *e) {
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
|
|
||||||
const auto &bg = (firstController()->listSt()
|
const auto &bg = firstController()->computeListSt().bg;
|
||||||
? *firstController()->listSt()
|
|
||||||
: st::peerListBox).bg;
|
|
||||||
for (const auto &rect : e->region()) {
|
for (const auto &rect : e->region()) {
|
||||||
p.fillRect(rect, bg);
|
p.fillRect(rect, bg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1194,6 +1194,11 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto filterCallback = [](not_null<Data::Thread*> thread) {
|
auto filterCallback = [](not_null<Data::Thread*> thread) {
|
||||||
|
if (const auto user = thread->peer()->asUser()) {
|
||||||
|
if (user->canSendIgnoreRequirePremium()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Data::CanSendTexts(thread);
|
return Data::CanSendTexts(thread);
|
||||||
};
|
};
|
||||||
auto object = Box<ShareBox>(ShareBox::Descriptor{
|
auto object = Box<ShareBox>(ShareBox::Descriptor{
|
||||||
|
@ -1201,6 +1206,7 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
.copyCallback = std::move(copyCallback),
|
.copyCallback = std::move(copyCallback),
|
||||||
.submitCallback = std::move(submitCallback),
|
.submitCallback = std::move(submitCallback),
|
||||||
.filterCallback = std::move(filterCallback),
|
.filterCallback = std::move(filterCallback),
|
||||||
|
.premiumRequiredError = SharePremiumRequiredError(),
|
||||||
});
|
});
|
||||||
*box = Ui::MakeWeak(object.data());
|
*box = Ui::MakeWeak(object.data());
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
|
|
||||||
|
#include "api/api_premium.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "base/qthelp_url.h"
|
#include "base/qthelp_url.h"
|
||||||
|
@ -30,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item_helpers.h"
|
#include "history/history_item_helpers.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/view/history_view_context_menu.h" // CopyPostLink.
|
#include "history/view/history_view_context_menu.h" // CopyPostLink.
|
||||||
|
#include "settings/settings_premium.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
|
@ -38,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_game.h"
|
#include "data/data_game.h"
|
||||||
#include "data/data_histories.h"
|
#include "data/data_histories.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
#include "data/data_forum.h"
|
#include "data/data_forum.h"
|
||||||
|
@ -96,19 +99,23 @@ protected:
|
||||||
private:
|
private:
|
||||||
struct Chat {
|
struct Chat {
|
||||||
Chat(
|
Chat(
|
||||||
not_null<PeerData*> peer,
|
not_null<History*> history,
|
||||||
const style::PeerListItem &st,
|
const style::PeerListItem &st,
|
||||||
Fn<void()> updateCallback);
|
Fn<void()> updateCallback);
|
||||||
|
|
||||||
|
not_null<History*> history;
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
Data::ForumTopic *topic = nullptr;
|
Data::ForumTopic *topic = nullptr;
|
||||||
rpl::lifetime topicLifetime;
|
rpl::lifetime topicLifetime;
|
||||||
Ui::RoundImageCheckbox checkbox;
|
Ui::RoundImageCheckbox checkbox;
|
||||||
Ui::Text::String name;
|
Ui::Text::String name;
|
||||||
Ui::Animations::Simple nameActive;
|
Ui::Animations::Simple nameActive;
|
||||||
|
bool locked = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
|
bool showLockedError(not_null<Chat*> chat);
|
||||||
|
void refreshLockedRows();
|
||||||
|
|
||||||
[[nodiscard]] int displayedChatsCount() const;
|
[[nodiscard]] int displayedChatsCount() const;
|
||||||
[[nodiscard]] not_null<Data::Thread*> chatThread(
|
[[nodiscard]] not_null<Data::Thread*> chatThread(
|
||||||
|
@ -117,12 +124,14 @@ private:
|
||||||
void paintChat(Painter &p, not_null<Chat*> chat, int index);
|
void paintChat(Painter &p, not_null<Chat*> chat, int index);
|
||||||
void updateChat(not_null<PeerData*> peer);
|
void updateChat(not_null<PeerData*> peer);
|
||||||
void updateChatName(not_null<Chat*> chat);
|
void updateChatName(not_null<Chat*> chat);
|
||||||
|
void initChatLocked(not_null<Chat*> chat);
|
||||||
void repaintChat(not_null<PeerData*> peer);
|
void repaintChat(not_null<PeerData*> peer);
|
||||||
int chatIndex(not_null<PeerData*> peer) const;
|
int chatIndex(not_null<PeerData*> peer) const;
|
||||||
void repaintChatAtIndex(int index);
|
void repaintChatAtIndex(int index);
|
||||||
Chat *getChatAtIndex(int index);
|
Chat *getChatAtIndex(int index);
|
||||||
|
|
||||||
void loadProfilePhotos(int yFrom);
|
void loadProfilePhotos();
|
||||||
|
void preloadUserpic(not_null<Dialogs::Entry*> entry);
|
||||||
void changeCheckState(Chat *chat);
|
void changeCheckState(Chat *chat);
|
||||||
void chooseForumTopic(not_null<Data::Forum*> forum);
|
void chooseForumTopic(not_null<Data::Forum*> forum);
|
||||||
enum class ChangeStateWay {
|
enum class ChangeStateWay {
|
||||||
|
@ -153,6 +162,7 @@ private:
|
||||||
int _columnCount = 4;
|
int _columnCount = 4;
|
||||||
int _active = -1;
|
int _active = -1;
|
||||||
int _upon = -1;
|
int _upon = -1;
|
||||||
|
int _visibleTop = 0;
|
||||||
|
|
||||||
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
|
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
|
||||||
QString _filter;
|
QString _filter;
|
||||||
|
@ -649,6 +659,16 @@ ShareBox::Inner::Inner(
|
||||||
_rowHeight = st::shareRowHeight;
|
_rowHeight = st::shareRowHeight;
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
|
if (_descriptor.premiumRequiredError) {
|
||||||
|
const auto session = _descriptor.session;
|
||||||
|
rpl::merge(
|
||||||
|
Data::AmPremiumValue(session) | rpl::to_empty,
|
||||||
|
session->api().premium().somePremiumRequiredResolved()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
refreshLockedRows();
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
const auto self = _descriptor.session->user();
|
const auto self = _descriptor.session->user();
|
||||||
const auto selfHistory = self->owner().history(self);
|
const auto selfHistory = self->owner().history(self);
|
||||||
if (_descriptor.filterCallback(selfHistory)) {
|
if (_descriptor.filterCallback(selfHistory)) {
|
||||||
|
@ -705,10 +725,48 @@ void ShareBox::Inner::invalidateCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShareBox::Inner::showLockedError(not_null<Chat*> chat) {
|
||||||
|
if (!chat->locked) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
::Settings::ShowPremiumPromoToast(
|
||||||
|
Main::MakeSessionShow(_show, _descriptor.session),
|
||||||
|
ChatHelpers::ResolveWindowDefault(),
|
||||||
|
_descriptor.premiumRequiredError(chat->peer->asUser()).text,
|
||||||
|
u"require_premium"_q);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShareBox::Inner::refreshLockedRows() {
|
||||||
|
auto changed = false;
|
||||||
|
for (const auto &[peer, data] : _dataMap) {
|
||||||
|
const auto history = data->history;
|
||||||
|
const auto locked = (Api::ResolveRequiresPremiumToWrite(history)
|
||||||
|
== Api::RequirePremiumState::Yes);
|
||||||
|
if (data->locked != locked) {
|
||||||
|
data->locked = locked;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &data : d_byUsernameFiltered) {
|
||||||
|
const auto history = data->history;
|
||||||
|
const auto locked = (Api::ResolveRequiresPremiumToWrite(history)
|
||||||
|
== Api::RequirePremiumState::Yes);
|
||||||
|
if (data->locked != locked) {
|
||||||
|
data->locked = locked;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::visibleTopBottomUpdated(
|
void ShareBox::Inner::visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) {
|
int visibleBottom) {
|
||||||
loadProfilePhotos(visibleTop);
|
_visibleTop = visibleTop;
|
||||||
|
loadProfilePhotos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::activateSkipRow(int direction) {
|
void ShareBox::Inner::activateSkipRow(int direction) {
|
||||||
|
@ -760,6 +818,16 @@ void ShareBox::Inner::updateChatName(not_null<Chat*> chat) {
|
||||||
chat->name.setText(_st.item.nameStyle, text, Ui::NameTextOptions());
|
chat->name.setText(_st.item.nameStyle, text, Ui::NameTextOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareBox::Inner::initChatLocked(not_null<Chat*> chat) {
|
||||||
|
if (_descriptor.premiumRequiredError) {
|
||||||
|
const auto history = chat->history;
|
||||||
|
const auto require = Api::ResolveRequiresPremiumToWrite(history);
|
||||||
|
if (require == Api::RequirePremiumState::Yes) {
|
||||||
|
chat->locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::repaintChatAtIndex(int index) {
|
void ShareBox::Inner::repaintChatAtIndex(int index) {
|
||||||
if (index < 0) return;
|
if (index < 0) return;
|
||||||
|
|
||||||
|
@ -829,11 +897,11 @@ int ShareBox::Inner::chatIndex(not_null<PeerData*> peer) const {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
void ShareBox::Inner::loadProfilePhotos() {
|
||||||
if (!parentWidget()) return;
|
if (!parentWidget()) {
|
||||||
if (yFrom < 0) {
|
return;
|
||||||
yFrom = 0;
|
|
||||||
}
|
}
|
||||||
|
auto yFrom = std::max(_visibleTop, 0);
|
||||||
if (auto part = (yFrom % _rowHeight)) {
|
if (auto part = (yFrom % _rowHeight)) {
|
||||||
yFrom -= part;
|
yFrom -= part;
|
||||||
}
|
}
|
||||||
|
@ -853,20 +921,38 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
||||||
if (((*i)->index() * _rowHeight) >= yTo) {
|
if (((*i)->index() * _rowHeight) >= yTo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
(*i)->entry()->chatListPreloadData();
|
preloadUserpic((*i)->entry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!_filtered.empty()) {
|
} else {
|
||||||
int from = yFrom / _rowHeight;
|
const auto from = std::max(yFrom / _rowHeight, 0);
|
||||||
if (from < 0) from = 0;
|
const auto to = std::max((yTo / _rowHeight) + 1, from);
|
||||||
if (from < _filtered.size()) {
|
|
||||||
int to = (yTo / _rowHeight) + 1;
|
|
||||||
if (to > _filtered.size()) to = _filtered.size();
|
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
const auto ffrom = from;
|
||||||
_filtered[from]->entry()->chatListPreloadData();
|
const auto fto = std::min(to, int(_filtered.size()));
|
||||||
}
|
for (auto i = ffrom; i != fto; ++i) {
|
||||||
|
preloadUserpic(_filtered[i]->entry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto ufrom = std::max(from - int(_filtered.size()), 0);
|
||||||
|
const auto uto = std::min(
|
||||||
|
to - int(_filtered.size()),
|
||||||
|
int(d_byUsernameFiltered.size()));
|
||||||
|
for (auto i = ufrom; i != uto; ++i) {
|
||||||
|
preloadUserpic(d_byUsernameFiltered[i]->history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShareBox::Inner::preloadUserpic(not_null<Dialogs::Entry*> entry) {
|
||||||
|
entry->chatListPreloadData();
|
||||||
|
const auto history = entry->asHistory();
|
||||||
|
if (!_descriptor.premiumRequiredError || !history) {
|
||||||
|
return;
|
||||||
|
} else if (Api::ResolveRequiresPremiumToWrite(history)
|
||||||
|
== Api::RequirePremiumState::Unknown) {
|
||||||
|
const auto user = history->peer->asUser();
|
||||||
|
_descriptor.session->api().premium().resolvePremiumRequired(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,15 +963,19 @@ auto ShareBox::Inner::getChat(not_null<Dialogs::Row*> row)
|
||||||
if (const auto data = static_cast<Chat*>(row->attached)) {
|
if (const auto data = static_cast<Chat*>(row->attached)) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
const auto peer = row->history()->peer;
|
const auto history = row->history();
|
||||||
|
const auto peer = history->peer;
|
||||||
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
|
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
|
||||||
row->attached = i->second.get();
|
row->attached = i->second.get();
|
||||||
return i->second.get();
|
return i->second.get();
|
||||||
}
|
}
|
||||||
const auto &[i, ok] = _dataMap.emplace(
|
const auto &[i, ok] = _dataMap.emplace(
|
||||||
peer,
|
peer,
|
||||||
std::make_unique<Chat>(peer, _st.item, [=] { repaintChat(peer); }));
|
std::make_unique<Chat>(history, _st.item, [=] {
|
||||||
|
repaintChat(peer);
|
||||||
|
}));
|
||||||
updateChatName(i->second.get());
|
updateChatName(i->second.get());
|
||||||
|
initChatLocked(i->second.get());
|
||||||
row->attached = i->second.get();
|
row->attached = i->second.get();
|
||||||
return i->second.get();
|
return i->second.get();
|
||||||
}
|
}
|
||||||
|
@ -919,6 +1009,16 @@ void ShareBox::Inner::paintChat(
|
||||||
auto photoTop = st::sharePhotoTop;
|
auto photoTop = st::sharePhotoTop;
|
||||||
chat->checkbox.paint(p, x + photoLeft, y + photoTop, outerWidth);
|
chat->checkbox.paint(p, x + photoLeft, y + photoTop, outerWidth);
|
||||||
|
|
||||||
|
if (chat->locked) {
|
||||||
|
PaintPremiumRequiredLock(
|
||||||
|
p,
|
||||||
|
&_st.item,
|
||||||
|
x + photoLeft,
|
||||||
|
y + photoTop,
|
||||||
|
outerWidth,
|
||||||
|
_st.item.checkbox.imageRadius * 2);
|
||||||
|
}
|
||||||
|
|
||||||
auto nameActive = chat->nameActive.value((index == _active) ? 1. : 0.);
|
auto nameActive = chat->nameActive.value((index == _active) ? 1. : 0.);
|
||||||
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameActive));
|
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameActive));
|
||||||
|
|
||||||
|
@ -929,10 +1029,11 @@ void ShareBox::Inner::paintChat(
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareBox::Inner::Chat::Chat(
|
ShareBox::Inner::Chat::Chat(
|
||||||
not_null<PeerData*> peer,
|
not_null<History*> history,
|
||||||
const style::PeerListItem &st,
|
const style::PeerListItem &st,
|
||||||
Fn<void()> updateCallback)
|
Fn<void()> updateCallback)
|
||||||
: peer(peer)
|
: history(history)
|
||||||
|
, peer(history->peer)
|
||||||
, checkbox(
|
, checkbox(
|
||||||
st.checkbox,
|
st.checkbox,
|
||||||
updateCallback,
|
updateCallback,
|
||||||
|
@ -1062,7 +1163,7 @@ void ShareBox::Inner::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::changeCheckState(Chat *chat) {
|
void ShareBox::Inner::changeCheckState(Chat *chat) {
|
||||||
if (!chat) {
|
if (!chat || showLockedError(chat)) {
|
||||||
return;
|
return;
|
||||||
} else if (!_filter.isEmpty()) {
|
} else if (!_filter.isEmpty()) {
|
||||||
const auto history = chat->peer->owner().history(chat->peer);
|
const auto history = chat->peer->owner().history(chat->peer);
|
||||||
|
@ -1194,8 +1295,8 @@ void ShareBox::Inner::updateFilter(QString filter) {
|
||||||
_searchRequests.fire({});
|
_searchRequests.fire({});
|
||||||
}
|
}
|
||||||
setActive(-1);
|
setActive(-1);
|
||||||
|
loadProfilePhotos();
|
||||||
update();
|
update();
|
||||||
loadProfilePhotos(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,10 +1335,11 @@ void ShareBox::Inner::peopleReceived(
|
||||||
}
|
}
|
||||||
_byUsernameFiltered.push_back(peer);
|
_byUsernameFiltered.push_back(peer);
|
||||||
d_byUsernameFiltered.push_back(std::make_unique<Chat>(
|
d_byUsernameFiltered.push_back(std::make_unique<Chat>(
|
||||||
peer,
|
history,
|
||||||
_st.item,
|
_st.item,
|
||||||
[=] { repaintChat(peer); }));
|
[=] { repaintChat(peer); }));
|
||||||
updateChatName(d_byUsernameFiltered.back().get());
|
updateChatName(d_byUsernameFiltered.back().get());
|
||||||
|
initChatLocked(d_byUsernameFiltered.back().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1256,6 +1358,7 @@ void ShareBox::Inner::refresh() {
|
||||||
} else {
|
} else {
|
||||||
resize(width(), st::noContactsHeight);
|
resize(width(), st::noContactsHeight);
|
||||||
}
|
}
|
||||||
|
loadProfilePhotos();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1525,6 +1628,11 @@ void FastShareMessage(
|
||||||
const auto requiredRight = item->requiredSendRight();
|
const auto requiredRight = item->requiredSendRight();
|
||||||
const auto requiresInline = item->requiresSendInlineRight();
|
const auto requiresInline = item->requiresSendInlineRight();
|
||||||
auto filterCallback = [=](not_null<Data::Thread*> thread) {
|
auto filterCallback = [=](not_null<Data::Thread*> thread) {
|
||||||
|
if (const auto user = thread->peer()->asUser()) {
|
||||||
|
if (user->canSendIgnoreRequirePremium()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Data::CanSend(thread, requiredRight)
|
return Data::CanSend(thread, requiredRight)
|
||||||
&& (!requiresInline
|
&& (!requiresInline
|
||||||
|| Data::CanSend(thread, ChatRestriction::SendInline))
|
|| Data::CanSend(thread, ChatRestriction::SendInline))
|
||||||
|
@ -1547,10 +1655,16 @@ void FastShareMessage(
|
||||||
.show = !hasOnlyForcedForwardedInfo,
|
.show = !hasOnlyForcedForwardedInfo,
|
||||||
.hasCaptions = hasCaptions,
|
.hasCaptions = hasCaptions,
|
||||||
},
|
},
|
||||||
|
.premiumRequiredError = SharePremiumRequiredError(),
|
||||||
}),
|
}),
|
||||||
Ui::LayerOption::CloseOther);
|
Ui::LayerOption::CloseOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto SharePremiumRequiredError()
|
||||||
|
-> Fn<ChooseRecipientPremiumRequiredError(not_null<UserData*>)> {
|
||||||
|
return WritePremiumRequiredError;
|
||||||
|
}
|
||||||
|
|
||||||
void ShareGameScoreByHash(
|
void ShareGameScoreByHash(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
const QString &hash) {
|
const QString &hash) {
|
||||||
|
|
|
@ -69,6 +69,10 @@ void FastShareMessage(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<HistoryItem*> item);
|
not_null<HistoryItem*> item);
|
||||||
|
|
||||||
|
struct ChooseRecipientPremiumRequiredError;
|
||||||
|
[[nodiscard]] auto SharePremiumRequiredError()
|
||||||
|
-> Fn<ChooseRecipientPremiumRequiredError(not_null<UserData*>)>;
|
||||||
|
|
||||||
class ShareBox final : public Ui::BoxContent {
|
class ShareBox final : public Ui::BoxContent {
|
||||||
public:
|
public:
|
||||||
using CopyCallback = Fn<void()>;
|
using CopyCallback = Fn<void()>;
|
||||||
|
@ -101,6 +105,9 @@ public:
|
||||||
bool hasCaptions = false;
|
bool hasCaptions = false;
|
||||||
} forwardOptions;
|
} forwardOptions;
|
||||||
HistoryView::ScheduleBoxStyleArgs scheduleBoxStyle;
|
HistoryView::ScheduleBoxStyleArgs scheduleBoxStyle;
|
||||||
|
|
||||||
|
using PremiumRequiredError = ChooseRecipientPremiumRequiredError;
|
||||||
|
Fn<PremiumRequiredError(not_null<UserData*>)> premiumRequiredError;
|
||||||
};
|
};
|
||||||
ShareBox(QWidget*, Descriptor &&descriptor);
|
ShareBox(QWidget*, Descriptor &&descriptor);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
#include "calls/group/calls_group_rtmp.h"
|
#include "calls/group/calls_group_rtmp.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
|
@ -191,6 +192,11 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
show->showToast(tr::lng_share_done(tr::now));
|
show->showToast(tr::lng_share_done(tr::now));
|
||||||
};
|
};
|
||||||
auto filterCallback = [](not_null<Data::Thread*> thread) {
|
auto filterCallback = [](not_null<Data::Thread*> thread) {
|
||||||
|
if (const auto user = thread->peer()->asUser()) {
|
||||||
|
if (user->canSendIgnoreRequirePremium()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Data::CanSend(thread, ChatRestriction::SendOther);
|
return Data::CanSend(thread, ChatRestriction::SendOther);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,6 +233,7 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
.st = &st::groupCallShareBoxList,
|
.st = &st::groupCallShareBoxList,
|
||||||
.stLabel = &st::groupCallField,
|
.stLabel = &st::groupCallField,
|
||||||
.scheduleBoxStyle = scheduleStyle(),
|
.scheduleBoxStyle = scheduleStyle(),
|
||||||
|
.premiumRequiredError = SharePremiumRequiredError(),
|
||||||
});
|
});
|
||||||
*box = result.data();
|
*box = result.data();
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -402,6 +402,10 @@ bool UserData::requirePremiumToWriteKnown() const {
|
||||||
return (flags() & UserDataFlag::RequirePremiumToWriteKnown);
|
return (flags() & UserDataFlag::RequirePremiumToWriteKnown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UserData::canSendIgnoreRequirePremium() const {
|
||||||
|
return !isInaccessible() && !isRepliesChat();
|
||||||
|
}
|
||||||
|
|
||||||
bool UserData::readDatesPrivate() const {
|
bool UserData::readDatesPrivate() const {
|
||||||
return (flags() & UserDataFlag::ReadDatesPrivate);
|
return (flags() & UserDataFlag::ReadDatesPrivate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ public:
|
||||||
[[nodiscard]] bool someRequirePremiumToWrite() const;
|
[[nodiscard]] bool someRequirePremiumToWrite() const;
|
||||||
[[nodiscard]] bool meRequiresPremiumToWrite() const;
|
[[nodiscard]] bool meRequiresPremiumToWrite() const;
|
||||||
[[nodiscard]] bool requirePremiumToWriteKnown() const;
|
[[nodiscard]] bool requirePremiumToWriteKnown() const;
|
||||||
|
[[nodiscard]] bool canSendIgnoreRequirePremium() const;
|
||||||
[[nodiscard]] bool readDatesPrivate() const;
|
[[nodiscard]] bool readDatesPrivate() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canShareThisContact() const;
|
[[nodiscard]] bool canShareThisContact() const;
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_stories.h"
|
#include "data/data_stories.h"
|
||||||
#include "data/data_thread.h"
|
#include "data/data_thread.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item_helpers.h" // GetErrorTextForSending.
|
#include "history/history_item_helpers.h" // GetErrorTextForSending.
|
||||||
#include "history/view/history_view_context_menu.h" // CopyStoryLink.
|
#include "history/view/history_view_context_menu.h" // CopyStoryLink.
|
||||||
|
@ -61,6 +62,11 @@ namespace Media::Stories {
|
||||||
};
|
};
|
||||||
const auto state = std::make_shared<State>();
|
const auto state = std::make_shared<State>();
|
||||||
auto filterCallback = [=](not_null<Data::Thread*> thread) {
|
auto filterCallback = [=](not_null<Data::Thread*> thread) {
|
||||||
|
if (const auto user = thread->peer()->asUser()) {
|
||||||
|
if (user->canSendIgnoreRequirePremium()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Data::CanSend(thread, ChatRestriction::SendPhotos)
|
return Data::CanSend(thread, ChatRestriction::SendPhotos)
|
||||||
&& Data::CanSend(thread, ChatRestriction::SendVideos);
|
&& Data::CanSend(thread, ChatRestriction::SendVideos);
|
||||||
};
|
};
|
||||||
|
@ -189,6 +195,7 @@ namespace Media::Stories {
|
||||||
.scheduleBoxStyle = (viewerStyle
|
.scheduleBoxStyle = (viewerStyle
|
||||||
? viewerScheduleStyle()
|
? viewerScheduleStyle()
|
||||||
: HistoryView::ScheduleBoxStyleArgs()),
|
: HistoryView::ScheduleBoxStyleArgs()),
|
||||||
|
.premiumRequiredError = SharePremiumRequiredError(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue