mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow editing links from ShowInviteLinkBox.
This commit is contained in:
parent
3399a05f1f
commit
047bf467b5
4 changed files with 301 additions and 127 deletions
|
@ -296,7 +296,6 @@ void PeerListController::setDescriptionText(const QString &text) {
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
setDescription(nullptr);
|
setDescription(nullptr);
|
||||||
} else {
|
} else {
|
||||||
const auto &st = _listSt ? *_listSt : st::peerListBox;
|
|
||||||
setDescription(object_ptr<Ui::FlatLabel>(nullptr, text, computeListSt().about));
|
setDescription(object_ptr<Ui::FlatLabel>(nullptr, text, computeListSt().about));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,6 +339,10 @@ rpl::producer<int> PeerListController::boxHeightValue() const {
|
||||||
return rpl::single(st::boxMaxListHeight);
|
return rpl::single(st::boxMaxListHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PeerListController::descriptionTopSkipMin() const {
|
||||||
|
return computeListSt().item.height;
|
||||||
|
}
|
||||||
|
|
||||||
void PeerListBox::addSelectItem(
|
void PeerListBox::addSelectItem(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
anim::type animated) {
|
anim::type animated) {
|
||||||
|
@ -959,6 +962,7 @@ int PeerListContent::fullRowsCount() const {
|
||||||
|
|
||||||
not_null<PeerListRow*> PeerListContent::rowAt(int index) const {
|
not_null<PeerListRow*> PeerListContent::rowAt(int index) const {
|
||||||
Expects(index >= 0 && index < _rows.size());
|
Expects(index >= 0 && index < _rows.size());
|
||||||
|
|
||||||
return _rows[index].get();
|
return _rows[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1132,10 @@ int PeerListContent::resizeGetHeight(int newWidth) {
|
||||||
_aboveHeight = _aboveSearchWidget->height();
|
_aboveHeight = _aboveSearchWidget->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto labelTop = rowsTop() + qMax(1, shownRowsCount()) * _rowHeight;
|
const auto labelTop = rowsTop()
|
||||||
|
+ std::max(
|
||||||
|
shownRowsCount() * _rowHeight,
|
||||||
|
_controller->descriptionTopSkipMin());
|
||||||
const auto labelWidth = newWidth - 2 * st::contactsPadding.left();
|
const auto labelWidth = newWidth - 2 * st::contactsPadding.left();
|
||||||
if (_description) {
|
if (_description) {
|
||||||
_description->resizeToWidth(labelWidth);
|
_description->resizeToWidth(labelWidth);
|
||||||
|
|
|
@ -429,29 +429,30 @@ public:
|
||||||
virtual void restoreState(
|
virtual void restoreState(
|
||||||
std::unique_ptr<PeerListState> state);
|
std::unique_ptr<PeerListState> state);
|
||||||
|
|
||||||
virtual int contentWidth() const;
|
[[nodiscard]] virtual int contentWidth() const;
|
||||||
virtual rpl::producer<int> boxHeightValue() const;
|
[[nodiscard]] virtual rpl::producer<int> boxHeightValue() const;
|
||||||
|
[[nodiscard]] virtual int descriptionTopSkipMin() const;
|
||||||
|
|
||||||
bool isRowSelected(not_null<PeerListRow*> row) {
|
[[nodiscard]] bool isRowSelected(not_null<PeerListRow*> row) {
|
||||||
return delegate()->peerListIsRowChecked(row);
|
return delegate()->peerListIsRowChecked(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool searchInLocal() {
|
virtual bool searchInLocal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool hasComplexSearch() const;
|
[[nodiscard]] bool hasComplexSearch() const;
|
||||||
void search(const QString &query);
|
void search(const QString &query);
|
||||||
|
|
||||||
void peerListSearchAddRow(not_null<PeerData*> peer) override;
|
void peerListSearchAddRow(not_null<PeerData*> peer) override;
|
||||||
void peerListSearchRefreshRows() override;
|
void peerListSearchRefreshRows() override;
|
||||||
|
|
||||||
virtual bool respectSavedMessagesChat() const {
|
[[nodiscard]] virtual bool respectSavedMessagesChat() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual rpl::producer<int> onlineCountValue() const;
|
[[nodiscard]] virtual rpl::producer<int> onlineCountValue() const;
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_layers.h" // st::boxDividerLabel.
|
#include "styles/style_layers.h" // st::boxDividerLabel.
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_settings.h" // st::settingsDividerLabelPadding.
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
|
|
||||||
|
@ -54,27 +54,37 @@ using LinkData = Api::InviteLink;
|
||||||
|
|
||||||
class Controller final : public PeerListController {
|
class Controller final : public PeerListController {
|
||||||
public:
|
public:
|
||||||
Controller(not_null<PeerData*> peer, const LinkData &data);
|
Controller(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
not_null<UserData*> admin,
|
||||||
|
rpl::producer<LinkData> data);
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void loadMoreRows() override;
|
void loadMoreRows() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
Main::Session &session() const override;
|
Main::Session &session() const override;
|
||||||
|
|
||||||
//rpl::producer<int> boxHeightValue() const override;
|
rpl::producer<int> boxHeightValue() const override;
|
||||||
|
int descriptionTopSkipMin() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void appendSlice(const Api::JoinedByLinkSlice &slice);
|
void appendSlice(const Api::JoinedByLinkSlice &slice);
|
||||||
[[nodiscard]] object_ptr<Ui::RpWidget> prepareHeader();
|
void addHeaderBlock(not_null<Ui::VerticalLayout*> container);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<LinkData> dataValue() const;
|
||||||
|
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
LinkData _data;
|
rpl::variable<LinkData> _data;
|
||||||
|
|
||||||
|
QString _link;
|
||||||
|
bool _revoked = false;
|
||||||
|
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
std::optional<Api::JoinedByLinkUser> _lastUser;
|
std::optional<Api::JoinedByLinkUser> _lastUser;
|
||||||
bool _allLoaded = false;
|
bool _allLoaded = false;
|
||||||
|
|
||||||
Ui::RpWidget *_headerWidget = nullptr;
|
Ui::RpWidget *_headerWidget = nullptr;
|
||||||
|
rpl::variable<int> _addedHeight;
|
||||||
|
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
@ -99,24 +109,48 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddHeaderBlock(
|
[[nodiscard]] bool ClosingLinkBox(const LinkData &updated, bool revoked) {
|
||||||
not_null<Ui::VerticalLayout*> container,
|
return updated.link.isEmpty() || (!revoked && updated.revoked);
|
||||||
not_null<PeerData*> peer,
|
}
|
||||||
const LinkData &data,
|
|
||||||
TimeId now) {
|
Controller::Controller(
|
||||||
const auto link = data.link;
|
not_null<PeerData*> peer,
|
||||||
|
not_null<UserData*> admin,
|
||||||
|
rpl::producer<LinkData> data)
|
||||||
|
: _peer(peer)
|
||||||
|
, _data(LinkData{ .admin = admin })
|
||||||
|
, _api(&_peer->session().api().instance()) {
|
||||||
|
_data = std::move(data);
|
||||||
|
const auto current = _data.current();
|
||||||
|
_link = current.link;
|
||||||
|
_revoked = current.revoked;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<LinkData> Controller::dataValue() const {
|
||||||
|
return _data.value(
|
||||||
|
) | rpl::filter([=](const LinkData &data) {
|
||||||
|
return !ClosingLinkBox(data, _revoked);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::addHeaderBlock(not_null<Ui::VerticalLayout*> container) {
|
||||||
|
using namespace Settings;
|
||||||
|
|
||||||
|
const auto current = _data.current();
|
||||||
|
const auto link = current.link;
|
||||||
|
const auto admin = current.admin;
|
||||||
const auto weak = Ui::MakeWeak(container);
|
const auto weak = Ui::MakeWeak(container);
|
||||||
const auto copyLink = crl::guard(weak, [=] {
|
const auto copyLink = crl::guard(weak, [=] {
|
||||||
CopyInviteLink(link);
|
CopyInviteLink(link);
|
||||||
});
|
});
|
||||||
const auto shareLink = crl::guard(weak, [=] {
|
const auto shareLink = crl::guard(weak, [=] {
|
||||||
ShareInviteLinkBox(peer, link);
|
ShareInviteLinkBox(_peer, link);
|
||||||
});
|
});
|
||||||
const auto revokeLink = crl::guard(weak, [=] {
|
const auto revokeLink = crl::guard(weak, [=] {
|
||||||
RevokeLink(peer, data.admin, data.link);
|
RevokeLink(_peer, admin, link);
|
||||||
});
|
});
|
||||||
const auto editLink = crl::guard(weak, [=] {
|
const auto editLink = crl::guard(weak, [=] {
|
||||||
EditLink(peer, data);
|
EditLink(_peer, _data.current());
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto createMenu = [=] {
|
const auto createMenu = [=] {
|
||||||
|
@ -150,98 +184,198 @@ void AddHeaderBlock(
|
||||||
label->clicks(
|
label->clicks(
|
||||||
) | rpl::start_with_next(copyLink, label->lifetime());
|
) | rpl::start_with_next(copyLink, label->lifetime());
|
||||||
|
|
||||||
if (IsExpiredLink(data, now)) {
|
const auto reactivateWrap = container->add(
|
||||||
AddReactivateLinkButton(container, editLink);
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
} else {
|
container,
|
||||||
AddCopyShareLinkButtons(container, copyLink, shareLink);
|
object_ptr<Ui::VerticalLayout>(
|
||||||
}
|
container)));
|
||||||
}
|
const auto copyShareWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::VerticalLayout>(
|
||||||
|
container)));
|
||||||
|
|
||||||
|
AddReactivateLinkButton(reactivateWrap->entity(), editLink);
|
||||||
|
AddCopyShareLinkButtons(copyShareWrap->entity(), copyLink, shareLink);
|
||||||
|
|
||||||
|
AddSkip(container, st::inviteLinkJoinedRowPadding.bottom() * 2);
|
||||||
|
|
||||||
|
auto grayLabelText = dataValue(
|
||||||
|
) | rpl::map([=](const LinkData &data) {
|
||||||
|
const auto usageExpired = (data.usageLimit > 0)
|
||||||
|
&& (data.usageLimit <= data.usage);
|
||||||
|
return usageExpired
|
||||||
|
? tr::lng_group_invite_used_about()
|
||||||
|
: tr::lng_group_invite_expires_at(
|
||||||
|
lt_when,
|
||||||
|
rpl::single(langDateTime(
|
||||||
|
base::unixtime::parse(data.expireDate))));
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
|
||||||
|
const auto redLabelWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::DividerLabel>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::DividerLabel>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
tr::lng_group_invite_expired_about(),
|
||||||
|
st::boxAttentionDividerLabel),
|
||||||
|
st::settingsDividerLabelPadding)));
|
||||||
|
const auto grayLabelWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::DividerLabel>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::DividerLabel>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
std::move(grayLabelText),
|
||||||
|
st::boxDividerLabel),
|
||||||
|
st::settingsDividerLabelPadding)));
|
||||||
|
const auto justDividerWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::BoxContentDivider>(container)));
|
||||||
|
AddSkip(container);
|
||||||
|
|
||||||
|
dataValue(
|
||||||
|
) | rpl::start_with_next([=](const LinkData &data) {
|
||||||
|
const auto now = base::unixtime::now();
|
||||||
|
const auto expired = IsExpiredLink(data, now);
|
||||||
|
reactivateWrap->toggle(expired, anim::type::instant);
|
||||||
|
copyShareWrap->toggle(!expired, anim::type::instant);
|
||||||
|
|
||||||
void AddHeader(
|
|
||||||
not_null<Ui::VerticalLayout*> container,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const LinkData &data,
|
|
||||||
TimeId now) {
|
|
||||||
using namespace Settings;
|
|
||||||
if (!data.revoked && !data.permanent) {
|
|
||||||
AddHeaderBlock(container, peer, data, now);
|
|
||||||
AddSkip(container, st::inviteLinkJoinedRowPadding.bottom() * 2);
|
|
||||||
const auto timeExpired = (data.expireDate > 0)
|
const auto timeExpired = (data.expireDate > 0)
|
||||||
&& (data.expireDate <= now);
|
&& (data.expireDate <= now);
|
||||||
const auto usageExpired = (data.usageLimit > 0)
|
const auto usageExpired = (data.usageLimit > 0)
|
||||||
&& (data.usageLimit <= data.usage);
|
&& (data.usageLimit <= data.usage);
|
||||||
if (data.expireDate > 0 || usageExpired) {
|
redLabelWrap->toggle(timeExpired, anim::type::instant);
|
||||||
container->add(object_ptr<Ui::DividerLabel>(
|
grayLabelWrap->toggle(
|
||||||
container,
|
!timeExpired && (data.expireDate > 0 || usageExpired),
|
||||||
object_ptr<Ui::FlatLabel>(
|
anim::type::instant);
|
||||||
container,
|
justDividerWrap->toggle(
|
||||||
(timeExpired
|
!data.expireDate && !expired,
|
||||||
? tr::lng_group_invite_expired_about()
|
anim::type::instant);
|
||||||
: usageExpired
|
}, lifetime());
|
||||||
? tr::lng_group_invite_used_about()
|
}
|
||||||
: tr::lng_group_invite_expires_at(
|
|
||||||
lt_when,
|
void Controller::prepare() {
|
||||||
rpl::single(langDateTime(
|
using namespace Settings;
|
||||||
base::unixtime::parse(data.expireDate))))),
|
|
||||||
(timeExpired
|
auto header = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
||||||
? st::boxAttentionDividerLabel
|
const auto container = header.data();
|
||||||
: st::boxDividerLabel)),
|
|
||||||
st::settingsDividerLabelPadding));
|
const auto current = _data.current();
|
||||||
} else {
|
if (!current.revoked && !current.permanent) {
|
||||||
AddDivider(container);
|
addHeaderBlock(container);
|
||||||
}
|
|
||||||
AddSkip(container);
|
|
||||||
}
|
}
|
||||||
AddSubsectionTitle(
|
AddSubsectionTitle(
|
||||||
container,
|
container,
|
||||||
tr::lng_group_invite_created_by());
|
tr::lng_group_invite_created_by());
|
||||||
AddSinglePeerRow(
|
AddSinglePeerRow(
|
||||||
container,
|
container,
|
||||||
data.admin,
|
current.admin,
|
||||||
rpl::single(langDateTime(base::unixtime::parse(data.date))));
|
rpl::single(langDateTime(base::unixtime::parse(current.date))));
|
||||||
AddSkip(container, st::membersMarginBottom);
|
AddSkip(container, st::membersMarginBottom);
|
||||||
}
|
|
||||||
|
|
||||||
Controller::Controller(not_null<PeerData*> peer, const LinkData &data)
|
const auto listHeaderWrap = container->add(
|
||||||
: _peer(peer)
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
, _data(data)
|
container,
|
||||||
, _api(&_peer->session().api().instance()) {
|
object_ptr<Ui::VerticalLayout>(
|
||||||
}
|
container)));
|
||||||
|
const auto listHeader = listHeaderWrap->entity();
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> Controller::prepareHeader() {
|
// Make this container occupy full width.
|
||||||
using namespace Settings;
|
listHeader->add(object_ptr<Ui::RpWidget>(listHeader));
|
||||||
|
|
||||||
const auto now = base::unixtime::now();
|
AddDivider(listHeader);
|
||||||
|
AddSkip(listHeader);
|
||||||
|
|
||||||
auto result = object_ptr<Ui::VerticalLayout>((QWidget*)nullptr);
|
auto listHeaderText = dataValue(
|
||||||
const auto container = result.data();
|
) | rpl::map([=](const LinkData &data) {
|
||||||
AddHeader(container, _peer, _data, now);
|
const auto now = base::unixtime::now();
|
||||||
AddDivider(container);
|
const auto timeExpired = (data.expireDate > 0)
|
||||||
AddSkip(container);
|
&& (data.expireDate <= now);
|
||||||
AddSubsectionTitle(
|
if (!data.usage && data.usageLimit > 0 && !timeExpired) {
|
||||||
container,
|
auto description = object_ptr<Ui::FlatLabel>(
|
||||||
(_data.usage
|
nullptr,
|
||||||
|
tr::lng_group_invite_can_join_via_link(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
data.usageLimit),
|
||||||
|
computeListSt().about);
|
||||||
|
if (!delegate()->peerListFullRowsCount()) {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
_addedHeight = description->heightValue(
|
||||||
|
) | rpl::map(_1
|
||||||
|
+ st::membersAboutLimitPadding.top()
|
||||||
|
+ st::membersAboutLimitPadding.bottom());
|
||||||
|
}
|
||||||
|
delegate()->peerListSetDescription(std::move(description));
|
||||||
|
} else {
|
||||||
|
_addedHeight = std::max(
|
||||||
|
data.usage,
|
||||||
|
delegate()->peerListFullRowsCount()
|
||||||
|
) * computeListSt().item.height;
|
||||||
|
delegate()->peerListSetDescription(nullptr);
|
||||||
|
}
|
||||||
|
listHeaderWrap->toggle(
|
||||||
|
data.usage || (data.usageLimit > 0 && !timeExpired),
|
||||||
|
anim::type::instant);
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
return data.usage
|
||||||
? tr::lng_group_invite_joined(
|
? tr::lng_group_invite_joined(
|
||||||
lt_count,
|
lt_count,
|
||||||
rpl::single(float64(_data.usage)))
|
rpl::single(float64(data.usage)))
|
||||||
: tr::lng_group_invite_no_joined()));
|
: tr::lng_group_invite_no_joined();
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
_headerWidget = result.data();
|
const auto listTitle = AddSubsectionTitle(
|
||||||
return result;
|
listHeader,
|
||||||
}
|
std::move(listHeaderText));
|
||||||
|
auto remainingText = dataValue(
|
||||||
void Controller::prepare() {
|
) | rpl::map([=](const LinkData &data) {
|
||||||
delegate()->peerListSetAboveWidget(prepareHeader());
|
return !data.usageLimit
|
||||||
if (!_data.usage && _data.usageLimit > 0) {
|
? QString()
|
||||||
setDescriptionText(
|
: tr::lng_group_invite_remaining(
|
||||||
tr::lng_group_invite_can_join_via_link(
|
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_count,
|
lt_count_decimal,
|
||||||
_data.usageLimit));
|
std::max(data.usageLimit - data.usage, 0));
|
||||||
}
|
});
|
||||||
_allLoaded = (_data.usage == 0);
|
const auto remaining = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
listHeader,
|
||||||
|
std::move(remainingText),
|
||||||
|
st::settingsSubsectionTitleRight);
|
||||||
|
dataValue(
|
||||||
|
) | rpl::start_with_next([=](const LinkData &data) {
|
||||||
|
remaining->setTextColorOverride(
|
||||||
|
(data.usageLimit && (data.usageLimit <= data.usage)
|
||||||
|
? std::make_optional(st::boxTextFgError->c)
|
||||||
|
: std::nullopt));
|
||||||
|
if (!data.usage && data.usageLimit > 0) {
|
||||||
|
remaining->hide();
|
||||||
|
} else {
|
||||||
|
remaining->show();
|
||||||
|
}
|
||||||
|
}, remaining->lifetime());
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
listTitle->positionValue(),
|
||||||
|
remaining->widthValue(),
|
||||||
|
listHeader->widthValue()
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
QPoint position,
|
||||||
|
int width,
|
||||||
|
int outerWidth) {
|
||||||
|
remaining->moveToRight(position.x(), position.y(), outerWidth);
|
||||||
|
}, remaining->lifetime());
|
||||||
|
|
||||||
|
_headerWidget = header.data();
|
||||||
|
|
||||||
|
delegate()->peerListSetAboveWidget(std::move(header));
|
||||||
|
_allLoaded = (current.usage == 0);
|
||||||
|
|
||||||
const auto &inviteLinks = _peer->session().api().inviteLinks();
|
const auto &inviteLinks = _peer->session().api().inviteLinks();
|
||||||
const auto slice = inviteLinks.joinedFirstSliceLoaded(_peer, _data.link);
|
const auto slice = inviteLinks.joinedFirstSliceLoaded(_peer, _link);
|
||||||
if (slice) {
|
if (slice) {
|
||||||
appendSlice(*slice);
|
appendSlice(*slice);
|
||||||
}
|
}
|
||||||
|
@ -254,7 +388,7 @@ void Controller::loadMoreRows() {
|
||||||
}
|
}
|
||||||
_requestId = _api.request(MTPmessages_GetChatInviteImporters(
|
_requestId = _api.request(MTPmessages_GetChatInviteImporters(
|
||||||
_peer->input,
|
_peer->input,
|
||||||
MTP_string(_data.link),
|
MTP_string(_link),
|
||||||
MTP_int(_lastUser ? _lastUser->date : 0),
|
MTP_int(_lastUser ? _lastUser->date : 0),
|
||||||
_lastUser ? _lastUser->user->inputUser : MTP_inputUserEmpty(),
|
_lastUser ? _lastUser->user->inputUser : MTP_inputUserEmpty(),
|
||||||
MTP_int(_lastUser ? kPerPage : kFirstPage)
|
MTP_int(_lastUser ? kPerPage : kFirstPage)
|
||||||
|
@ -276,6 +410,12 @@ void Controller::appendSlice(const Api::JoinedByLinkSlice &slice) {
|
||||||
std::make_unique<PeerListRow>(user.user));
|
std::make_unique<PeerListRow>(user.user));
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
|
if (delegate()->peerListFullRowsCount() > 0) {
|
||||||
|
_addedHeight = std::max(
|
||||||
|
_data.current().usage,
|
||||||
|
delegate()->peerListFullRowsCount()
|
||||||
|
) * computeListSt().item.height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::rowClicked(not_null<PeerListRow*> row) {
|
void Controller::rowClicked(not_null<PeerListRow*> row) {
|
||||||
|
@ -286,11 +426,25 @@ Main::Session &Controller::session() const {
|
||||||
return _peer->session();
|
return _peer->session();
|
||||||
}
|
}
|
||||||
|
|
||||||
//rpl::producer<int> Controller::boxHeightValue() const {
|
rpl::producer<int> Controller::boxHeightValue() const {
|
||||||
// Expects(_headerWidget != nullptr);
|
Expects(_headerWidget != nullptr);
|
||||||
//
|
|
||||||
// return _headerWidget->heightValue();
|
return rpl::combine(
|
||||||
//}
|
_headerWidget->heightValue(),
|
||||||
|
_addedHeight.value()
|
||||||
|
) | rpl::map([=](int header, int description) {
|
||||||
|
const auto wrapped = description
|
||||||
|
? (computeListSt().padding.top()
|
||||||
|
+ description
|
||||||
|
+ computeListSt().padding.bottom())
|
||||||
|
: 0;
|
||||||
|
return std::min(header + wrapped, st::boxMaxListHeight);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int Controller::descriptionTopSkipMin() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SingleRowController::SingleRowController(
|
SingleRowController::SingleRowController(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
@ -685,35 +839,44 @@ void RevokeLink(
|
||||||
void ShowInviteLinkBox(
|
void ShowInviteLinkBox(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const Api::InviteLink &link) {
|
const Api::InviteLink &link) {
|
||||||
const auto now = base::unixtime::now();
|
const auto admin = link.admin;
|
||||||
auto initBox = [=](not_null<Ui::BoxContent*> box) {
|
const auto linkText = link.link;
|
||||||
box->setTitle(IsExpiredLink(link, now)
|
const auto revoked = link.revoked;
|
||||||
? tr::lng_manage_peer_link_expired()
|
|
||||||
: (link.permanent && !link.revoked)
|
auto updates = peer->session().api().inviteLinks().updates(
|
||||||
? tr::lng_manage_peer_link_permanent()
|
peer,
|
||||||
: tr::lng_manage_peer_link_invite());
|
admin
|
||||||
peer->session().api().inviteLinks().updates(
|
) | rpl::filter([=](const Api::InviteLinkUpdate &update) {
|
||||||
peer,
|
return (update.was == linkText);
|
||||||
link.admin
|
}) | rpl::map([=](const Api::InviteLinkUpdate &update) {
|
||||||
) | rpl::start_with_next([=](const Api::InviteLinkUpdate &update) {
|
return update.now ? *update.now : LinkData{ .admin = admin };
|
||||||
if (update.was == link.link
|
});
|
||||||
&& (!update.now || (!link.revoked && update.now->revoked))) {
|
auto data = revoked
|
||||||
|
? rpl::single(link) | rpl::type_erased()
|
||||||
|
: rpl::single(link) | rpl::then(std::move(updates));
|
||||||
|
|
||||||
|
auto initBox = [=, data = rpl::duplicate(data)](
|
||||||
|
not_null<Ui::BoxContent*> box) {
|
||||||
|
rpl::duplicate(
|
||||||
|
data
|
||||||
|
) | rpl::start_with_next([=](const LinkData &link) {
|
||||||
|
if (ClosingLinkBox(link, revoked)) {
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const auto now = base::unixtime::now();
|
||||||
|
box->setTitle(IsExpiredLink(link, now)
|
||||||
|
? tr::lng_manage_peer_link_expired()
|
||||||
|
: (link.permanent && !link.revoked)
|
||||||
|
? tr::lng_manage_peer_link_permanent()
|
||||||
|
: tr::lng_manage_peer_link_invite());
|
||||||
}, box->lifetime());
|
}, box->lifetime());
|
||||||
|
|
||||||
box->addButton(tr::lng_about_done(), [=] { box->closeBox(); });
|
box->addButton(tr::lng_about_done(), [=] { box->closeBox(); });
|
||||||
};
|
};
|
||||||
if (link.usage > 0) {
|
Ui::show(
|
||||||
Ui::show(
|
Box<PeerListBox>(
|
||||||
Box<PeerListBox>(
|
std::make_unique<Controller>(peer, link.admin, std::move(data)),
|
||||||
std::make_unique<Controller>(peer, link),
|
std::move(initBox)),
|
||||||
std::move(initBox)),
|
Ui::LayerOption::KeepOther);
|
||||||
Ui::LayerOption::KeepOther);
|
|
||||||
} else {
|
|
||||||
Ui::show(Box([=](not_null<Ui::GenericBox*> box) {
|
|
||||||
initBox(box);
|
|
||||||
const auto container = box->verticalLayout();
|
|
||||||
AddHeader(container, peer, link, now);
|
|
||||||
}), Ui::LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,9 @@ settingsSubsectionTitle: FlatLabel(defaultFlatLabel) {
|
||||||
textFg: windowActiveTextFg;
|
textFg: windowActiveTextFg;
|
||||||
minWidth: 240px;
|
minWidth: 240px;
|
||||||
}
|
}
|
||||||
|
settingsSubsectionTitleRight: FlatLabel(settingsSubsectionTitle) {
|
||||||
|
minWidth: 0px;
|
||||||
|
}
|
||||||
settingsSubsectionTitlePadding: margins(22px, 7px, 10px, 9px);
|
settingsSubsectionTitlePadding: margins(22px, 7px, 10px, 9px);
|
||||||
settingsBackgroundPadding: margins(22px, 11px, 10px, 12px);
|
settingsBackgroundPadding: margins(22px, 11px, 10px, 12px);
|
||||||
settingsTileSkip: 15px;
|
settingsTileSkip: 15px;
|
||||||
|
|
Loading…
Add table
Reference in a new issue