mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
feat: save message shot config
This commit is contained in:
@@ -210,6 +210,8 @@ set(ayugram_files
|
|||||||
ayu/features/streamer_mode/streamer_mode.h
|
ayu/features/streamer_mode/streamer_mode.h
|
||||||
ayu/features/message_shot/message_shot.cpp
|
ayu/features/message_shot/message_shot.cpp
|
||||||
ayu/features/message_shot/message_shot.h
|
ayu/features/message_shot/message_shot.h
|
||||||
|
ayu/features/message_shot/message_shot_theme_state.cpp
|
||||||
|
ayu/features/message_shot/message_shot_theme_state.h
|
||||||
ayu/features/forward/ayu_forward.cpp
|
ayu/features/forward/ayu_forward.cpp
|
||||||
ayu/features/forward/ayu_forward.h
|
ayu/features/forward/ayu_forward.h
|
||||||
ayu/features/forward/ayu_sync.cpp
|
ayu/features/forward/ayu_sync.cpp
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
#include "ayu/data/ayu_database.h"
|
#include "ayu/data/ayu_database.h"
|
||||||
#include "features/translator/ayu_translator.h"
|
#include "features/translator/ayu_translator.h"
|
||||||
#include "lang/lang_instance.h"
|
#include "lang/lang_instance.h"
|
||||||
#include "main/main_account.h"
|
|
||||||
#include "main/main_domain.h"
|
|
||||||
#include "main/main_session.h"
|
|
||||||
#include "ui/layers/generic_box.h"
|
|
||||||
#include "utils/rc_manager.h"
|
#include "utils/rc_manager.h"
|
||||||
|
|
||||||
namespace AyuInfra {
|
namespace AyuInfra {
|
||||||
|
|||||||
@@ -193,6 +193,119 @@ void from_json(const nlohmann::json &j, GhostModeAccountSettings &s) {
|
|||||||
s._sendOfflinePacketAfterOnlineLocked = j.value("sendOfflinePacketAfterOnlineLocked", false);
|
s._sendOfflinePacketAfterOnlineLocked = j.value("sendOfflinePacketAfterOnlineLocked", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setShowBackground(bool val) {
|
||||||
|
if (_showBackground.current() == val) return;
|
||||||
|
_showBackground = val;
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setShowDate(bool val) {
|
||||||
|
if (_showDate.current() == val) return;
|
||||||
|
_showDate = val;
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setShowReactions(bool val) {
|
||||||
|
if (_showReactions.current() == val) return;
|
||||||
|
_showReactions = val;
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setShowColorfulReplies(bool val) {
|
||||||
|
if (_showColorfulReplies.current() == val) return;
|
||||||
|
_showColorfulReplies = val;
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageShotSettings::isCloudThemeEmpty() const {
|
||||||
|
return !_cloudThemeId.current()
|
||||||
|
&& !_cloudThemeAccessHash.current()
|
||||||
|
&& !_cloudThemeDocumentId.current()
|
||||||
|
&& _cloudThemeTitle.current().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::clearCloudThemeData() {
|
||||||
|
_cloudThemeId = uint64(0);
|
||||||
|
_cloudThemeAccessHash = uint64(0);
|
||||||
|
_cloudThemeDocumentId = uint64(0);
|
||||||
|
_cloudThemeTitle = QString();
|
||||||
|
_cloudThemeAccountId = uint64(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setEmbeddedTheme(int type, uint32 accentColor) {
|
||||||
|
if (_embeddedThemeType.current() == type
|
||||||
|
&& _embeddedThemeAccentColor.current() == accentColor
|
||||||
|
&& isCloudThemeEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_embeddedThemeType = type;
|
||||||
|
_embeddedThemeAccentColor = accentColor;
|
||||||
|
clearCloudThemeData();
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::setCloudTheme(uint64 accountId, uint64 id, uint64 accessHash, uint64 documentId, const QString &title) {
|
||||||
|
if (_embeddedThemeType.current() == -1
|
||||||
|
&& _embeddedThemeAccentColor.current() == 0
|
||||||
|
&& _cloudThemeAccountId.current() == accountId
|
||||||
|
&& _cloudThemeId.current() == id
|
||||||
|
&& _cloudThemeAccessHash.current() == accessHash
|
||||||
|
&& _cloudThemeDocumentId.current() == documentId
|
||||||
|
&& _cloudThemeTitle.current() == title) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_embeddedThemeType = -1;
|
||||||
|
_embeddedThemeAccentColor = uint32(0);
|
||||||
|
_cloudThemeAccountId = accountId;
|
||||||
|
_cloudThemeId = id;
|
||||||
|
_cloudThemeAccessHash = accessHash;
|
||||||
|
_cloudThemeDocumentId = documentId;
|
||||||
|
_cloudThemeTitle = title;
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotSettings::clearTheme() {
|
||||||
|
if (_embeddedThemeType.current() == -1
|
||||||
|
&& _embeddedThemeAccentColor.current() == 0
|
||||||
|
&& isCloudThemeEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_embeddedThemeType = -1;
|
||||||
|
_embeddedThemeAccentColor = uint32(0);
|
||||||
|
clearCloudThemeData();
|
||||||
|
AyuSettings::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void to_json(nlohmann::json &j, const MessageShotSettings &s) {
|
||||||
|
j = nlohmann::json{
|
||||||
|
{"showBackground", s._showBackground.current()},
|
||||||
|
{"showDate", s._showDate.current()},
|
||||||
|
{"showReactions", s._showReactions.current()},
|
||||||
|
{"showColorfulReplies", s._showColorfulReplies.current()},
|
||||||
|
{"embeddedThemeType", s._embeddedThemeType.current()},
|
||||||
|
{"embeddedThemeAccentColor", s._embeddedThemeAccentColor.current()},
|
||||||
|
{"cloudThemeId", s._cloudThemeId.current()},
|
||||||
|
{"cloudThemeAccessHash", s._cloudThemeAccessHash.current()},
|
||||||
|
{"cloudThemeDocumentId", s._cloudThemeDocumentId.current()},
|
||||||
|
{"cloudThemeTitle", s._cloudThemeTitle.current()},
|
||||||
|
{"cloudThemeAccountId", s._cloudThemeAccountId.current()},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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._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));
|
||||||
|
s._cloudThemeAccessHash = j.value("cloudThemeAccessHash", uint64(0));
|
||||||
|
s._cloudThemeDocumentId = j.value("cloudThemeDocumentId", uint64(0));
|
||||||
|
s._cloudThemeTitle = j.value("cloudThemeTitle", QString());
|
||||||
|
s._cloudThemeAccountId = j.value("cloudThemeAccountId", uint64(0));
|
||||||
|
}
|
||||||
|
|
||||||
AyuSettings::AyuSettings()
|
AyuSettings::AyuSettings()
|
||||||
: _appIcon(AyuAssets::DEFAULT_ICON)
|
: _appIcon(AyuAssets::DEFAULT_ICON)
|
||||||
, _editedMark(Core::IsAppLaunched() ? tr::lng_edited(tr::now) : QString("edited")) {
|
, _editedMark(Core::IsAppLaunched() ? tr::lng_edited(tr::now) : QString("edited")) {
|
||||||
@@ -356,6 +469,14 @@ void AyuSettings::validate() {
|
|||||||
validateRange(_wideMultiplier, 0.5, 3.0, defaults._wideMultiplier);
|
validateRange(_wideMultiplier, 0.5, 3.0, defaults._wideMultiplier);
|
||||||
validateRange(_recentStickersCount, 1, 200, defaults._recentStickersCount);
|
validateRange(_recentStickersCount, 1, 200, defaults._recentStickersCount);
|
||||||
|
|
||||||
|
const auto embeddedType = _messageShotSettings._embeddedThemeType.current();
|
||||||
|
auto embeddedTypeValid = (embeddedType == -1) || (embeddedType >= 0 && embeddedType <= 3); // from Window::Theme::EmbeddedType::DayBlue to Window::Theme::EmbeddedType::NightGreen
|
||||||
|
if (!embeddedTypeValid) {
|
||||||
|
_messageShotSettings._embeddedThemeType = defaults._messageShotSettings._embeddedThemeType.current();
|
||||||
|
_messageShotSettings._embeddedThemeAccentColor = defaults._messageShotSettings._embeddedThemeAccentColor.current();
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (modified) {
|
if (modified) {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
@@ -904,7 +1025,8 @@ void to_json(nlohmann::json &j, const AyuSettings &s) {
|
|||||||
{"translationProvider", s._translationProvider.current()},
|
{"translationProvider", s._translationProvider.current()},
|
||||||
{"adaptiveCoverColor", s._adaptiveCoverColor.current()},
|
{"adaptiveCoverColor", s._adaptiveCoverColor.current()},
|
||||||
{"improveLinkPreviews", s._improveLinkPreviews.current()},
|
{"improveLinkPreviews", s._improveLinkPreviews.current()},
|
||||||
{"crashReporting", s._crashReporting.current()}
|
{"crashReporting", s._crashReporting.current()},
|
||||||
|
{"messageShotSettings", s._messageShotSettings}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,4 +1119,8 @@ void from_json(const nlohmann::json &j, AyuSettings &s) {
|
|||||||
s._adaptiveCoverColor = j.value("adaptiveCoverColor", defaults._adaptiveCoverColor.current());
|
s._adaptiveCoverColor = j.value("adaptiveCoverColor", defaults._adaptiveCoverColor.current());
|
||||||
s._improveLinkPreviews = j.value("improveLinkPreviews", defaults._improveLinkPreviews.current());
|
s._improveLinkPreviews = j.value("improveLinkPreviews", defaults._improveLinkPreviews.current());
|
||||||
s._crashReporting = j.value("crashReporting", defaults._crashReporting.current());
|
s._crashReporting = j.value("crashReporting", defaults._crashReporting.current());
|
||||||
|
|
||||||
|
if (j.contains("messageShotSettings") && j["messageShotSettings"].is_object()) {
|
||||||
|
j["messageShotSettings"].get_to(s._messageShotSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,6 +135,56 @@ private:
|
|||||||
void to_json(nlohmann::json &j, const GhostModeAccountSettings &s);
|
void to_json(nlohmann::json &j, const GhostModeAccountSettings &s);
|
||||||
void from_json(const nlohmann::json &j, GhostModeAccountSettings &s);
|
void from_json(const nlohmann::json &j, GhostModeAccountSettings &s);
|
||||||
|
|
||||||
|
class MessageShotSettings {
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool showBackground() const { return _showBackground.current(); }
|
||||||
|
[[nodiscard]] bool showDate() const { return _showDate.current(); }
|
||||||
|
[[nodiscard]] bool showReactions() const { return _showReactions.current(); }
|
||||||
|
[[nodiscard]] bool showColorfulReplies() const { return _showColorfulReplies.current(); }
|
||||||
|
[[nodiscard]] int embeddedThemeType() const { return _embeddedThemeType.current(); }
|
||||||
|
[[nodiscard]] uint32 embeddedThemeAccentColor() const { return _embeddedThemeAccentColor.current(); }
|
||||||
|
[[nodiscard]] uint64 cloudThemeId() const { return _cloudThemeId.current(); }
|
||||||
|
[[nodiscard]] uint64 cloudThemeAccessHash() const { return _cloudThemeAccessHash.current(); }
|
||||||
|
[[nodiscard]] uint64 cloudThemeDocumentId() const { return _cloudThemeDocumentId.current(); }
|
||||||
|
[[nodiscard]] const QString &cloudThemeTitle() const { return _cloudThemeTitle.current(); }
|
||||||
|
[[nodiscard]] uint64 cloudThemeAccountId() const { return _cloudThemeAccountId.current(); }
|
||||||
|
|
||||||
|
void setShowBackground(bool val);
|
||||||
|
void setShowDate(bool val);
|
||||||
|
void setShowReactions(bool val);
|
||||||
|
void setShowColorfulReplies(bool val);
|
||||||
|
|
||||||
|
void setEmbeddedTheme(int type, uint32 accentColor = 0);
|
||||||
|
void setCloudTheme(uint64 accountId, uint64 id, uint64 accessHash, uint64 documentId, const QString &title);
|
||||||
|
void clearTheme();
|
||||||
|
|
||||||
|
friend void to_json(nlohmann::json &j, const MessageShotSettings &s);
|
||||||
|
friend void from_json(const nlohmann::json &j, MessageShotSettings &s);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class AyuSettings;
|
||||||
|
[[nodiscard]] bool isCloudThemeEmpty() const;
|
||||||
|
void clearCloudThemeData();
|
||||||
|
|
||||||
|
rpl::variable<bool> _showBackground = true;
|
||||||
|
rpl::variable<bool> _showDate = false;
|
||||||
|
rpl::variable<bool> _showReactions = false;
|
||||||
|
rpl::variable<bool> _showColorfulReplies = false;
|
||||||
|
|
||||||
|
rpl::variable<int> _embeddedThemeType = -1;
|
||||||
|
rpl::variable<uint32> _embeddedThemeAccentColor = 0;
|
||||||
|
|
||||||
|
rpl::variable<uint64> _cloudThemeId = 0;
|
||||||
|
rpl::variable<uint64> _cloudThemeAccessHash = 0;
|
||||||
|
rpl::variable<uint64> _cloudThemeDocumentId = 0;
|
||||||
|
rpl::variable<QString> _cloudThemeTitle;
|
||||||
|
rpl::variable<uint64> _cloudThemeAccountId = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void to_json(nlohmann::json &j, const MessageShotSettings &s);
|
||||||
|
void from_json(const nlohmann::json &j, MessageShotSettings &s);
|
||||||
|
|
||||||
class AyuSettings {
|
class AyuSettings {
|
||||||
public:
|
public:
|
||||||
AyuSettings(const AyuSettings &) = delete;
|
AyuSettings(const AyuSettings &) = delete;
|
||||||
@@ -151,6 +201,9 @@ public:
|
|||||||
[[nodiscard]] static GhostModeAccountSettings &ghost(not_null<Main::Session*> session);
|
[[nodiscard]] static GhostModeAccountSettings &ghost(not_null<Main::Session*> session);
|
||||||
[[nodiscard]] static GhostModeAccountSettings &ghost(uint64 userId);
|
[[nodiscard]] static GhostModeAccountSettings &ghost(uint64 userId);
|
||||||
[[nodiscard]] static GhostModeAccountSettings &ghost();
|
[[nodiscard]] static GhostModeAccountSettings &ghost();
|
||||||
|
|
||||||
|
[[nodiscard]] MessageShotSettings &messageShotSettings() { return _messageShotSettings; }
|
||||||
|
[[nodiscard]] const MessageShotSettings &messageShotSettings() const { return _messageShotSettings; }
|
||||||
[[nodiscard]] bool useGlobalGhostMode() const { return _useGlobalGhostMode.current(); }
|
[[nodiscard]] bool useGlobalGhostMode() const { return _useGlobalGhostMode.current(); }
|
||||||
void setUseGlobalGhostMode(bool val);
|
void setUseGlobalGhostMode(bool val);
|
||||||
|
|
||||||
@@ -477,6 +530,8 @@ private:
|
|||||||
|
|
||||||
rpl::variable<bool> _useGlobalGhostMode = true;
|
rpl::variable<bool> _useGlobalGhostMode = true;
|
||||||
std::map<uint64, std::unique_ptr<GhostModeAccountSettings>> _ghostAccounts;
|
std::map<uint64, std::unique_ptr<GhostModeAccountSettings>> _ghostAccounts;
|
||||||
|
|
||||||
|
MessageShotSettings _messageShotSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
void to_json(nlohmann::json &j, const AyuSettings &s);
|
void to_json(nlohmann::json &j, const AyuSettings &s);
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
#include "qguiapplication.h"
|
#include "qguiapplication.h"
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/boxes/message_shot_box.h"
|
#include "ayu/ui/boxes/message_shot_box.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "data/data_cloud_themes.h"
|
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
@@ -39,22 +39,11 @@
|
|||||||
|
|
||||||
namespace AyuFeatures::MessageShot {
|
namespace AyuFeatures::MessageShot {
|
||||||
|
|
||||||
ShotConfig *config;
|
ShotConfig *config = nullptr;
|
||||||
|
|
||||||
Window::Theme::EmbeddedType defaultSelected = Window::Theme::EmbeddedType(-1);
|
|
||||||
std::optional<QColor> defaultSelectedColor;
|
|
||||||
|
|
||||||
std::optional<Data::CloudTheme> customSelected;
|
|
||||||
|
|
||||||
rpl::event_stream<> resetDefaultSelectedStream;
|
|
||||||
rpl::event_stream<> resetCustomSelectedStream;
|
|
||||||
|
|
||||||
bool takingShot = false;
|
bool takingShot = false;
|
||||||
bool choosingTheme = false;
|
bool choosingTheme = false;
|
||||||
|
|
||||||
rpl::event_stream<Data::CloudTheme> themeChosenStream;
|
|
||||||
rpl::event_stream<style::palette> paletteChosenStream;
|
|
||||||
|
|
||||||
void setShotConfig(ShotConfig &config) {
|
void setShotConfig(ShotConfig &config) {
|
||||||
MessageShot::config = &config;
|
MessageShot::config = &config;
|
||||||
}
|
}
|
||||||
@@ -67,62 +56,15 @@ ShotConfig getShotConfig() {
|
|||||||
return *config;
|
return *config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDefaultSelected(const Window::Theme::EmbeddedType type) {
|
|
||||||
resetCustomSelected();
|
|
||||||
defaultSelected = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::Theme::EmbeddedType getSelectedFromDefault() {
|
|
||||||
return defaultSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDefaultSelectedColor(const QColor color) {
|
|
||||||
resetCustomSelected();
|
|
||||||
defaultSelectedColor = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<QColor> getSelectedColorFromDefault() {
|
|
||||||
return defaultSelectedColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCustomSelected(const Data::CloudTheme theme) {
|
|
||||||
resetDefaultSelected();
|
|
||||||
customSelected = theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Data::CloudTheme> getSelectedFromCustom() {
|
|
||||||
return customSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetDefaultSelected() {
|
|
||||||
defaultSelected = Window::Theme::EmbeddedType(-1);
|
|
||||||
resetDefaultSelectedStream.fire({});
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetCustomSelected() {
|
|
||||||
customSelected = std::nullopt;
|
|
||||||
resetCustomSelectedStream.fire({});
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> resetDefaultSelectedEvents() {
|
|
||||||
return resetDefaultSelectedStream.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> resetCustomSelectedEvents() {
|
|
||||||
return resetCustomSelectedStream.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ignoreRender(RenderPart part) {
|
bool ignoreRender(RenderPart part) {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ignoreDate = !config->showDate;
|
const auto &s = AyuSettings::getInstance().messageShotSettings();
|
||||||
const auto ignoreReactions = !config->showReactions;
|
return isTakingShot()
|
||||||
|
&& ((part == RenderPart::Date && !s.showDate())
|
||||||
return isTakingShot() &&
|
|| (part == RenderPart::Reactions && !s.showReactions()));
|
||||||
((part == RenderPart::Date && ignoreDate) ||
|
|
||||||
(part == RenderPart::Reactions && ignoreReactions));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTakingShot() {
|
bool isTakingShot() {
|
||||||
@@ -138,22 +80,6 @@ bool isChoosingTheme() {
|
|||||||
return choosingTheme;
|
return choosingTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<Data::CloudTheme> themeChosen() {
|
|
||||||
return themeChosenStream.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTheme(Data::CloudTheme theme) {
|
|
||||||
themeChosenStream.fire(std::move(theme));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPalette(style::palette &palette) {
|
|
||||||
paletteChosenStream.fire(std::move(palette));
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<style::palette> paletteChosen() {
|
|
||||||
return paletteChosenStream.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
class MessageShotDelegate final : public HistoryView::DefaultElementDelegate
|
class MessageShotDelegate final : public HistoryView::DefaultElementDelegate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -375,7 +301,7 @@ void Make(not_null<QWidget*> box, const ShotConfig &config, const Fn<void(QImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto showBackground = config.showBackground;
|
const auto showBackground = AyuSettings::getInstance().messageShotSettings().showBackground();
|
||||||
auto render = [=, messages = std::move(messages), delegate = std::move(delegate)](bool final)
|
auto render = [=, messages = std::move(messages), delegate = std::move(delegate)](bool final)
|
||||||
{
|
{
|
||||||
takingShot = true;
|
takingShot = true;
|
||||||
@@ -512,28 +438,38 @@ void Make(not_null<QWidget*> box, const ShotConfig &config, const Fn<void(QImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wrapper(not_null<HistoryView::ListWidget*> widget, Fn<void()> clearSelected) {
|
namespace {
|
||||||
const auto items = widget->getSelectedIds();
|
|
||||||
if (items.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto session = &widget->session();
|
// 🥀🥀🥀
|
||||||
const auto controller = widget->session().tryResolveWindow();
|
|
||||||
if (!controller) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto messages = ranges::views::all(items)
|
std::shared_ptr<Ui::ChatStyle> BuildShotChatStyle(
|
||||||
|
not_null<Window::SessionController*> controller) {
|
||||||
|
const auto &shot = AyuSettings::getInstance().messageShotSettings();
|
||||||
|
const auto hasSavedTheme = shot.embeddedThemeType() != -1
|
||||||
|
|| shot.cloudThemeId() != 0;
|
||||||
|
const auto persistedPalette = getPersistedPalette();
|
||||||
|
if (hasSavedTheme && persistedPalette) {
|
||||||
|
return std::make_shared<Ui::ChatStyle>(persistedPalette.get());
|
||||||
|
}
|
||||||
|
return std::make_shared<Ui::ChatStyle>(controller->chatStyle());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ResolveMessage>
|
||||||
|
void ShowMessageShotBox(
|
||||||
|
ResolveMessage resolveMessage,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
const MessageIdsList &ids,
|
||||||
|
Fn<void()> clearSelected) {
|
||||||
|
const auto messages = ranges::views::all(ids)
|
||||||
| ranges::views::transform([=](const auto item)
|
| ranges::views::transform([=](const auto item)
|
||||||
{
|
{
|
||||||
return gsl::not_null(session->data().message(item));
|
return resolveMessage(item);
|
||||||
})
|
})
|
||||||
| ranges::to_vector;
|
| ranges::to_vector;
|
||||||
|
|
||||||
const AyuFeatures::MessageShot::ShotConfig config = {
|
const AyuFeatures::MessageShot::ShotConfig config = {
|
||||||
controller,
|
controller,
|
||||||
std::make_shared<Ui::ChatStyle>(controller->chatStyle()),
|
BuildShotChatStyle(controller),
|
||||||
messages,
|
messages,
|
||||||
};
|
};
|
||||||
auto box = Box<MessageShotBox>(config);
|
auto box = Box<MessageShotBox>(config);
|
||||||
@@ -545,4 +481,43 @@ void Wrapper(not_null<HistoryView::ListWidget*> widget, Fn<void()> clearSelected
|
|||||||
Ui::show(std::move(box));
|
Ui::show(std::move(box));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Widget, typename GetIds>
|
||||||
|
void WrapperImpl(
|
||||||
|
not_null<Widget*> widget,
|
||||||
|
GetIds getIds,
|
||||||
|
Fn<void()> clearSelected) {
|
||||||
|
const auto items = getIds(widget);
|
||||||
|
if (items.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto session = &widget->session();
|
||||||
|
const auto controller = widget->session().tryResolveWindow();
|
||||||
|
if (!controller) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowMessageShotBox(
|
||||||
|
[=](const auto item) { return gsl::not_null(session->data().message(item)); },
|
||||||
|
controller,
|
||||||
|
items,
|
||||||
|
std::move(clearSelected));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wrapper(not_null<HistoryView::ListWidget*> widget, Fn<void()> clearSelected) {
|
||||||
|
WrapperImpl(
|
||||||
|
widget,
|
||||||
|
[](const auto widget) { return widget->getSelectedIds(); },
|
||||||
|
std::move(clearSelected));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wrapper(not_null<HistoryInner*> widget, Fn<void()> clearSelected) {
|
||||||
|
WrapperImpl(
|
||||||
|
widget,
|
||||||
|
[](const auto widget) { return widget->getSelectedItems(); },
|
||||||
|
std::move(clearSelected));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
// Copyright @Radolyn, 2025
|
// Copyright @Radolyn, 2025
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ayu/features/message_shot/message_shot_theme_state.h"
|
||||||
#include "history/view/history_view_list_widget.h"
|
#include "history/view/history_view_list_widget.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/themes/window_themes_embedded.h"
|
|
||||||
|
class HistoryInner;
|
||||||
|
|
||||||
namespace AyuFeatures::MessageShot {
|
namespace AyuFeatures::MessageShot {
|
||||||
|
|
||||||
@@ -18,10 +20,6 @@ struct ShotConfig
|
|||||||
not_null<Window::SessionController*> controller;
|
not_null<Window::SessionController*> controller;
|
||||||
std::shared_ptr<Ui::ChatStyle> st;
|
std::shared_ptr<Ui::ChatStyle> st;
|
||||||
std::vector<not_null<HistoryItem*>> messages;
|
std::vector<not_null<HistoryItem*>> messages;
|
||||||
|
|
||||||
bool showBackground = true;
|
|
||||||
bool showDate;
|
|
||||||
bool showReactions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RenderPart
|
enum RenderPart
|
||||||
@@ -34,41 +32,18 @@ void setShotConfig(ShotConfig &config);
|
|||||||
void resetShotConfig();
|
void resetShotConfig();
|
||||||
ShotConfig getShotConfig();
|
ShotConfig getShotConfig();
|
||||||
|
|
||||||
// for default themes
|
|
||||||
void setDefaultSelected(Window::Theme::EmbeddedType type);
|
|
||||||
Window::Theme::EmbeddedType getSelectedFromDefault();
|
|
||||||
|
|
||||||
void setDefaultSelectedColor(QColor color);
|
|
||||||
std::optional<QColor> getSelectedColorFromDefault();
|
|
||||||
|
|
||||||
// for custom themes
|
|
||||||
void setCustomSelected(Data::CloudTheme theme);
|
|
||||||
std::optional<Data::CloudTheme> getSelectedFromCustom();
|
|
||||||
|
|
||||||
// resets
|
|
||||||
void resetDefaultSelected();
|
|
||||||
void resetCustomSelected();
|
|
||||||
|
|
||||||
rpl::producer<> resetDefaultSelectedEvents();
|
|
||||||
rpl::producer<> resetCustomSelectedEvents();
|
|
||||||
|
|
||||||
bool ignoreRender(RenderPart part);
|
bool ignoreRender(RenderPart part);
|
||||||
bool isTakingShot();
|
bool isTakingShot();
|
||||||
|
|
||||||
bool isChoosingTheme();
|
bool isChoosingTheme();
|
||||||
bool setChoosingTheme(bool val);
|
bool setChoosingTheme(bool val);
|
||||||
|
|
||||||
void setTheme(Data::CloudTheme theme);
|
|
||||||
rpl::producer<Data::CloudTheme> themeChosen();
|
|
||||||
|
|
||||||
void setPalette(style::palette &palette);
|
|
||||||
rpl::producer<style::palette> paletteChosen();
|
|
||||||
|
|
||||||
// util
|
// util
|
||||||
QColor makeDefaultBackgroundColor();
|
QColor makeDefaultBackgroundColor();
|
||||||
|
|
||||||
void Make(not_null<QWidget*> box, const ShotConfig &config, const Fn<void(QImage&,bool)>& callback);
|
void Make(not_null<QWidget*> box, const ShotConfig &config, const Fn<void(QImage&,bool)>& callback);
|
||||||
|
|
||||||
void Wrapper(not_null<HistoryView::ListWidget*> widget, Fn<void()> clearSelected);
|
void Wrapper(not_null<HistoryView::ListWidget*> widget, Fn<void()> clearSelected);
|
||||||
|
void Wrapper(not_null<HistoryInner*> widget, Fn<void()> clearSelected);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,408 @@
|
|||||||
|
// This is the source code of AyuGram for Desktop.
|
||||||
|
//
|
||||||
|
// We do not and cannot prevent the use of our code,
|
||||||
|
// but be respectful and credit the original author.
|
||||||
|
//
|
||||||
|
// Copyright @Radolyn, 2025
|
||||||
|
#include "message_shot_theme_state.h"
|
||||||
|
|
||||||
|
#include "lang_auto.h"
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "ui/style/style_palette_colorizer.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/themes/window_theme_preview.h"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace AyuFeatures::MessageShot {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Window::Theme::EmbeddedType defaultSelected = Window::Theme::EmbeddedType(-1);
|
||||||
|
std::optional<QColor> defaultSelectedColor;
|
||||||
|
std::optional<Data::CloudTheme> customSelected;
|
||||||
|
|
||||||
|
rpl::event_stream<> resetDefaultSelectedStream;
|
||||||
|
rpl::event_stream<> resetCustomSelectedStream;
|
||||||
|
rpl::event_stream<Data::CloudTheme> themeChosenStream;
|
||||||
|
rpl::event_stream<style::palette> paletteChosenStream;
|
||||||
|
|
||||||
|
std::shared_ptr<style::palette> persistedPalette;
|
||||||
|
std::unordered_set<uint64> refreshedThemeAccounts;
|
||||||
|
|
||||||
|
std::optional<Data::CloudTheme> findCloudThemeById(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
uint64 id) {
|
||||||
|
const auto &chat = session->data().cloudThemes().chatThemes();
|
||||||
|
const auto &list = session->data().cloudThemes().list();
|
||||||
|
auto it = ranges::find(chat, id, &Data::CloudTheme::id);
|
||||||
|
if (it != chat.end()) {
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
it = ranges::find(list, id, &Data::CloudTheme::id);
|
||||||
|
if (it != list.end()) {
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryApplyCloudThemePalette(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const Data::CloudTheme &theme,
|
||||||
|
std::shared_ptr<style::palette> palette) {
|
||||||
|
if (!theme.documentId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto document = session->data().document(theme.documentId);
|
||||||
|
const auto documentView = document->createMediaView();
|
||||||
|
auto preview = Window::Theme::PreviewFromFile(
|
||||||
|
documentView->bytes(),
|
||||||
|
document->location().name(),
|
||||||
|
theme);
|
||||||
|
if (!preview) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
palette->reset();
|
||||||
|
palette->load(preview->instance.palette.save());
|
||||||
|
setCustomSelected(theme);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedThemeApplyResult tryApplyEmbeddedThemePalette(
|
||||||
|
const MessageShotSettings &shot,
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied) {
|
||||||
|
if (shot.embeddedThemeType() == -1) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto type = static_cast<Window::Theme::EmbeddedType>(shot.embeddedThemeType());
|
||||||
|
const auto themes = Window::Theme::EmbeddedThemes();
|
||||||
|
const auto it = ranges::find(themes, type, &Window::Theme::EmbeddedScheme::type);
|
||||||
|
if (it == themes.end()) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto accentRgb = shot.embeddedThemeAccentColor();
|
||||||
|
if (it->path.isEmpty() && type == Window::Theme::EmbeddedType::Default) {
|
||||||
|
style::palette embeddedPalette;
|
||||||
|
const auto accent = (accentRgb != 0)
|
||||||
|
? std::optional<QColor>(QColor::fromRgb(accentRgb))
|
||||||
|
: std::nullopt;
|
||||||
|
Window::Theme::PreparePaletteCallback(false, accent)(embeddedPalette);
|
||||||
|
palette->reset();
|
||||||
|
palette->load(embeddedPalette.save());
|
||||||
|
setDefaultSelected(type);
|
||||||
|
if (accent) {
|
||||||
|
setDefaultSelectedColor(*accent);
|
||||||
|
}
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
return SavedThemeApplyResult::AppliedSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accentRgb != 0) {
|
||||||
|
const auto color = QColor::fromRgb(accentRgb);
|
||||||
|
const auto colorizer = Window::Theme::ColorizerFrom(*it, color);
|
||||||
|
auto instance = Window::Theme::Instance();
|
||||||
|
if (!Window::Theme::LoadFromFile(it->path, &instance, nullptr, nullptr, colorizer)) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
palette->reset();
|
||||||
|
palette->load(instance.palette.save());
|
||||||
|
setDefaultSelected(type);
|
||||||
|
setDefaultSelectedColor(color);
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
return SavedThemeApplyResult::AppliedSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Data::CloudTheme cloud;
|
||||||
|
const auto preview = Window::Theme::PreviewFromFile(
|
||||||
|
QByteArray(),
|
||||||
|
it->path,
|
||||||
|
cloud);
|
||||||
|
if (!preview) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
palette->reset();
|
||||||
|
palette->load(preview->instance.palette.save());
|
||||||
|
setDefaultSelected(type);
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
return SavedThemeApplyResult::AppliedSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyCloudThemeAsync(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const Data::CloudTheme &theme,
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied) {
|
||||||
|
if (!theme.documentId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto weak = base::make_weak(controller);
|
||||||
|
const auto document = session->data().document(theme.documentId);
|
||||||
|
const auto documentView = document->createMediaView();
|
||||||
|
|
||||||
|
document->save(
|
||||||
|
Data::FileOriginTheme(theme.id, theme.accessHash),
|
||||||
|
QString());
|
||||||
|
|
||||||
|
const auto apply = [=] {
|
||||||
|
if (!weak) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto preview = Window::Theme::PreviewFromFile(
|
||||||
|
documentView->bytes(),
|
||||||
|
document->location().name(),
|
||||||
|
theme);
|
||||||
|
if (!preview) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
palette->reset();
|
||||||
|
palette->load(preview->instance.palette.save());
|
||||||
|
setCustomSelected(theme);
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (documentView->loaded()) {
|
||||||
|
apply();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->downloaderTaskFinished(
|
||||||
|
) | rpl::filter([=] {
|
||||||
|
return documentView->loaded();
|
||||||
|
}) | rpl::take(1) | rpl::on_next([=] {
|
||||||
|
apply();
|
||||||
|
}, controller->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultSelected(const Window::Theme::EmbeddedType type) {
|
||||||
|
resetCustomSelected();
|
||||||
|
defaultSelected = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::Theme::EmbeddedType getSelectedFromDefault() {
|
||||||
|
return defaultSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultSelectedColor(const QColor color) {
|
||||||
|
resetCustomSelected();
|
||||||
|
defaultSelectedColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QColor> getSelectedColorFromDefault() {
|
||||||
|
return defaultSelectedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCustomSelected(const Data::CloudTheme theme) {
|
||||||
|
resetDefaultSelected();
|
||||||
|
customSelected = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Data::CloudTheme> getSelectedFromCustom() {
|
||||||
|
return customSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetDefaultSelected() {
|
||||||
|
defaultSelected = Window::Theme::EmbeddedType(-1);
|
||||||
|
defaultSelectedColor = std::nullopt;
|
||||||
|
resetDefaultSelectedStream.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetCustomSelected() {
|
||||||
|
customSelected = std::nullopt;
|
||||||
|
resetCustomSelectedStream.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> resetDefaultSelectedEvents() {
|
||||||
|
return resetDefaultSelectedStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> resetCustomSelectedEvents() {
|
||||||
|
return resetCustomSelectedStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTheme(Data::CloudTheme theme) {
|
||||||
|
themeChosenStream.fire(std::move(theme));
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<Data::CloudTheme> themeChosen() {
|
||||||
|
return themeChosenStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPalette(const style::palette &palette) {
|
||||||
|
paletteChosenStream.fire_copy(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<style::palette> paletteChosen() {
|
||||||
|
return paletteChosenStream.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensureChatThemesRefreshed() {
|
||||||
|
const auto accountId = AyuSettings::getInstance().messageShotSettings().cloudThemeAccountId();
|
||||||
|
if (!accountId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!refreshedThemeAccounts.emplace(accountId).second) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto session = getSession(accountId);
|
||||||
|
if (!session) {
|
||||||
|
refreshedThemeAccounts.erase(accountId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->data().cloudThemes().refreshChatThemes();
|
||||||
|
session->data().cloudThemes().refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
// from `std::vector<EmbeddedScheme> EmbeddedThemes()`
|
||||||
|
QString embeddedThemeDisplayName(Window::Theme::EmbeddedType type) {
|
||||||
|
switch (type) {
|
||||||
|
case Window::Theme::EmbeddedType::Default:
|
||||||
|
return tr::lng_settings_theme_classic(tr::now);
|
||||||
|
case Window::Theme::EmbeddedType::DayBlue:
|
||||||
|
return tr::lng_settings_theme_day(tr::now);
|
||||||
|
case Window::Theme::EmbeddedType::Night:
|
||||||
|
return tr::lng_settings_theme_tinted(tr::now);
|
||||||
|
case Window::Theme::EmbeddedType::NightGreen:
|
||||||
|
return tr::lng_settings_theme_night(tr::now);
|
||||||
|
}
|
||||||
|
return tr::ayu_MessageShotThemeDefault(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString resolveThemeName() {
|
||||||
|
const auto &shot = AyuSettings::getInstance().messageShotSettings();
|
||||||
|
if (shot.cloudThemeId() != 0) {
|
||||||
|
return shot.cloudThemeTitle();
|
||||||
|
}
|
||||||
|
if (shot.embeddedThemeType() != -1) {
|
||||||
|
const auto type = static_cast<Window::Theme::EmbeddedType>(shot.embeddedThemeType());
|
||||||
|
return embeddedThemeDisplayName(type);
|
||||||
|
}
|
||||||
|
return tr::ayu_MessageShotThemeDefault(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<style::palette> getPersistedPalette() {
|
||||||
|
return persistedPalette;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPersistedPalette(std::shared_ptr<style::palette> palette) {
|
||||||
|
persistedPalette = std::move(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedThemeApplyResult applySavedThemePalette(
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied) {
|
||||||
|
const auto &shot = AyuSettings::getInstance().messageShotSettings();
|
||||||
|
|
||||||
|
if (shot.embeddedThemeType() != -1) {
|
||||||
|
return tryApplyEmbeddedThemePalette(shot, std::move(palette), std::move(onApplied));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shot.cloudThemeId() == 0) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto session = getSession(shot.cloudThemeAccountId());
|
||||||
|
if (!session) {
|
||||||
|
return SavedThemeApplyResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto fromList = findCloudThemeById(session, shot.cloudThemeId())) {
|
||||||
|
if (tryApplyCloudThemePalette(session, *fromList, palette)) {
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
return SavedThemeApplyResult::AppliedSync;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data::CloudTheme saved;
|
||||||
|
saved.id = shot.cloudThemeId();
|
||||||
|
saved.accessHash = shot.cloudThemeAccessHash();
|
||||||
|
saved.documentId = shot.cloudThemeDocumentId();
|
||||||
|
saved.title = shot.cloudThemeTitle();
|
||||||
|
if (tryApplyCloudThemePalette(session, saved, palette)) {
|
||||||
|
if (onApplied) {
|
||||||
|
onApplied();
|
||||||
|
}
|
||||||
|
return SavedThemeApplyResult::AppliedSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SavedThemeApplyResult::AwaitingAsync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subscribeToCloudThemeLoad(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied) {
|
||||||
|
const auto &shot = AyuSettings::getInstance().messageShotSettings();
|
||||||
|
if (shot.cloudThemeId() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto session = getSession(shot.cloudThemeAccountId());
|
||||||
|
if (!session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSelectedFromCustom().has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id = shot.cloudThemeId();
|
||||||
|
const auto weak = base::make_weak(controller);
|
||||||
|
const auto tryApplyFromTheme = [=](const Data::CloudTheme &theme) {
|
||||||
|
applyCloudThemeAsync(controller, session, theme, palette, onApplied);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (const auto theme = findCloudThemeById(session, id)) {
|
||||||
|
tryApplyFromTheme(*theme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto found = std::make_shared<bool>(false);
|
||||||
|
const auto tryFind = [=] {
|
||||||
|
if (*found || !weak) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto theme = findCloudThemeById(session, id)) {
|
||||||
|
*found = true;
|
||||||
|
tryApplyFromTheme(*theme);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
session->data().cloudThemes().chatThemesUpdated(
|
||||||
|
) | rpl::on_next(tryFind, controller->lifetime());
|
||||||
|
session->data().cloudThemes().updated(
|
||||||
|
) | rpl::on_next(tryFind, controller->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// This is the source code of AyuGram for Desktop.
|
||||||
|
//
|
||||||
|
// We do not and cannot prevent the use of our code,
|
||||||
|
// but be respectful and credit the original author.
|
||||||
|
//
|
||||||
|
// Copyright @Radolyn, 2025
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_cloud_themes.h"
|
||||||
|
#include "window/themes/window_themes_embedded.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
#include "ui/style/style_core_palette.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace AyuFeatures::MessageShot {
|
||||||
|
|
||||||
|
enum class SavedThemeApplyResult {
|
||||||
|
AppliedSync,
|
||||||
|
AwaitingAsync,
|
||||||
|
Failed,
|
||||||
|
};
|
||||||
|
|
||||||
|
void setDefaultSelected(Window::Theme::EmbeddedType type);
|
||||||
|
Window::Theme::EmbeddedType getSelectedFromDefault();
|
||||||
|
|
||||||
|
void setDefaultSelectedColor(QColor color);
|
||||||
|
std::optional<QColor> getSelectedColorFromDefault();
|
||||||
|
|
||||||
|
void setCustomSelected(Data::CloudTheme theme);
|
||||||
|
std::optional<Data::CloudTheme> getSelectedFromCustom();
|
||||||
|
|
||||||
|
void resetDefaultSelected();
|
||||||
|
void resetCustomSelected();
|
||||||
|
|
||||||
|
rpl::producer<> resetDefaultSelectedEvents();
|
||||||
|
rpl::producer<> resetCustomSelectedEvents();
|
||||||
|
|
||||||
|
void setTheme(Data::CloudTheme theme);
|
||||||
|
rpl::producer<Data::CloudTheme> themeChosen();
|
||||||
|
|
||||||
|
void setPalette(const style::palette &palette);
|
||||||
|
rpl::producer<style::palette> paletteChosen();
|
||||||
|
|
||||||
|
void ensureChatThemesRefreshed();
|
||||||
|
QString resolveThemeName();
|
||||||
|
QString embeddedThemeDisplayName(Window::Theme::EmbeddedType type);
|
||||||
|
std::shared_ptr<style::palette> getPersistedPalette();
|
||||||
|
void setPersistedPalette(std::shared_ptr<style::palette> palette);
|
||||||
|
SavedThemeApplyResult applySavedThemePalette(
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied);
|
||||||
|
void subscribeToCloudThemeLoad(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
std::shared_ptr<style::palette> palette,
|
||||||
|
Fn<void()> onApplied);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
// Copyright @Radolyn, 2025
|
// Copyright @Radolyn, 2025
|
||||||
#include "message_shot_box.h"
|
#include "message_shot_box.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include "styles/style_ayu_styles.h"
|
#include "styles/style_ayu_styles.h"
|
||||||
@@ -16,8 +17,6 @@
|
|||||||
#include "ayu/ui/components/image_view.h"
|
#include "ayu/ui/components/image_view.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "core/core_settings.h"
|
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
@@ -37,13 +36,36 @@ void MessageShotBox::prepare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessageShotBox::setupContent() {
|
void MessageShotBox::setupContent() {
|
||||||
_selectedPalette = std::make_shared<style::palette>();
|
_selectedPalette = AyuFeatures::MessageShot::getPersistedPalette();
|
||||||
|
if (!_selectedPalette) {
|
||||||
|
_selectedPalette = std::make_shared<style::palette>();
|
||||||
|
}
|
||||||
|
AyuFeatures::MessageShot::setPersistedPalette(_selectedPalette);
|
||||||
|
|
||||||
const auto &settings = AyuSettings::getInstance();
|
AyuFeatures::MessageShot::ensureChatThemesRefreshed();
|
||||||
const auto savedShowColorfulReplies = !settings.simpleQuotesAndReplies();
|
|
||||||
|
auto &settings = AyuSettings::getInstance();
|
||||||
|
auto &shotSettings = settings.messageShotSettings();
|
||||||
|
const auto savedSimpleQuotesAndReplies = settings.simpleQuotesAndReplies();
|
||||||
|
settings.setSimpleQuotesAndReplies(!shotSettings.showColorfulReplies());
|
||||||
|
|
||||||
using namespace Settings;
|
using namespace Settings;
|
||||||
|
|
||||||
|
auto savedThemeApplyResult = AyuFeatures::MessageShot::SavedThemeApplyResult::Failed;
|
||||||
|
const auto hasSavedTheme = shotSettings.embeddedThemeType() != -1
|
||||||
|
|| shotSettings.cloudThemeId() != 0;
|
||||||
|
if (hasSavedTheme) {
|
||||||
|
savedThemeApplyResult = AyuFeatures::MessageShot::applySavedThemePalette(
|
||||||
|
_selectedPalette,
|
||||||
|
nullptr);
|
||||||
|
if (savedThemeApplyResult != AyuFeatures::MessageShot::SavedThemeApplyResult::Failed) {
|
||||||
|
_config.st = std::make_shared<Ui::ChatStyle>(_selectedPalette.get());
|
||||||
|
} else {
|
||||||
|
shotSettings.clearTheme();
|
||||||
|
_config.st = std::make_shared<Ui::ChatStyle>(_config.controller->chatStyle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AyuFeatures::MessageShot::setShotConfig(_config);
|
AyuFeatures::MessageShot::setShotConfig(_config);
|
||||||
|
|
||||||
setTitle(rpl::single(QString("Message Shot")));
|
setTitle(rpl::single(QString("Message Shot")));
|
||||||
@@ -81,8 +103,23 @@ void MessageShotBox::setupContent() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (savedThemeApplyResult == AyuFeatures::MessageShot::SavedThemeApplyResult::AwaitingAsync) {
|
||||||
|
const auto weakBox = base::make_weak(this);
|
||||||
|
AyuFeatures::MessageShot::subscribeToCloudThemeLoad(
|
||||||
|
_config.controller,
|
||||||
|
_selectedPalette,
|
||||||
|
[=] {
|
||||||
|
if (!weakBox) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_config.st = std::make_shared<Ui::ChatStyle>(_selectedPalette.get());
|
||||||
|
updatePreview();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
auto selectedTheme =
|
auto selectedTheme =
|
||||||
content->lifetime().make_state<rpl::variable<QString>>(tr::ayu_MessageShotThemeDefault(tr::now));
|
content->lifetime().make_state<rpl::variable<QString>>(
|
||||||
|
AyuFeatures::MessageShot::resolveThemeName());
|
||||||
|
|
||||||
AddButtonWithLabel(
|
AddButtonWithLabel(
|
||||||
content,
|
content,
|
||||||
@@ -101,8 +138,20 @@ void MessageShotBox::setupContent() {
|
|||||||
_selectedPalette->reset();
|
_selectedPalette->reset();
|
||||||
_selectedPalette->load(palette.save());
|
_selectedPalette->load(palette.save());
|
||||||
|
|
||||||
_config.st = std::make_shared<Ui::ChatStyle>(
|
_config.st = std::make_shared<Ui::ChatStyle>(_selectedPalette.get());
|
||||||
_selectedPalette.get());
|
|
||||||
|
auto &shot = AyuSettings::getInstance().messageShotSettings();
|
||||||
|
const auto embedded = AyuFeatures::MessageShot::getSelectedFromDefault();
|
||||||
|
const auto cloud = AyuFeatures::MessageShot::getSelectedFromCustom();
|
||||||
|
if (cloud.has_value()) {
|
||||||
|
const auto accountId = _config.controller->session().userId().bare;
|
||||||
|
shot.setCloudTheme(accountId, cloud->id, cloud->accessHash, cloud->documentId, cloud->title);
|
||||||
|
} else if (embedded != Window::Theme::EmbeddedType(-1)) {
|
||||||
|
const auto color = AyuFeatures::MessageShot::getSelectedColorFromDefault();
|
||||||
|
shot.setEmbeddedTheme(static_cast<int>(embedded), color ? color->rgb() : 0);
|
||||||
|
} else {
|
||||||
|
shot.clearTheme();
|
||||||
|
}
|
||||||
|
|
||||||
updatePreview();
|
updatePreview();
|
||||||
},
|
},
|
||||||
@@ -128,13 +177,12 @@ void MessageShotBox::setupContent() {
|
|||||||
content,
|
content,
|
||||||
tr::ayu_MessageShotShowBackground(),
|
tr::ayu_MessageShotShowBackground(),
|
||||||
st::settingsButtonNoIcon
|
st::settingsButtonNoIcon
|
||||||
)->toggleOn(rpl::single(_config.showBackground)
|
)->toggleOn(rpl::single(shotSettings.showBackground())
|
||||||
)->toggledValue(
|
)->toggledValue(
|
||||||
) | on_next(
|
) | rpl::skip(1) | on_next(
|
||||||
[=](bool enabled)
|
[=](bool enabled)
|
||||||
{
|
{
|
||||||
_config.showBackground = enabled;
|
AyuSettings::getInstance().messageShotSettings().setShowBackground(enabled);
|
||||||
|
|
||||||
updatePreview();
|
updatePreview();
|
||||||
},
|
},
|
||||||
content->lifetime());
|
content->lifetime());
|
||||||
@@ -143,13 +191,12 @@ void MessageShotBox::setupContent() {
|
|||||||
content,
|
content,
|
||||||
tr::ayu_MessageShotShowDate(),
|
tr::ayu_MessageShotShowDate(),
|
||||||
st::settingsButtonNoIcon
|
st::settingsButtonNoIcon
|
||||||
)->toggleOn(rpl::single(_config.showDate)
|
)->toggleOn(rpl::single(shotSettings.showDate())
|
||||||
)->toggledValue(
|
)->toggledValue(
|
||||||
) | on_next(
|
) | rpl::skip(1) | on_next(
|
||||||
[=](bool enabled)
|
[=](bool enabled)
|
||||||
{
|
{
|
||||||
_config.showDate = enabled;
|
AyuSettings::getInstance().messageShotSettings().setShowDate(enabled);
|
||||||
|
|
||||||
updatePreview();
|
updatePreview();
|
||||||
},
|
},
|
||||||
content->lifetime());
|
content->lifetime());
|
||||||
@@ -158,13 +205,12 @@ void MessageShotBox::setupContent() {
|
|||||||
content,
|
content,
|
||||||
tr::ayu_MessageShotShowReactions(),
|
tr::ayu_MessageShotShowReactions(),
|
||||||
st::settingsButtonNoIcon
|
st::settingsButtonNoIcon
|
||||||
)->toggleOn(rpl::single(_config.showReactions)
|
)->toggleOn(rpl::single(shotSettings.showReactions())
|
||||||
)->toggledValue(
|
)->toggledValue(
|
||||||
) | on_next(
|
) | rpl::skip(1) | on_next(
|
||||||
[=](bool enabled)
|
[=](bool enabled)
|
||||||
{
|
{
|
||||||
_config.showReactions = enabled;
|
AyuSettings::getInstance().messageShotSettings().setShowReactions(enabled);
|
||||||
|
|
||||||
updatePreview();
|
updatePreview();
|
||||||
},
|
},
|
||||||
content->lifetime());
|
content->lifetime());
|
||||||
@@ -174,12 +220,14 @@ void MessageShotBox::setupContent() {
|
|||||||
tr::ayu_MessageShotShowColorfulReplies(),
|
tr::ayu_MessageShotShowColorfulReplies(),
|
||||||
st::settingsButtonNoIcon
|
st::settingsButtonNoIcon
|
||||||
);
|
);
|
||||||
latestToggle->toggleOn(rpl::single(savedShowColorfulReplies)
|
latestToggle->toggleOn(rpl::single(shotSettings.showColorfulReplies())
|
||||||
)->toggledValue(
|
)->toggledValue(
|
||||||
) | on_next(
|
) | rpl::skip(1) | on_next(
|
||||||
[=](bool enabled)
|
[=](bool enabled)
|
||||||
{
|
{
|
||||||
AyuSettings::getInstance().setSimpleQuotesAndReplies(!enabled);
|
auto ¤tSettings = AyuSettings::getInstance();
|
||||||
|
currentSettings.messageShotSettings().setShowColorfulReplies(enabled);
|
||||||
|
currentSettings.setSimpleQuotesAndReplies(!enabled);
|
||||||
|
|
||||||
_config.st = std::make_shared<Ui::ChatStyle>(_config.st.get());
|
_config.st = std::make_shared<Ui::ChatStyle>(_config.st.get());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
@@ -226,12 +274,11 @@ void MessageShotBox::setupContent() {
|
|||||||
AyuFeatures::MessageShot::resetDefaultSelected();
|
AyuFeatures::MessageShot::resetDefaultSelected();
|
||||||
AyuFeatures::MessageShot::resetShotConfig();
|
AyuFeatures::MessageShot::resetShotConfig();
|
||||||
|
|
||||||
AyuSettings::getInstance().setSimpleQuotesAndReplies(!savedShowColorfulReplies);
|
AyuSettings::getInstance().setSimpleQuotesAndReplies(savedSimpleQuotesAndReplies);
|
||||||
},
|
},
|
||||||
content->lifetime());
|
content->lifetime());
|
||||||
|
|
||||||
setDimensionsToContent(boxWidth, content);
|
setDimensionsToContent(boxWidth, content);
|
||||||
|
|
||||||
// scroll to the end
|
|
||||||
scrollToWidget(latestToggle);
|
scrollToWidget(latestToggle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "theme_selector_box.h"
|
#include "theme_selector_box.h"
|
||||||
|
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "ayu/features/message_shot/message_shot.h"
|
#include "ayu/features/message_shot/message_shot_theme_state.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
@@ -140,6 +140,9 @@ void ThemeSelectorBox::setupContent() {
|
|||||||
documentView->bytes(),
|
documentView->bytes(),
|
||||||
document->location().name(),
|
document->location().name(),
|
||||||
theme);
|
theme);
|
||||||
|
if (!preview) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_selectedPalette = preview->instance.palette;
|
_selectedPalette = preview->instance.palette;
|
||||||
|
|
||||||
@@ -168,7 +171,11 @@ void ThemeSelectorBox::setupContent() {
|
|||||||
AyuFeatures::MessageShot::paletteChosen(
|
AyuFeatures::MessageShot::paletteChosen(
|
||||||
) | rpl::on_next([=](const auto &palette)
|
) | rpl::on_next([=](const auto &palette)
|
||||||
{
|
{
|
||||||
_themeNames.fire(tr::ayu_MessageShotThemeDefault(tr::now));
|
const auto type = AyuFeatures::MessageShot::getSelectedFromDefault();
|
||||||
|
const auto name = (type != Window::Theme::EmbeddedType(-1))
|
||||||
|
? AyuFeatures::MessageShot::embeddedThemeDisplayName(type)
|
||||||
|
: tr::ayu_MessageShotThemeDefault(tr::now);
|
||||||
|
_themeNames.fire(QString(name));
|
||||||
_selectedPalette = palette;
|
_selectedPalette = palette;
|
||||||
},
|
},
|
||||||
lifetime());
|
lifetime());
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ const auto kZalgoPattern = QStringLiteral(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Main::Session *getSession(ID userId) {
|
Main::Session *getSession(ID userId) {
|
||||||
|
if (!userId) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
for (const auto &[index, account] : Core::App().domain().accounts()) {
|
for (const auto &[index, account] : Core::App().domain().accounts()) {
|
||||||
if (const auto session = account->maybeSession()) {
|
if (const auto session = account->maybeSession()) {
|
||||||
if (session->userId().bare == userId) {
|
if (session->userId().bare == userId) {
|
||||||
|
|||||||
@@ -196,7 +196,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "ayu/features/message_shot/message_shot.h"
|
#include "ayu/features/message_shot/message_shot.h"
|
||||||
#include "ayu/features/forward/ayu_forward.h"
|
#include "ayu/features/forward/ayu_forward.h"
|
||||||
#include "ayu/ui/boxes/message_shot_box.h"
|
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -9401,32 +9400,13 @@ void HistoryWidget::confirmDeleteSelected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::messageShotSelected() {
|
void HistoryWidget::messageShotSelected() {
|
||||||
if (!_list) return;
|
if (!_list) {
|
||||||
|
|
||||||
auto items = getSelectedItems();
|
|
||||||
if (items.empty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto messages = ranges::views::all(items)
|
AyuFeatures::MessageShot::Wrapper(
|
||||||
| ranges::views::transform([this](const auto fullId)
|
_list.data(),
|
||||||
{
|
[=] { clearSelected(); });
|
||||||
return gsl::not_null(session().data().message(fullId));
|
|
||||||
})
|
|
||||||
| ranges::to_vector;
|
|
||||||
|
|
||||||
const AyuFeatures::MessageShot::ShotConfig config = {
|
|
||||||
controller(),
|
|
||||||
std::make_shared<Ui::ChatStyle>(controller()->chatStyle()),
|
|
||||||
messages
|
|
||||||
};
|
|
||||||
auto box = Box<MessageShotBox>(config);
|
|
||||||
const auto raw = box.data();
|
|
||||||
raw->boxClosing() | rpl::on_next([=]
|
|
||||||
{
|
|
||||||
if (raw->tookShot()) clearSelected();
|
|
||||||
}, raw->lifetime());
|
|
||||||
Ui::show(std::move(box));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::escape() {
|
void HistoryWidget::escape() {
|
||||||
|
|||||||
@@ -1529,6 +1529,25 @@ void SetupDefaultThemes(
|
|||||||
|
|
||||||
const auto updateMessageShotPalette = [=](const QString &path)
|
const auto updateMessageShotPalette = [=](const QString &path)
|
||||||
{
|
{
|
||||||
|
if (path.isEmpty()) { // for Default theme (otherwise doesn't dispaly name properly)
|
||||||
|
style::palette embeddedPalette;
|
||||||
|
const auto color = AyuFeatures::MessageShot::getSelectedColorFromDefault();
|
||||||
|
Window::Theme::PreparePaletteCallback(false, color)(embeddedPalette);
|
||||||
|
AyuFeatures::MessageShot::setPalette(embeddedPalette);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (const auto color = AyuFeatures::MessageShot::getSelectedColorFromDefault()) {
|
||||||
|
const auto type = AyuFeatures::MessageShot::getSelectedFromDefault();
|
||||||
|
const auto scheme = ranges::find(kSchemesList, type, &Scheme::type);
|
||||||
|
if (scheme != end(kSchemesList)) {
|
||||||
|
const auto colorizer = ColorizerFrom(*scheme, *color);
|
||||||
|
auto instance = Window::Theme::Instance();
|
||||||
|
if (Window::Theme::LoadFromFile(path, &instance, nullptr, nullptr, colorizer)) {
|
||||||
|
AyuFeatures::MessageShot::setPalette(instance.palette);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const Data::CloudTheme theme;
|
const Data::CloudTheme theme;
|
||||||
if (const auto preview = PreviewFromFile(QByteArray(), path, theme)) {
|
if (const auto preview = PreviewFromFile(QByteArray(), path, theme)) {
|
||||||
AyuFeatures::MessageShot::setPalette(preview->instance.palette);
|
AyuFeatures::MessageShot::setPalette(preview->instance.palette);
|
||||||
|
|||||||
Reference in New Issue
Block a user