Start PeerShortInfoBox for small in-box profiles.
This commit is contained in:
parent
49b28ac695
commit
61ac7e6c1d
|
@ -182,6 +182,10 @@ PRIVATE
|
|||
boxes/peers/edit_peer_requests_box.h
|
||||
boxes/peers/edit_peer_type_box.cpp
|
||||
boxes/peers/edit_peer_type_box.h
|
||||
boxes/peers/peer_short_info_box.cpp
|
||||
boxes/peers/peer_short_info_box.h
|
||||
boxes/peers/prepare_short_info_box.cpp
|
||||
boxes/peers/prepare_short_info_box.h
|
||||
boxes/about_box.cpp
|
||||
boxes/about_box.h
|
||||
boxes/about_sponsored_box.cpp
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration
|
||||
#include "boxes/peers/edit_peer_invite_link.h" // PrepareRequestedRowStatus
|
||||
#include "boxes/peers/prepare_short_info_box.h" // PrepareShortInfoBox
|
||||
#include "history/view/history_view_requests_bar.h" // kRecentRequestsLimit
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_user.h"
|
||||
|
@ -354,7 +355,9 @@ void RequestsBoxController::refreshDescription() {
|
|||
}
|
||||
|
||||
void RequestsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
_navigation->showPeerInfo(row->peer());
|
||||
_navigation->parentController()->show(PrepareShortInfoBox(
|
||||
row->peer(),
|
||||
_navigation));
|
||||
}
|
||||
|
||||
void RequestsBoxController::rowElementClicked(
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/peers/peer_short_info_box.h"
|
||||
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "media/streaming/media_streaming_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
PeerShortInfoBox::PeerShortInfoBox(
|
||||
QWidget*,
|
||||
PeerShortInfoType type,
|
||||
rpl::producer<PeerShortInfoFields> fields,
|
||||
rpl::producer<QString> status,
|
||||
rpl::producer<PeerShortInfoUserpic> userpic)
|
||||
: _type(type)
|
||||
, _fields(std::move(fields))
|
||||
, _name(this, nameValue(), st::shortInfoName)
|
||||
, _status(this, std::move(status), st::shortInfoStatus) {
|
||||
std::move(
|
||||
userpic
|
||||
) | rpl::start_with_next([=](PeerShortInfoUserpic &&value) {
|
||||
applyUserpic(std::move(value));
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
PeerShortInfoBox::~PeerShortInfoBox() = default;
|
||||
|
||||
rpl::producer<> PeerShortInfoBox::openRequests() const {
|
||||
return _openRequests.events();
|
||||
}
|
||||
|
||||
void PeerShortInfoBox::prepare() {
|
||||
addButton(tr::lng_close(), [=] { closeBox(); });
|
||||
|
||||
// Perhaps a new lang key should be added for opening a group.
|
||||
addLeftButton((_type == PeerShortInfoType::User)
|
||||
? tr::lng_profile_send_message()
|
||||
: (_type == PeerShortInfoType::Group)
|
||||
? tr::lng_view_button_group()
|
||||
: tr::lng_profile_view_channel(), [=] { _openRequests.fire({}); });
|
||||
|
||||
setNoContentMargin(true);
|
||||
setDimensions(st::shortInfoWidth, st::shortInfoWidth);
|
||||
}
|
||||
|
||||
RectParts PeerShortInfoBox::customCornersFilling() {
|
||||
return RectPart::FullTop;
|
||||
}
|
||||
|
||||
void PeerShortInfoBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
}
|
||||
|
||||
void PeerShortInfoBox::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
|
||||
const auto coverSize = st::shortInfoWidth;
|
||||
if (_userpicImage.isNull()) {
|
||||
const auto size = coverSize * style::DevicePixelRatio();
|
||||
auto image = QImage(size, size, QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
Images::prepareRound(
|
||||
image,
|
||||
ImageRoundRadius::Small,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
p.drawImage(QRect(0, 0, coverSize, coverSize), _userpicImage);
|
||||
}
|
||||
|
||||
rpl::producer<QString> PeerShortInfoBox::nameValue() const {
|
||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
||||
return fields.name;
|
||||
}) | rpl::distinct_until_changed();
|
||||
}
|
||||
|
||||
void PeerShortInfoBox::applyUserpic(PeerShortInfoUserpic &&value) {
|
||||
if (!value.photo.isNull()
|
||||
&& _userpicImage.cacheKey() != value.photo.cacheKey()) {
|
||||
_userpicImage = std::move(value.photo);
|
||||
update();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Media::Streaming {
|
||||
class Document;
|
||||
class Instance;
|
||||
} // namespace Media::Streaming
|
||||
|
||||
enum class PeerShortInfoType {
|
||||
User,
|
||||
Group,
|
||||
Channel,
|
||||
};
|
||||
|
||||
struct PeerShortInfoFields {
|
||||
QString name;
|
||||
QString phone;
|
||||
QString link;
|
||||
TextWithEntities about;
|
||||
QString username;
|
||||
};
|
||||
|
||||
struct PeerShortInfoUserpic {
|
||||
int index = 0;
|
||||
int count = 0;
|
||||
|
||||
QImage photo;
|
||||
float64 photoLoadingProgress = 0.;
|
||||
std::shared_ptr<Media::Streaming::Document> videoDocument;
|
||||
};
|
||||
|
||||
class PeerShortInfoBox final : public Ui::BoxContent {
|
||||
public:
|
||||
PeerShortInfoBox(
|
||||
QWidget*,
|
||||
PeerShortInfoType type,
|
||||
rpl::producer<PeerShortInfoFields> fields,
|
||||
rpl::producer<QString> status,
|
||||
rpl::producer<PeerShortInfoUserpic> userpic);
|
||||
~PeerShortInfoBox();
|
||||
|
||||
[[nodiscard]] rpl::producer<> openRequests() const;
|
||||
|
||||
private:
|
||||
void prepare() override;
|
||||
RectParts customCornersFilling() override;
|
||||
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
[[nodiscard]] rpl::producer<QString> nameValue() const;
|
||||
void applyUserpic(PeerShortInfoUserpic &&value);
|
||||
|
||||
const PeerShortInfoType _type = PeerShortInfoType::User;
|
||||
|
||||
rpl::variable<PeerShortInfoFields> _fields;
|
||||
|
||||
object_ptr<Ui::FlatLabel> _name;
|
||||
object_ptr<Ui::FlatLabel> _status;
|
||||
|
||||
QImage _userpicImage;
|
||||
std::unique_ptr<Media::Streaming::Instance> _videoInstance;
|
||||
|
||||
rpl::event_stream<> _openRequests;
|
||||
|
||||
};
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/peers/prepare_short_info_box.h"
|
||||
|
||||
#include "boxes/peers/peer_short_info_box.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_streaming.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct UserpicState {
|
||||
PeerShortInfoUserpic current;
|
||||
std::shared_ptr<Data::CloudImageView> userpicView;
|
||||
std::shared_ptr<Data::PhotoMedia> photoView;
|
||||
InMemoryKey userpicKey;
|
||||
PhotoId photoId = 0;
|
||||
bool waitingFull = false;
|
||||
bool waitingLoad = false;
|
||||
};
|
||||
|
||||
void GenerateImage(
|
||||
not_null<UserpicState*> state,
|
||||
QImage image,
|
||||
bool blurred = false) {
|
||||
using namespace Images;
|
||||
const auto size = st::shortInfoWidth;
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
const auto options = Option::Smooth
|
||||
| Option::RoundedSmall
|
||||
| Option::RoundedTopLeft
|
||||
| Option::RoundedTopRight
|
||||
| (blurred ? Option::Blurred : Option());
|
||||
state->current.photo = Images::prepare(
|
||||
std::move(image),
|
||||
size * factor,
|
||||
size * factor,
|
||||
options,
|
||||
size * factor,
|
||||
size * factor);
|
||||
}
|
||||
|
||||
void GenerateImage(
|
||||
not_null<UserpicState*> state,
|
||||
not_null<Image*> image,
|
||||
bool blurred = false) {
|
||||
GenerateImage(state, image->original(), blurred);
|
||||
}
|
||||
|
||||
void ProcessUserpic(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<UserpicState*> state) {
|
||||
state->current.videoDocument = nullptr;
|
||||
state->userpicKey = peer->userpicUniqueKey(state->userpicView);
|
||||
if (!state->userpicView) {
|
||||
GenerateImage(
|
||||
state,
|
||||
peer->generateUserpicImage(
|
||||
state->userpicView,
|
||||
st::shortInfoWidth * style::DevicePixelRatio(),
|
||||
ImageRoundRadius::None),
|
||||
false);
|
||||
state->photoView = nullptr;
|
||||
return;
|
||||
}
|
||||
peer->loadUserpic();
|
||||
state->current.photoLoadingProgress = 0.;
|
||||
const auto image = state->userpicView->image();
|
||||
if (!image) {
|
||||
state->current.photo = QImage();
|
||||
state->waitingLoad = true;
|
||||
return;
|
||||
}
|
||||
GenerateImage(state, image, true);
|
||||
state->photoView = nullptr;
|
||||
}
|
||||
|
||||
void ProcessFullPhoto(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<UserpicState*> state,
|
||||
not_null<PhotoData*> photo) {
|
||||
using PhotoSize = Data::PhotoSize;
|
||||
const auto video = photo->hasVideo();
|
||||
const auto origin = peer->userpicPhotoOrigin();
|
||||
const auto was = base::take(state->current.videoDocument);
|
||||
const auto view = photo->createMediaView();
|
||||
if (!video) {
|
||||
view->wanted(PhotoSize::Large, origin);
|
||||
}
|
||||
if (const auto image = view->image(PhotoSize::Large)) {
|
||||
GenerateImage(state, image);
|
||||
state->photoView = nullptr;
|
||||
state->current.photoLoadingProgress = 1.;
|
||||
} else {
|
||||
if (const auto thumbnail = view->image(PhotoSize::Thumbnail)) {
|
||||
GenerateImage(state, thumbnail, true);
|
||||
} else if (const auto small = view->image(PhotoSize::Small)) {
|
||||
GenerateImage(state, small, true);
|
||||
} else {
|
||||
ProcessUserpic(peer, state);
|
||||
if (state->current.photo.isNull()) {
|
||||
if (const auto blurred = view->thumbnailInline()) {
|
||||
GenerateImage(state, blurred, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
state->waitingLoad = !video;
|
||||
state->photoView = view;
|
||||
state->current.photoLoadingProgress = photo->progress();
|
||||
}
|
||||
if (!video) {
|
||||
return;
|
||||
}
|
||||
state->current.videoDocument = peer->owner().streaming().sharedDocument(
|
||||
photo,
|
||||
origin);
|
||||
state->photoView = nullptr;
|
||||
state->current.photoLoadingProgress = 1.;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
[[nodiscard]] rpl::producer<PeerShortInfoFields> FieldsValue(
|
||||
not_null<PeerData*> peer) {
|
||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||
return peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
(UpdateFlag::Name
|
||||
| UpdateFlag::PhoneNumber
|
||||
| UpdateFlag::Username
|
||||
| UpdateFlag::About)
|
||||
) | rpl::map([=] {
|
||||
const auto user = peer->asUser();
|
||||
const auto username = peer->userName();
|
||||
return PeerShortInfoFields{
|
||||
.name = peer->name,
|
||||
.phone = user ? Ui::FormatPhone(user->phone()) : QString(),
|
||||
.link = ((user || username.isEmpty())
|
||||
? QString()
|
||||
: peer->session().createInternalLinkFull(username)),
|
||||
.about = Info::Profile::AboutWithEntities(peer, peer->about()),
|
||||
.username = ((user && !username.isEmpty())
|
||||
? ('@' + username)
|
||||
: QString())
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<QString> StatusValue(not_null<PeerData*> peer) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
const auto now = base::unixtime::now();
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
const auto timer = lifetime.make_state<base::Timer>();
|
||||
const auto push = [=] {
|
||||
consumer.put_next(Data::OnlineText(user, now));
|
||||
timer->callOnce(Data::OnlineChangeTimeout(user, now));
|
||||
};
|
||||
timer->setCallback(push);
|
||||
push();
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
return peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Data::PeerUpdate::Flag::Members
|
||||
) | rpl::map([=] {
|
||||
const auto chat = peer->asChat();
|
||||
const auto channel = peer->asChannel();
|
||||
const auto count = std::max({
|
||||
chat ? chat->count : channel->membersCount(),
|
||||
chat ? int(chat->participants.size()) : 0,
|
||||
0,
|
||||
});
|
||||
return (chat && !chat->amIn())
|
||||
? tr::lng_chat_status_unaccessible(tr::now)
|
||||
: (count > 0)
|
||||
? ((channel && channel->isBroadcast())
|
||||
? tr::lng_chat_status_subscribers(
|
||||
tr::now,
|
||||
lt_count_decimal,
|
||||
count)
|
||||
: tr::lng_chat_status_members(
|
||||
tr::now,
|
||||
lt_count_decimal,
|
||||
count))
|
||||
: ((channel && channel->isBroadcast())
|
||||
? tr::lng_channel_status(tr::now)
|
||||
: tr::lng_group_status(tr::now));
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<PeerShortInfoUserpic> UserpicValue(
|
||||
not_null<PeerData*> peer) {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
const auto state = lifetime.make_state<UserpicState>();
|
||||
const auto push = [=] {
|
||||
state->waitingLoad = false;
|
||||
const auto nowPhotoId = peer->userpicPhotoId();
|
||||
const auto photo = (nowPhotoId
|
||||
&& (nowPhotoId != PeerData::kUnknownPhotoId)
|
||||
&& (state->photoId != nowPhotoId || state->photoView))
|
||||
? peer->owner().photo(nowPhotoId).get()
|
||||
: nullptr;
|
||||
state->waitingFull = !(state->photoId == nowPhotoId)
|
||||
&& ((nowPhotoId == PeerData::kUnknownPhotoId)
|
||||
|| (nowPhotoId && photo->isNull()));
|
||||
if (state->waitingFull) {
|
||||
peer->updateFullForced();
|
||||
}
|
||||
const auto oldPhotoId = state->waitingFull
|
||||
? state->photoId
|
||||
: std::exchange(state->photoId, nowPhotoId);
|
||||
const auto changedPhotoId = (state->photoId != oldPhotoId);
|
||||
const auto changedUserpic = (state->userpicKey
|
||||
!= peer->userpicUniqueKey(state->userpicView));
|
||||
if (!changedPhotoId
|
||||
&& !changedUserpic
|
||||
&& !state->photoView
|
||||
&& (!state->current.photo.isNull()
|
||||
|| state->current.videoDocument)) {
|
||||
return;
|
||||
} else if (photo && !photo->isNull()) {
|
||||
ProcessFullPhoto(peer, state, photo);
|
||||
} else {
|
||||
ProcessUserpic(peer, state);
|
||||
}
|
||||
consumer.put_next_copy(state->current);
|
||||
};
|
||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||
peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
UpdateFlag::Photo | UpdateFlag::FullInfo
|
||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||
return (update.flags & UpdateFlag::Photo) || state->waitingFull;
|
||||
}) | rpl::start_with_next([=] {
|
||||
push();
|
||||
}, lifetime);
|
||||
|
||||
peer->session().downloaderTaskFinished(
|
||||
) | rpl::filter([=] {
|
||||
return state->waitingLoad
|
||||
&& (state->photoView
|
||||
? (!!state->photoView->image(Data::PhotoSize::Large))
|
||||
: (state->userpicView && state->userpicView->image()));
|
||||
}) | rpl::start_with_next([=] {
|
||||
push();
|
||||
}, lifetime);
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
object_ptr<Ui::BoxContent> PrepareShortInfoBox(
|
||||
not_null<PeerData*> peer,
|
||||
Fn<void()> open) {
|
||||
const auto type = peer->isUser()
|
||||
? PeerShortInfoType::User
|
||||
: peer->isBroadcast()
|
||||
? PeerShortInfoType::Channel
|
||||
: PeerShortInfoType::Group;
|
||||
auto result = Box<PeerShortInfoBox>(
|
||||
type,
|
||||
FieldsValue(peer),
|
||||
StatusValue(peer),
|
||||
UserpicValue(peer));
|
||||
|
||||
result->openRequests(
|
||||
) | rpl::start_with_next(open, result->lifetime());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
object_ptr<Ui::BoxContent> PrepareShortInfoBox(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<Window::SessionNavigation*> navigation) {
|
||||
return PrepareShortInfoBox(
|
||||
peer,
|
||||
[=] { navigation->showPeerHistory(peer); });
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
class PeerData;
|
||||
|
||||
namespace Ui {
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
class SessionNavigation;
|
||||
} // namespace Window
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> PrepareShortInfoBox(
|
||||
not_null<PeerData*> peer,
|
||||
Fn<void()> open);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::BoxContent> PrepareShortInfoBox(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<Window::SessionNavigation*> navigation);
|
|
@ -952,3 +952,9 @@ infoAboutGigagroup: FlatLabel(defaultFlatLabel) {
|
|||
|
||||
infoScrollDateHideTimeout: historyScrollDateHideTimeout;
|
||||
infoDateFadeDuration: historyDateFadeDuration;
|
||||
|
||||
shortInfoName: FlatLabel(defaultFlatLabel) {
|
||||
}
|
||||
shortInfoStatus: FlatLabel(defaultFlatLabel) {
|
||||
}
|
||||
shortInfoWidth: 336px;
|
||||
|
|
|
@ -74,7 +74,7 @@ rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
|
|||
UpdateFlag::Name
|
||||
) | rpl::map([=] {
|
||||
return peer->name;
|
||||
}) | Ui::Text::ToWithEntities();;
|
||||
}) | Ui::Text::ToWithEntities();
|
||||
}
|
||||
|
||||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
||||
|
@ -113,7 +113,9 @@ rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
|
|||
}) | Ui::Text::ToWithEntities();
|
||||
}
|
||||
|
||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
||||
TextWithEntities AboutWithEntities(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &value) {
|
||||
auto flags = TextParseLinks | TextParseMentions;
|
||||
const auto user = peer->asUser();
|
||||
const auto isBot = user && user->isBot();
|
||||
|
@ -125,15 +127,19 @@ rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
|||
const auto stripExternal = peer->isChat()
|
||||
|| peer->isMegagroup()
|
||||
|| (user && !isBot);
|
||||
auto result = TextWithEntities{ value };
|
||||
TextUtilities::ParseEntities(result, flags);
|
||||
if (stripExternal) {
|
||||
StripExternalLinks(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
||||
return PlainAboutValue(
|
||||
peer
|
||||
) | Ui::Text::ToWithEntities(
|
||||
) | rpl::map([=](TextWithEntities &&text) {
|
||||
TextUtilities::ParseEntities(text, flags);
|
||||
if (stripExternal) {
|
||||
StripExternalLinks(text);
|
||||
}
|
||||
return std::move(text);
|
||||
) | rpl::map([peer](const QString &value) {
|
||||
return AboutWithEntities(peer, value);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,9 @@ rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer);
|
|||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user);
|
||||
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user);
|
||||
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user);
|
||||
[[nodiscard]] TextWithEntities AboutWithEntities(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &value);
|
||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer);
|
||||
rpl::producer<QString> LinkValue(not_null<PeerData*> peer);
|
||||
rpl::producer<const ChannelLocation*> LocationValue(
|
||||
|
|
Loading…
Reference in New Issue