mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
feat: improve message shot
Add Show Spoiler Fix photo not showing date in shot Fix show date in media group Hide inapplicable options Co-authored-by: AlexeyZavar <sltkval1@gmail.com>
This commit is contained in:
@@ -8080,6 +8080,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_MessageShotShowDate" = "Show date";
|
||||
"ayu_MessageShotShowReactions" = "Show reactions";
|
||||
"ayu_MessageShotShowColorfulReplies" = "Show colorful replies";
|
||||
"ayu_MessageShotRevealSpoilers" = "Reveal spoilers";
|
||||
"ayu_SendAsSticker" = "Send as Sticker";
|
||||
"ayu_SendWithSound" = "Send With Sound";
|
||||
"ayu_AyuForwardStatusPreparing" = "Forwarding messages";
|
||||
|
||||
@@ -220,6 +220,12 @@ void MessageShotSettings::setShowColorfulReplies(bool val) {
|
||||
AyuSettings::save();
|
||||
}
|
||||
|
||||
void MessageShotSettings::setRevealSpoilers(bool val) {
|
||||
if (_revealSpoilers.current() == val) return;
|
||||
_revealSpoilers = val;
|
||||
AyuSettings::save();
|
||||
}
|
||||
|
||||
bool MessageShotSettings::isCloudThemeEmpty() const {
|
||||
return !_cloudThemeId.current()
|
||||
&& !_cloudThemeAccessHash.current()
|
||||
@@ -285,6 +291,7 @@ void to_json(nlohmann::json &j, const MessageShotSettings &s) {
|
||||
{"showDate", s._showDate.current()},
|
||||
{"showReactions", s._showReactions.current()},
|
||||
{"showColorfulReplies", s._showColorfulReplies.current()},
|
||||
{"revealSpoilers", s._revealSpoilers.current()},
|
||||
{"embeddedThemeType", s._embeddedThemeType.current()},
|
||||
{"embeddedThemeAccentColor", s._embeddedThemeAccentColor.current()},
|
||||
{"cloudThemeId", s._cloudThemeId.current()},
|
||||
@@ -299,7 +306,8 @@ void from_json(const nlohmann::json &j, MessageShotSettings &s) {
|
||||
s._showBackground = j.value("showBackground", true);
|
||||
s._showDate = j.value("showDate", false);
|
||||
s._showReactions = j.value("showReactions", false);
|
||||
s._showColorfulReplies = j.value("showColorfulReplies", false);
|
||||
s._showColorfulReplies = j.value("showColorfulReplies", true);
|
||||
s._revealSpoilers = j.value("revealSpoilers", true);
|
||||
s._embeddedThemeType = j.value("embeddedThemeType", j.value("themeType", -1));
|
||||
s._embeddedThemeAccentColor = j.value("embeddedThemeAccentColor", j.value("themeAccentColor", uint32(0)));
|
||||
s._cloudThemeId = j.value("cloudThemeId", uint64(0));
|
||||
|
||||
@@ -167,6 +167,7 @@ public:
|
||||
[[nodiscard]] bool showDate() const { return _showDate.current(); }
|
||||
[[nodiscard]] bool showReactions() const { return _showReactions.current(); }
|
||||
[[nodiscard]] bool showColorfulReplies() const { return _showColorfulReplies.current(); }
|
||||
[[nodiscard]] bool revealSpoilers() const { return _revealSpoilers.current(); }
|
||||
[[nodiscard]] int embeddedThemeType() const { return _embeddedThemeType.current(); }
|
||||
[[nodiscard]] uint32 embeddedThemeAccentColor() const { return _embeddedThemeAccentColor.current(); }
|
||||
[[nodiscard]] uint64 cloudThemeId() const { return _cloudThemeId.current(); }
|
||||
@@ -179,6 +180,7 @@ public:
|
||||
void setShowDate(bool val);
|
||||
void setShowReactions(bool val);
|
||||
void setShowColorfulReplies(bool val);
|
||||
void setRevealSpoilers(bool val);
|
||||
|
||||
void setEmbeddedTheme(int type, uint32 accentColor = 0);
|
||||
void setCloudTheme(uint64 accountId, uint64 id, uint64 accessHash, uint64 documentId, const QString &title);
|
||||
@@ -195,7 +197,8 @@ private:
|
||||
rpl::variable<bool> _showBackground = true;
|
||||
rpl::variable<bool> _showDate = false;
|
||||
rpl::variable<bool> _showReactions = false;
|
||||
rpl::variable<bool> _showColorfulReplies = false;
|
||||
rpl::variable<bool> _showColorfulReplies = true;
|
||||
rpl::variable<bool> _revealSpoilers = true;
|
||||
|
||||
rpl::variable<int> _embeddedThemeType = -1;
|
||||
rpl::variable<uint32> _embeddedThemeAccentColor = 0;
|
||||
|
||||
@@ -315,6 +315,9 @@ void Make(not_null<QWidget*> box, const ShotConfig &config, const Fn<void(QImage
|
||||
|
||||
view->itemDataChanged(); // refresh reactions
|
||||
height += view->resizeGetHeight(width);
|
||||
if (AyuSettings::getInstance().messageShotSettings().revealSpoilers()) {
|
||||
view->revealSpoilers();
|
||||
}
|
||||
}
|
||||
|
||||
width *= style::DevicePixelRatio();
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "ayu/ui/components/image_view.h"
|
||||
#include "ayu/utils/telegram_helpers.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "data/data_todo_list.h"
|
||||
#include "history/history_item.h"
|
||||
#include "main/main_session.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "styles/style_ayu_styles.h"
|
||||
@@ -83,6 +85,55 @@ void MessageShotBox::setupContent() {
|
||||
AddSkip(content);
|
||||
AddSubsectionTitle(content, tr::ayu_MessageShotPreferences());
|
||||
|
||||
auto hasReactions = false;
|
||||
auto hasReplies = false;
|
||||
auto hasSpoilers = false;
|
||||
for (const auto &item : _config.messages) {
|
||||
if (!hasReactions && !item->reactions().empty()) {
|
||||
hasReactions = true;
|
||||
}
|
||||
if (!hasReplies) {
|
||||
if (item->replyTo().replying()
|
||||
|| (item->media() && item->media()->webpage())) {
|
||||
hasReplies = true;
|
||||
}
|
||||
}
|
||||
if (!hasSpoilers) {
|
||||
for (const auto &entity : item->originalText().entities) {
|
||||
if (entity.type() == EntityType::Spoiler) {
|
||||
hasSpoilers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasSpoilers && item->media()) {
|
||||
if (item->media()->hasSpoiler()) {
|
||||
hasSpoilers = true;
|
||||
} else if (const auto todoList = item->media()->todolist()) {
|
||||
for (const auto &entity : todoList->title.entities) {
|
||||
if (entity.type() == EntityType::Spoiler) {
|
||||
hasSpoilers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasSpoilers) {
|
||||
for (const auto &task : todoList->items) {
|
||||
for (const auto &entity : task.text.entities) {
|
||||
if (entity.type() == EntityType::Spoiler) {
|
||||
hasSpoilers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasSpoilers) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasReactions && hasReplies && hasSpoilers) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto firstPreviewLatch = std::make_shared<TimedCountDownLatch>(1);
|
||||
const auto generation = content->lifetime().make_state<int>(0);
|
||||
const auto weak = base::make_weak(this);
|
||||
@@ -187,11 +238,12 @@ void MessageShotBox::setupContent() {
|
||||
},
|
||||
content->lifetime());
|
||||
|
||||
AddButtonWithIcon(
|
||||
auto latestToggle = AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotShowDate(),
|
||||
st::settingsButtonNoIcon
|
||||
)->toggleOn(rpl::single(shotSettings.showDate())
|
||||
);
|
||||
latestToggle->toggleOn(rpl::single(shotSettings.showDate())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
@@ -201,38 +253,60 @@ void MessageShotBox::setupContent() {
|
||||
},
|
||||
content->lifetime());
|
||||
|
||||
AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotShowReactions(),
|
||||
st::settingsButtonNoIcon
|
||||
)->toggleOn(rpl::single(shotSettings.showReactions())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
AyuSettings::getInstance().messageShotSettings().setShowReactions(enabled);
|
||||
updatePreview();
|
||||
},
|
||||
content->lifetime());
|
||||
if (hasReactions) {
|
||||
latestToggle = AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotShowReactions(),
|
||||
st::settingsButtonNoIcon
|
||||
);
|
||||
latestToggle->toggleOn(rpl::single(shotSettings.showReactions())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
AyuSettings::getInstance().messageShotSettings().setShowReactions(enabled);
|
||||
updatePreview();
|
||||
},
|
||||
content->lifetime());
|
||||
}
|
||||
|
||||
const auto latestToggle = AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotShowColorfulReplies(),
|
||||
st::settingsButtonNoIcon
|
||||
);
|
||||
latestToggle->toggleOn(rpl::single(shotSettings.showColorfulReplies())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
auto ¤tSettings = AyuSettings::getInstance();
|
||||
currentSettings.messageShotSettings().setShowColorfulReplies(enabled);
|
||||
currentSettings.setSimpleQuotesAndReplies(!enabled);
|
||||
if (hasReplies) {
|
||||
latestToggle = AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotShowColorfulReplies(),
|
||||
st::settingsButtonNoIcon
|
||||
);
|
||||
latestToggle->toggleOn(rpl::single(shotSettings.showColorfulReplies())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
auto ¤tSettings = AyuSettings::getInstance();
|
||||
currentSettings.messageShotSettings().setShowColorfulReplies(enabled);
|
||||
currentSettings.setSimpleQuotesAndReplies(!enabled);
|
||||
|
||||
_config.st = std::make_shared<Ui::ChatStyle>(_config.st.get());
|
||||
updatePreview();
|
||||
},
|
||||
content->lifetime());
|
||||
_config.st = std::make_shared<Ui::ChatStyle>(_config.st.get());
|
||||
updatePreview();
|
||||
},
|
||||
content->lifetime());
|
||||
}
|
||||
|
||||
if (hasSpoilers) {
|
||||
latestToggle = AddButtonWithIcon(
|
||||
content,
|
||||
tr::ayu_MessageShotRevealSpoilers(),
|
||||
st::settingsButtonNoIcon
|
||||
);
|
||||
latestToggle->toggleOn(rpl::single(shotSettings.revealSpoilers())
|
||||
)->toggledValue(
|
||||
) | rpl::skip(1) | on_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
AyuSettings::getInstance().messageShotSettings().setRevealSpoilers(enabled);
|
||||
updatePreview();
|
||||
},
|
||||
content->lifetime());
|
||||
}
|
||||
|
||||
AddSkip(content);
|
||||
|
||||
|
||||
@@ -1298,6 +1298,15 @@ void Element::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void Element::revealSpoilers() {
|
||||
if (_text.hasSpoilers()) {
|
||||
_text.setSpoilerRevealed(true, anim::type::instant);
|
||||
}
|
||||
if (_media) {
|
||||
_media->revealSpoilers();
|
||||
}
|
||||
}
|
||||
|
||||
void Element::customEmojiRepaint() {
|
||||
if (!(_flags & Flag::CustomEmojiRepainting)) {
|
||||
_flags |= Flag::CustomEmojiRepainting;
|
||||
|
||||
@@ -654,6 +654,7 @@ public:
|
||||
const Reactions::InlineList &reactions) const;
|
||||
void clearCustomEmojiRepaint() const;
|
||||
void hideSpoilers();
|
||||
void revealSpoilers();
|
||||
void repaint(QRect r = QRect()) const;
|
||||
|
||||
[[nodiscard]] ClickHandlerPtr fromPhotoLink() const {
|
||||
|
||||
@@ -1738,6 +1738,12 @@ void Document::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void Document::revealSpoilers() {
|
||||
if (const auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||
captioned->caption.setSpoilerRevealed(true, anim::type::instant);
|
||||
}
|
||||
}
|
||||
|
||||
Ui::Text::String Document::createCaption() const {
|
||||
return File::createCaption(_realParent);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
}
|
||||
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
bool needsBubble() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1701,6 +1701,12 @@ void Gif::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void Gif::revealSpoilers() {
|
||||
if (_spoiler) {
|
||||
_spoiler->revealed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Gif::needsBubble() const {
|
||||
if (_storyId) {
|
||||
return true;
|
||||
|
||||
@@ -102,6 +102,7 @@ public:
|
||||
QImage spoilerTagBackground() const override;
|
||||
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
bool needsBubble() const override;
|
||||
bool unwrapped() const override;
|
||||
bool customInfoLayout() const override {
|
||||
|
||||
@@ -265,6 +265,8 @@ public:
|
||||
|
||||
virtual void hideSpoilers() {
|
||||
}
|
||||
virtual void revealSpoilers() {
|
||||
}
|
||||
[[nodiscard]] virtual bool needsBubble() const = 0;
|
||||
[[nodiscard]] virtual bool unwrapped() const {
|
||||
return false;
|
||||
|
||||
@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/ayu_settings.h"
|
||||
#include "ayu/features/message_shot/message_shot.h"
|
||||
|
||||
|
||||
namespace HistoryView {
|
||||
@@ -512,7 +513,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
||||
if (_parent->media() == this && (!_parent->hasBubble() || isBubbleBottom())) {
|
||||
auto fullRight = width();
|
||||
auto fullBottom = height();
|
||||
if (needInfoDisplay()) {
|
||||
if (needInfoDisplay() && !AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||
_parent->drawInfo(
|
||||
p,
|
||||
context,
|
||||
@@ -847,6 +848,12 @@ void GroupedMedia::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void GroupedMedia::revealSpoilers() {
|
||||
for (const auto &part : _parts) {
|
||||
part.content->revealSpoilers();
|
||||
}
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask GroupedMedia::sharedMediaTypes() const {
|
||||
return main()->sharedMediaTypes();
|
||||
}
|
||||
@@ -960,6 +967,9 @@ bool GroupedMedia::computeNeedBubble() const {
|
||||
}
|
||||
|
||||
bool GroupedMedia::needInfoDisplay() const {
|
||||
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||
return (_mode != Mode::Column);
|
||||
}
|
||||
const auto item = _parent->data();
|
||||
return (_mode != Mode::Column)
|
||||
&& (item->isSending()
|
||||
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
bool pressed) override;
|
||||
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
bool overrideEditedDate() const override {
|
||||
|
||||
@@ -893,6 +893,10 @@ bool Photo::needInfoDisplay() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_parent->data()->isFakeAboutView()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1094,6 +1098,12 @@ void Photo::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void Photo::revealSpoilers() {
|
||||
if (_spoiler) {
|
||||
_spoiler->revealed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Photo::needsBubble() const {
|
||||
if (_storyId) {
|
||||
return true;
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
QImage spoilerTagBackground() const override;
|
||||
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
bool needsBubble() const override;
|
||||
bool customInfoLayout() const override {
|
||||
return true;
|
||||
|
||||
@@ -422,6 +422,10 @@ void ServiceBox::hideSpoilers() {
|
||||
_subtitle.setSpoilerRevealed(false, anim::type::instant);
|
||||
}
|
||||
|
||||
void ServiceBox::revealSpoilers() {
|
||||
_subtitle.setSpoilerRevealed(true, anim::type::instant);
|
||||
}
|
||||
|
||||
bool ServiceBox::hasHeavyPart() const {
|
||||
return _content->hasHeavyPart();
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
return _content->hideServiceText();
|
||||
}
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
|
||||
bool hasHeavyPart() const override;
|
||||
void unloadHeavyPart() override;
|
||||
|
||||
@@ -864,6 +864,17 @@ void TodoList::hideSpoilers() {
|
||||
}
|
||||
}
|
||||
|
||||
void TodoList::revealSpoilers() {
|
||||
if (_title.hasSpoilers()) {
|
||||
_title.setSpoilerRevealed(true, anim::type::instant);
|
||||
}
|
||||
for (auto &task : _tasks) {
|
||||
if (task.text.hasSpoilers()) {
|
||||
task.text.setSpoilerRevealed(true, anim::type::instant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Media::TodoTaskInfo> TodoList::takeTasksInfo() {
|
||||
if (_tasks.empty()) {
|
||||
return {};
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
bool hasHeavyPart() const override;
|
||||
|
||||
void hideSpoilers() override;
|
||||
void revealSpoilers() override;
|
||||
|
||||
std::vector<TodoTaskInfo> takeTasksInfo() override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user