mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improved shared story layout.
This commit is contained in:
parent
c133f4de69
commit
1c41df364c
9 changed files with 107 additions and 56 deletions
|
@ -1699,6 +1699,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_context_about_private_link" = "This link will only work for members of this chat.";
|
"lng_context_about_private_link" = "This link will only work for members of this chat.";
|
||||||
|
|
||||||
"lng_forwarded" = "Forwarded from {user}";
|
"lng_forwarded" = "Forwarded from {user}";
|
||||||
|
"lng_forwarded_story" = "Story from {user}";
|
||||||
"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}";
|
||||||
|
|
|
@ -410,6 +410,10 @@ FullStoryId Media::storyId() const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Media::storyExpired() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Media::uploading() const {
|
bool Media::uploading() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1978,12 +1982,16 @@ MediaStory::MediaStory(not_null<HistoryItem*> parent, FullStoryId storyId)
|
||||||
: Media(parent)
|
: Media(parent)
|
||||||
, _storyId(storyId) {
|
, _storyId(storyId) {
|
||||||
const auto stories = &parent->history()->owner().stories();
|
const auto stories = &parent->history()->owner().stories();
|
||||||
if (!stories->lookup(storyId)) {
|
const auto maybeStory = stories->lookup(storyId);
|
||||||
stories->resolve(storyId, crl::guard(this, [=] {
|
if (!maybeStory) {
|
||||||
if (stories->lookup(storyId)) {
|
if (maybeStory.error() == NoStory::Unknown) {
|
||||||
|
stories->resolve(storyId, crl::guard(this, [=] {
|
||||||
|
_expired = !stories->lookup(storyId);
|
||||||
parent->history()->owner().requestItemViewRefresh(parent);
|
parent->history()->owner().requestItemViewRefresh(parent);
|
||||||
}
|
}));
|
||||||
}));
|
} else {
|
||||||
|
_expired = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1995,6 +2003,10 @@ FullStoryId MediaStory::storyId() const {
|
||||||
return _storyId;
|
return _storyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaStory::storyExpired() const {
|
||||||
|
return _expired;
|
||||||
|
}
|
||||||
|
|
||||||
TextWithEntities MediaStory::notificationText() const {
|
TextWithEntities MediaStory::notificationText() const {
|
||||||
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);
|
||||||
|
@ -2015,6 +2027,10 @@ TextForMimeData MediaStory::clipboardText() const {
|
||||||
parent()->clipboardText());
|
parent()->clipboardText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaStory::dropForwardedInfo() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MediaStory::updateInlineResultMedia(const MTPMessageMedia &media) {
|
bool MediaStory::updateInlineResultMedia(const MTPMessageMedia &media) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2030,26 +2046,33 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
|
||||||
const auto spoiler = false;
|
const auto spoiler = false;
|
||||||
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 (const auto story = maybeStory ? maybeStory->get() : nullptr) {
|
if (!maybeStory) {
|
||||||
if (const auto photo = story->photo()) {
|
if (maybeStory.error() == Data::NoStory::Deleted) {
|
||||||
return std::make_unique<HistoryView::Photo>(
|
_expired = true;
|
||||||
message,
|
return nullptr;
|
||||||
realParent,
|
|
||||||
photo,
|
|
||||||
spoiler);
|
|
||||||
} else {
|
|
||||||
return std::make_unique<HistoryView::Gif>(
|
|
||||||
message,
|
|
||||||
realParent,
|
|
||||||
story->document(),
|
|
||||||
spoiler);
|
|
||||||
}
|
}
|
||||||
|
_expired = false;
|
||||||
|
return std::make_unique<HistoryView::Photo>(
|
||||||
|
message,
|
||||||
|
realParent,
|
||||||
|
realParent->history()->owner().photo(kLoadingStoryPhotoId),
|
||||||
|
spoiler);
|
||||||
|
}
|
||||||
|
_expired = false;
|
||||||
|
const auto story = *maybeStory;
|
||||||
|
if (const auto photo = story->photo()) {
|
||||||
|
return std::make_unique<HistoryView::Photo>(
|
||||||
|
message,
|
||||||
|
realParent,
|
||||||
|
photo,
|
||||||
|
spoiler);
|
||||||
|
} else {
|
||||||
|
return std::make_unique<HistoryView::Gif>(
|
||||||
|
message,
|
||||||
|
realParent,
|
||||||
|
story->document(),
|
||||||
|
spoiler);
|
||||||
}
|
}
|
||||||
return std::make_unique<HistoryView::Photo>(
|
|
||||||
message,
|
|
||||||
realParent,
|
|
||||||
realParent->history()->owner().photo(kLoadingStoryPhotoId),
|
|
||||||
spoiler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -112,6 +112,7 @@ public:
|
||||||
virtual PollData *poll() const;
|
virtual PollData *poll() const;
|
||||||
virtual const WallPaper *paper() const;
|
virtual const WallPaper *paper() const;
|
||||||
virtual FullStoryId storyId() const;
|
virtual FullStoryId storyId() const;
|
||||||
|
virtual bool storyExpired() const;
|
||||||
|
|
||||||
virtual bool uploading() const;
|
virtual bool uploading() const;
|
||||||
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
||||||
|
@ -571,11 +572,13 @@ public:
|
||||||
|
|
||||||
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
|
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
|
||||||
|
|
||||||
[[nodiscard]] FullStoryId storyId() const override;
|
FullStoryId storyId() const override;
|
||||||
|
bool storyExpired() const override;
|
||||||
|
|
||||||
TextWithEntities notificationText() const override;
|
TextWithEntities notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
TextForMimeData clipboardText() const override;
|
TextForMimeData clipboardText() const override;
|
||||||
|
bool dropForwardedInfo() const override;
|
||||||
|
|
||||||
bool updateInlineResultMedia(const MTPMessageMedia &media) override;
|
bool updateInlineResultMedia(const MTPMessageMedia &media) override;
|
||||||
bool updateSentMedia(const MTPMessageMedia &media) override;
|
bool updateSentMedia(const MTPMessageMedia &media) override;
|
||||||
|
@ -586,6 +589,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const FullStoryId _storyId;
|
const FullStoryId _storyId;
|
||||||
|
bool _expired = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -742,11 +742,12 @@ void Stories::sendResolveRequests() {
|
||||||
auto leftToSend = kMaxResolveTogether;
|
auto leftToSend = kMaxResolveTogether;
|
||||||
auto byPeer = base::flat_map<PeerId, QVector<MTPint>>();
|
auto byPeer = base::flat_map<PeerId, QVector<MTPint>>();
|
||||||
for (auto i = begin(_resolvePending); i != end(_resolvePending);) {
|
for (auto i = begin(_resolvePending); i != end(_resolvePending);) {
|
||||||
auto &[peerId, ids] = *i;
|
const auto peerId = i->first;
|
||||||
|
auto &ids = i->second;
|
||||||
auto &sent = _resolveSent[peerId];
|
auto &sent = _resolveSent[peerId];
|
||||||
if (ids.size() <= leftToSend) {
|
if (ids.size() <= leftToSend) {
|
||||||
sent = base::take(ids);
|
sent = base::take(ids);
|
||||||
i = _resolvePending.erase(i);
|
i = _resolvePending.erase(i); // Invalidates `ids`.
|
||||||
leftToSend -= int(sent.size());
|
leftToSend -= int(sent.size());
|
||||||
} else {
|
} else {
|
||||||
sent = {
|
sent = {
|
||||||
|
|
|
@ -192,7 +192,13 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
|
||||||
} else {
|
} else {
|
||||||
phrase = name;
|
phrase = name;
|
||||||
}
|
}
|
||||||
if (via && psaType.isEmpty()) {
|
if (story) {
|
||||||
|
phrase = tr::lng_forwarded_story(
|
||||||
|
tr::now,
|
||||||
|
lt_user,
|
||||||
|
Ui::Text::Link(phrase.text, QString()), // Link 1.
|
||||||
|
Ui::Text::WithEntities);
|
||||||
|
} else if (via && psaType.isEmpty()) {
|
||||||
if (fromChannel) {
|
if (fromChannel) {
|
||||||
phrase = tr::lng_forwarded_channel_via(
|
phrase = tr::lng_forwarded_channel_via(
|
||||||
tr::now,
|
tr::now,
|
||||||
|
|
|
@ -839,14 +839,15 @@ auto Element::contextDependentServiceText() -> TextWithLinks {
|
||||||
void Element::validateText() {
|
void Element::validateText() {
|
||||||
const auto item = data();
|
const auto item = data();
|
||||||
const auto &text = item->_text;
|
const auto &text = item->_text;
|
||||||
if (_text.isEmpty() == text.empty()) {
|
const auto media = item->media();
|
||||||
return;
|
if (media && media->storyExpired()) {
|
||||||
}
|
_media = nullptr;
|
||||||
const auto context = Core::MarkedTextContext{
|
if (_text.isEmpty()) {
|
||||||
.session = &history()->session(),
|
setTextWithLinks(
|
||||||
.customEmojiRepaint = [=] { customEmojiRepaint(); },
|
Ui::Text::Italic(u"This story has expired"_q));
|
||||||
};
|
}
|
||||||
if (_flags & Flag::ServiceMessage) {
|
} else if (_text.isEmpty() == text.empty()) {
|
||||||
|
} else if (_flags & Flag::ServiceMessage) {
|
||||||
const auto contextDependentText = contextDependentServiceText();
|
const auto contextDependentText = contextDependentServiceText();
|
||||||
const auto &markedText = contextDependentText.text.empty()
|
const auto &markedText = contextDependentText.text.empty()
|
||||||
? text
|
? text
|
||||||
|
@ -854,28 +855,33 @@ void Element::validateText() {
|
||||||
const auto &customLinks = contextDependentText.text.empty()
|
const auto &customLinks = contextDependentText.text.empty()
|
||||||
? item->customTextLinks()
|
? item->customTextLinks()
|
||||||
: contextDependentText.links;
|
: contextDependentText.links;
|
||||||
_text.setMarkedText(
|
setTextWithLinks(markedText, customLinks);
|
||||||
st::serviceTextStyle,
|
} else {
|
||||||
markedText,
|
setTextWithLinks(item->translatedTextWithLocalEntities());
|
||||||
Ui::ItemTextServiceOptions(),
|
}
|
||||||
context);
|
}
|
||||||
|
|
||||||
|
void Element::setTextWithLinks(
|
||||||
|
const TextWithEntities &text,
|
||||||
|
const std::vector<ClickHandlerPtr> &links) {
|
||||||
|
const auto context = Core::MarkedTextContext{
|
||||||
|
.session = &history()->session(),
|
||||||
|
.customEmojiRepaint = [=] { customEmojiRepaint(); },
|
||||||
|
};
|
||||||
|
if (_flags & Flag::ServiceMessage) {
|
||||||
|
const auto &options = Ui::ItemTextServiceOptions();
|
||||||
|
_text.setMarkedText(st::serviceTextStyle, text, options, context);
|
||||||
auto linkIndex = 0;
|
auto linkIndex = 0;
|
||||||
for (const auto &link : customLinks) {
|
for (const auto &link : links) {
|
||||||
// Link indices start with 1.
|
// Link indices start with 1.
|
||||||
_text.setLink(++linkIndex, link);
|
_text.setLink(++linkIndex, link);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const auto item = data();
|
||||||
|
const auto &options = Ui::ItemTextOptions(item);
|
||||||
clearSpecialOnlyEmoji();
|
clearSpecialOnlyEmoji();
|
||||||
const auto context = Core::MarkedTextContext{
|
_text.setMarkedText(st::messageTextStyle, text, options, context);
|
||||||
.session = &history()->session(),
|
if (!item->_text.empty() && _text.isEmpty()){
|
||||||
.customEmojiRepaint = [=] { customEmojiRepaint(); },
|
|
||||||
};
|
|
||||||
_text.setMarkedText(
|
|
||||||
st::messageTextStyle,
|
|
||||||
item->translatedTextWithLocalEntities(),
|
|
||||||
Ui::ItemTextOptions(item),
|
|
||||||
context);
|
|
||||||
if (!text.empty() && _text.isEmpty()) {
|
|
||||||
// If server has allowed some text that we've trim-ed entirely,
|
// If server has allowed some text that we've trim-ed entirely,
|
||||||
// just replace it with something so that UI won't look buggy.
|
// just replace it with something so that UI won't look buggy.
|
||||||
_text.setMarkedText(
|
_text.setMarkedText(
|
||||||
|
|
|
@ -536,6 +536,9 @@ private:
|
||||||
virtual QSize performCountCurrentSize(int newWidth) = 0;
|
virtual QSize performCountCurrentSize(int newWidth) = 0;
|
||||||
|
|
||||||
void refreshMedia(Element *replacing);
|
void refreshMedia(Element *replacing);
|
||||||
|
void setTextWithLinks(
|
||||||
|
const TextWithEntities &text,
|
||||||
|
const std::vector<ClickHandlerPtr> &links = {});
|
||||||
|
|
||||||
struct TextWithLinks {
|
struct TextWithLinks {
|
||||||
TextWithEntities text;
|
TextWithEntities text;
|
||||||
|
|
|
@ -1777,9 +1777,8 @@ void Message::unloadHeavyPart() {
|
||||||
bool Message::showForwardsFromSender(
|
bool Message::showForwardsFromSender(
|
||||||
not_null<HistoryMessageForwarded*> forwarded) const {
|
not_null<HistoryMessageForwarded*> forwarded) const {
|
||||||
const auto peer = data()->history()->peer;
|
const auto peer = data()->history()->peer;
|
||||||
return peer->isSelf()
|
return !forwarded->story
|
||||||
|| peer->isRepliesChat()
|
&& (peer->isSelf() || peer->isRepliesChat() || forwarded->imported);
|
||||||
|| forwarded->imported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Message::hasFromPhoto() const {
|
bool Message::hasFromPhoto() const {
|
||||||
|
@ -2877,7 +2876,9 @@ bool Message::displayFromName() const {
|
||||||
bool Message::displayForwardedFrom() const {
|
bool Message::displayForwardedFrom() const {
|
||||||
const auto item = data();
|
const auto item = data();
|
||||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||||
if (showForwardsFromSender(forwarded)) {
|
if (forwarded->story) {
|
||||||
|
return true;
|
||||||
|
} else if (showForwardsFromSender(forwarded)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (const auto sender = item->discussionPostOriginalSender()) {
|
if (const auto sender = item->discussionPostOriginalSender()) {
|
||||||
|
@ -3685,6 +3686,9 @@ bool Message::needInfoDisplay() const {
|
||||||
|
|
||||||
bool Message::hasVisibleText() const {
|
bool Message::hasVisibleText() const {
|
||||||
if (data()->emptyText()) {
|
if (data()->emptyText()) {
|
||||||
|
if (const auto media = data()->media()) {
|
||||||
|
return media->storyExpired();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
|
@ -3713,6 +3717,9 @@ void Message::refreshInfoSkipBlock() {
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
const auto hasTextSkipBlock = [&] {
|
const auto hasTextSkipBlock = [&] {
|
||||||
if (item->_text.empty()) {
|
if (item->_text.empty()) {
|
||||||
|
if (const auto media = data()->media()) {
|
||||||
|
return media->storyExpired();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (item->Has<HistoryMessageLogEntryOriginal>()) {
|
} else if (item->Has<HistoryMessageLogEntryOriginal>()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -72,7 +72,7 @@ Photo::Photo(
|
||||||
, _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr) {
|
, _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr) {
|
||||||
if (const auto media = realParent->media()) {
|
if (const auto media = realParent->media()) {
|
||||||
if (media->storyId()) {
|
if (media->storyId()) {
|
||||||
_story = true;
|
_story = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_caption = createCaption(realParent);
|
_caption = createCaption(realParent);
|
||||||
|
|
Loading…
Add table
Reference in a new issue