Support and use share comment in stories.
This commit is contained in:
parent
0b1b996e33
commit
fb4e05405e
|
@ -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}";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user