mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Start PeerShortInfoBox for small in-box profiles.
This commit is contained in:
parent
49b28ac695
commit
61ac7e6c1d
9 changed files with 529 additions and 10 deletions
|
@ -182,6 +182,10 @@ PRIVATE
|
||||||
boxes/peers/edit_peer_requests_box.h
|
boxes/peers/edit_peer_requests_box.h
|
||||||
boxes/peers/edit_peer_type_box.cpp
|
boxes/peers/edit_peer_type_box.cpp
|
||||||
boxes/peers/edit_peer_type_box.h
|
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.cpp
|
||||||
boxes/about_box.h
|
boxes/about_box.h
|
||||||
boxes/about_sponsored_box.cpp
|
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/peer_list_controllers.h"
|
||||||
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration
|
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration
|
||||||
#include "boxes/peers/edit_peer_invite_link.h" // PrepareRequestedRowStatus
|
#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 "history/view/history_view_requests_bar.h" // kRecentRequestsLimit
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
@ -354,7 +355,9 @@ void RequestsBoxController::refreshDescription() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
void RequestsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
_navigation->showPeerInfo(row->peer());
|
_navigation->parentController()->show(PrepareShortInfoBox(
|
||||||
|
row->peer(),
|
||||||
|
_navigation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestsBoxController::rowElementClicked(
|
void RequestsBoxController::rowElementClicked(
|
||||||
|
|
94
Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp
Normal file
94
Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
74
Telegram/SourceFiles/boxes/peers/peer_short_info_box.h
Normal file
74
Telegram/SourceFiles/boxes/peers/peer_short_info_box.h
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
};
|
301
Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp
Normal file
301
Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp
Normal file
|
@ -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); });
|
||||||
|
}
|
28
Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h
Normal file
28
Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h
Normal file
|
@ -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;
|
infoScrollDateHideTimeout: historyScrollDateHideTimeout;
|
||||||
infoDateFadeDuration: historyDateFadeDuration;
|
infoDateFadeDuration: historyDateFadeDuration;
|
||||||
|
|
||||||
|
shortInfoName: FlatLabel(defaultFlatLabel) {
|
||||||
|
}
|
||||||
|
shortInfoStatus: FlatLabel(defaultFlatLabel) {
|
||||||
|
}
|
||||||
|
shortInfoWidth: 336px;
|
||||||
|
|
|
@ -74,7 +74,7 @@ rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
|
||||||
UpdateFlag::Name
|
UpdateFlag::Name
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
return peer->name;
|
return peer->name;
|
||||||
}) | Ui::Text::ToWithEntities();;
|
}) | Ui::Text::ToWithEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
||||||
|
@ -113,7 +113,9 @@ rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
|
||||||
}) | Ui::Text::ToWithEntities();
|
}) | Ui::Text::ToWithEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
TextWithEntities AboutWithEntities(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QString &value) {
|
||||||
auto flags = TextParseLinks | TextParseMentions;
|
auto flags = TextParseLinks | TextParseMentions;
|
||||||
const auto user = peer->asUser();
|
const auto user = peer->asUser();
|
||||||
const auto isBot = user && user->isBot();
|
const auto isBot = user && user->isBot();
|
||||||
|
@ -125,15 +127,19 @@ rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
||||||
const auto stripExternal = peer->isChat()
|
const auto stripExternal = peer->isChat()
|
||||||
|| peer->isMegagroup()
|
|| peer->isMegagroup()
|
||||||
|| (user && !isBot);
|
|| (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(
|
return PlainAboutValue(
|
||||||
peer
|
peer
|
||||||
) | Ui::Text::ToWithEntities(
|
) | rpl::map([peer](const QString &value) {
|
||||||
) | rpl::map([=](TextWithEntities &&text) {
|
return AboutWithEntities(peer, value);
|
||||||
TextUtilities::ParseEntities(text, flags);
|
|
||||||
if (stripExternal) {
|
|
||||||
StripExternalLinks(text);
|
|
||||||
}
|
|
||||||
return std::move(text);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer);
|
||||||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user);
|
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user);
|
||||||
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user);
|
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user);
|
||||||
rpl::producer<TextWithEntities> UsernameValue(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<TextWithEntities> AboutValue(not_null<PeerData*> peer);
|
||||||
rpl::producer<QString> LinkValue(not_null<PeerData*> peer);
|
rpl::producer<QString> LinkValue(not_null<PeerData*> peer);
|
||||||
rpl::producer<const ChannelLocation*> LocationValue(
|
rpl::producer<const ChannelLocation*> LocationValue(
|
||||||
|
|
Loading…
Add table
Reference in a new issue