Support and use share comment in stories.

This commit is contained in:
John Preston 2023-07-24 11:43:20 +04:00
parent 0b1b996e33
commit fb4e05405e
9 changed files with 57 additions and 56 deletions

View File

@ -1710,6 +1710,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarded" = "Forwarded from {user}"; "lng_forwarded" = "Forwarded from {user}";
"lng_forwarded_story" = "Story from {user}"; "lng_forwarded_story" = "Story from {user}";
"lng_forwarded_story_expired" = "This story has expired.";
"lng_forwarded_date" = "Original: {date}"; "lng_forwarded_date" = "Original: {date}";
"lng_forwarded_channel" = "Forwarded from {channel}"; "lng_forwarded_channel" = "Forwarded from {channel}";
"lng_forwarded_psa_default" = "Forwarded from {channel}"; "lng_forwarded_psa_default" = "Forwarded from {channel}";

View File

@ -744,6 +744,11 @@ groupCallShareBoxComment: InputField(groupCallField) {
} }
groupCallShareBoxList: PeerList(groupCallMembersList) { groupCallShareBoxList: PeerList(groupCallMembersList) {
item: PeerListItem(groupCallMembersListItem) { item: PeerListItem(groupCallMembersListItem) {
nameStyle: TextStyle(defaultTextStyle) {
font: font(11px);
linkFont: font(11px);
linkFontOver: font(11px);
}
checkbox: RoundImageCheckbox(groupCallMembersListCheckbox) { checkbox: RoundImageCheckbox(groupCallMembersListCheckbox) {
imageRadius: 28px; imageRadius: 28px;
imageSmallRadius: 24px; imageSmallRadius: 24px;

View File

@ -1995,18 +1995,11 @@ MediaStory::MediaStory(
owner->registerStoryItem(storyId, parent); owner->registerStoryItem(storyId, parent);
const auto stories = &owner->stories(); const auto stories = &owner->stories();
if (const auto maybeStory = stories->lookup(storyId)) { const auto maybeStory = stories->lookup(storyId);
if (!_mention) { if (!maybeStory) {
parent->setText((*maybeStory)->caption());
}
} else {
if (maybeStory.error() == NoStory::Unknown) { if (maybeStory.error() == NoStory::Unknown) {
stories->resolve(storyId, crl::guard(this, [=] { stories->resolve(storyId, crl::guard(this, [=] {
if (const auto maybeStory = stories->lookup(storyId)) { if (!stories->lookup(storyId)) {
if (!_mention) {
parent->setText((*maybeStory)->caption());
}
} else {
_expired = true; _expired = true;
} }
if (_mention) { if (_mention) {
@ -2058,9 +2051,7 @@ TextWithEntities MediaStory::notificationText() const {
&& maybeStory.error() == Data::NoStory::Deleted)) && maybeStory.error() == Data::NoStory::Deleted))
? tr::lng_in_dlg_story_expired ? tr::lng_in_dlg_story_expired
: tr::lng_in_dlg_story)(tr::now), : tr::lng_in_dlg_story)(tr::now),
(maybeStory parent()->originalText());
? (*maybeStory)->caption()
: TextWithEntities()));
} }
QString MediaStory::pinnedTextSubstring() const { QString MediaStory::pinnedTextSubstring() const {
@ -2100,9 +2091,6 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
const auto stories = &parent()->history()->owner().stories(); const auto stories = &parent()->history()->owner().stories();
const auto maybeStory = stories->lookup(_storyId); const auto maybeStory = stories->lookup(_storyId);
if (!maybeStory) { if (!maybeStory) {
if (!_mention) {
realParent->setText(TextWithEntities());
}
if (maybeStory.error() == Data::NoStory::Deleted) { if (maybeStory.error() == Data::NoStory::Deleted) {
_expired = true; _expired = true;
return nullptr; return nullptr;
@ -2124,7 +2112,6 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
message, message,
std::make_unique<HistoryView::StoryMention>(message, story)); std::make_unique<HistoryView::StoryMention>(message, story));
} else { } else {
realParent->setText(story->caption());
if (const auto photo = story->photo()) { if (const auto photo = story->photo()) {
return std::make_unique<HistoryView::Photo>( return std::make_unique<HistoryView::Photo>(
message, message,

View File

@ -846,8 +846,12 @@ void Element::validateText() {
_media = nullptr; _media = nullptr;
if (!storyMention) { if (!storyMention) {
if (_text.isEmpty()) { if (_text.isEmpty()) {
setTextWithLinks( auto now = Ui::Text::Italic(
Ui::Text::Italic(u"This story has expired"_q)); tr::lng_forwarded_story_expired(tr::now));
if (!text.empty()) {
now.append(u"\n\n"_q).append(text);
}
setTextWithLinks(std::move(now));
} }
return; return;
} }

View File

@ -88,14 +88,13 @@ Gif::Gif(
bool spoiler) bool spoiler)
: File(parent, realParent) : File(parent, realParent)
, _data(document) , _data(document)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) , _storyId(realParent->media()
? realParent->media()->storyId()
: FullStoryId())
, _caption(
st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right())
, _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr) , _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr)
, _downloadSize(Ui::FormatSizeText(_data->size)) { , _downloadSize(Ui::FormatSizeText(_data->size)) {
if (const auto media = realParent->media()) {
if (media->storyId()) {
_story = true;
}
}
setDocumentLinks(_data, realParent, [=] { setDocumentLinks(_data, realParent, [=] {
if (!_data->createMediaView()->canBePlayed(realParent) if (!_data->createMediaView()->canBePlayed(realParent)
|| !_data->isAnimation() || !_data->isAnimation()
@ -1438,15 +1437,14 @@ void Gif::dataMediaCreated() const {
} }
void Gif::togglePollingStory(bool enabled) const { void Gif::togglePollingStory(bool enabled) const {
if (!_story || _pollingStory == enabled) { if (!_storyId || _pollingStory == enabled) {
return; return;
} }
const auto polling = Data::Stories::Polling::Chat; const auto polling = Data::Stories::Polling::Chat;
const auto media = _parent->data()->media();
const auto id = media ? media->storyId() : FullStoryId();
if (!enabled) { if (!enabled) {
_data->owner().stories().unregisterPolling(id, polling); _data->owner().stories().unregisterPolling(_storyId, polling);
} else if (!_data->owner().stories().registerPolling(id, polling)) { } else if (
!_data->owner().stories().registerPolling(_storyId, polling)) {
return; return;
} }
_pollingStory = enabled; _pollingStory = enabled;
@ -1464,7 +1462,7 @@ void Gif::hideSpoilers() {
} }
bool Gif::needsBubble() const { bool Gif::needsBubble() const {
if (_story) { if (_storyId) {
return true; return true;
} else if (_data->isVideoMessage()) { } else if (_data->isVideoMessage()) {
return false; return false;

View File

@ -211,6 +211,7 @@ private:
void togglePollingStory(bool enabled) const; void togglePollingStory(bool enabled) const;
const not_null<DocumentData*> _data; const not_null<DocumentData*> _data;
const FullStoryId _storyId;
Ui::Text::String _caption; Ui::Text::String _caption;
std::unique_ptr<Streamed> _streamed; std::unique_ptr<Streamed> _streamed;
const std::unique_ptr<MediaSpoiler> _spoiler; const std::unique_ptr<MediaSpoiler> _spoiler;
@ -223,7 +224,6 @@ private:
mutable std::optional<Ui::BubbleRounding> _thumbCacheRounding; mutable std::optional<Ui::BubbleRounding> _thumbCacheRounding;
mutable bool _thumbCacheBlurred : 1 = false; mutable bool _thumbCacheBlurred : 1 = false;
mutable bool _thumbIsEllipse : 1 = false; mutable bool _thumbIsEllipse : 1 = false;
mutable bool _story : 1 = false;
mutable bool _pollingStory : 1 = false; mutable bool _pollingStory : 1 = false;
}; };

View File

@ -69,13 +69,11 @@ Photo::Photo(
bool spoiler) bool spoiler)
: File(parent, realParent) : File(parent, realParent)
, _data(photo) , _data(photo)
, _storyId(realParent->media()
? realParent->media()->storyId()
: FullStoryId())
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right())
, _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr) { , _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr) {
if (const auto media = realParent->media()) {
if (media->storyId()) {
_story = 1;
}
}
_caption = createCaption(realParent); _caption = createCaption(realParent);
create(realParent->fullId()); create(realParent->fullId());
} }
@ -168,15 +166,14 @@ void Photo::unloadHeavyPart() {
void Photo::togglePollingStory(bool enabled) const { void Photo::togglePollingStory(bool enabled) const {
const auto pollingStory = (enabled ? 1 : 0); const auto pollingStory = (enabled ? 1 : 0);
if (!_story || _pollingStory == pollingStory) { if (!_storyId || _pollingStory == pollingStory) {
return; return;
} }
const auto polling = Data::Stories::Polling::Chat; const auto polling = Data::Stories::Polling::Chat;
const auto media = _parent->data()->media();
const auto id = media ? media->storyId() : FullStoryId();
if (!enabled) { if (!enabled) {
_data->owner().stories().unregisterPolling(id, polling); _data->owner().stories().unregisterPolling(_storyId, polling);
} else if (!_data->owner().stories().registerPolling(id, polling)) { } else if (
!_data->owner().stories().registerPolling(_storyId, polling)) {
return; return;
} }
_pollingStory = pollingStory; _pollingStory = pollingStory;
@ -285,7 +282,7 @@ int Photo::adjustHeightForLessCrop(QSize dimensions, QSize current) const {
void Photo::draw(Painter &p, const PaintContext &context) const { void Photo::draw(Painter &p, const PaintContext &context) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) { if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
return; return;
} else if (_story && _data->isNull()) { } else if (_storyId && _data->isNull()) {
return; return;
} }
@ -623,7 +620,7 @@ void Photo::paintUserpicFrame(
} }
QSize Photo::photoSize() const { QSize Photo::photoSize() const {
if (_story) { if (_storyId) {
return { kStoryWidth, kStoryHeight }; return { kStoryWidth, kStoryHeight };
} }
return QSize(_data->width(), _data->height()); return QSize(_data->width(), _data->height());
@ -634,7 +631,7 @@ TextState Photo::textState(QPoint point, StateRequest request) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) { if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
return result; return result;
} else if (_story && _data->isNull()) { } else if (_storyId && _data->isNull()) {
return result; return result;
} }
auto paintx = 0, painty = 0, paintw = width(), painth = height(); auto paintx = 0, painty = 0, paintw = width(), painth = height();
@ -1054,7 +1051,7 @@ void Photo::hideSpoilers() {
} }
bool Photo::needsBubble() const { bool Photo::needsBubble() const {
if (_story || !_caption.isEmpty()) { if (_storyId || !_caption.isEmpty()) {
return true; return true;
} }
const auto item = _parent->data(); const auto item = _parent->data();

View File

@ -163,6 +163,7 @@ private:
void togglePollingStory(bool enabled) const; void togglePollingStory(bool enabled) const;
const not_null<PhotoData*> _data; const not_null<PhotoData*> _data;
const FullStoryId _storyId;
Ui::Text::String _caption; Ui::Text::String _caption;
mutable std::shared_ptr<Data::PhotoMedia> _dataMedia; mutable std::shared_ptr<Data::PhotoMedia> _dataMedia;
mutable std::unique_ptr<Streamed> _streamed; mutable std::unique_ptr<Streamed> _streamed;
@ -172,7 +173,6 @@ private:
uint32 _serviceWidth : 28 = 0; uint32 _serviceWidth : 28 = 0;
mutable uint32 _imageCacheForum : 1 = 0; mutable uint32 _imageCacheForum : 1 = 0;
mutable uint32 _imageCacheBlurred : 1 = 0; mutable uint32 _imageCacheBlurred : 1 = 0;
mutable uint32 _story : 1 = 0;
mutable uint32 _pollingStory : 1 = 0; mutable uint32 _pollingStory : 1 = 0;
}; };

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/stories/media_stories_share.h" #include "media/stories/media_stories_share.h"
#include "api/api_common.h" #include "api/api_common.h"
#include "api/api_text_entities.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "base/random.h" #include "base/random.h"
#include "boxes/share_box.h" #include "boxes/share_box.h"
@ -86,7 +87,7 @@ namespace Media::Stories {
for (const auto thread : result) { for (const auto thread : result) {
const auto error = GetErrorTextForSending( const auto error = GetErrorTextForSending(
thread, thread,
{ .story = story, .text = &comment }); { .story = story });
if (!error.isEmpty()) { if (!error.isEmpty()) {
return std::make_pair(error, thread); return std::make_pair(error, thread);
} }
@ -105,16 +106,21 @@ namespace Media::Stories {
return; return;
} }
auto caption = TextWithEntities{
comment.text,
TextUtilities::ConvertTextTagsToEntities(comment.tags)
};
TextUtilities::Trim(caption);
auto sentEntities = Api::EntitiesToMTP(
session,
caption.entities,
Api::ConvertOption::SkipLocal);
const auto captionText = caption.text;
const auto api = &story->owner().session().api(); const auto api = &story->owner().session().api();
auto &histories = story->owner().histories(); auto &histories = story->owner().histories();
for (const auto thread : result) { for (const auto thread : result) {
const auto action = Api::SendAction(thread, options); const auto action = Api::SendAction(thread, options);
if (!comment.text.isEmpty()) {
auto message = Api::MessageToSend(action);
message.textWithTags = comment;
message.action.clearDraft = false;
api->sendMessage(std::move(message));
}
const auto peer = thread->peer(); const auto peer = thread->peer();
const auto threadHistory = thread->owningHistory(); const auto threadHistory = thread->owningHistory();
const auto randomId = base::RandomValue<uint64>(); const auto randomId = base::RandomValue<uint64>();
@ -126,6 +132,9 @@ namespace Media::Stories {
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
if (!sentEntities.v.isEmpty()) {
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
}
const auto done = [=] { const auto done = [=] {
if (!--state->requests) { if (!--state->requests) {
if (show->valid()) { if (show->valid()) {
@ -145,10 +154,10 @@ namespace Media::Stories {
MTP_inputMediaStory( MTP_inputMediaStory(
user->inputUser, user->inputUser,
MTP_int(id.story)), MTP_int(id.story)),
MTPstring(), MTP_string(captionText),
MTP_long(randomId), MTP_long(randomId),
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), sentEntities,
MTP_int(action.options.scheduled), MTP_int(action.options.scheduled),
MTP_inputPeerEmpty() MTP_inputPeerEmpty()
), [=](const MTPUpdates &result, const MTP::Response &response) { ), [=](const MTPUpdates &result, const MTP::Response &response) {