mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
feat: message shot
feat: send image as sticker fix: don't query author pack if ID == 0 fix: use predefined confirmation boxes
This commit is contained in:
parent
0cf36db010
commit
9c71aba5d1
41 changed files with 1417 additions and 292 deletions
|
@ -134,18 +134,20 @@ PRIVATE
|
||||||
ayu/ui/sections/edited/edited_log_item.h
|
ayu/ui/sections/edited/edited_log_item.h
|
||||||
ayu/ui/sections/edited/edited_log_section.cpp
|
ayu/ui/sections/edited/edited_log_section.cpp
|
||||||
ayu/ui/sections/edited/edited_log_section.h
|
ayu/ui/sections/edited/edited_log_section.h
|
||||||
ayu/ui/boxes/voice_confirmation_box.cpp
|
ayu/ui/boxes/server_read_confirmation_box.cpp
|
||||||
ayu/ui/boxes/voice_confirmation_box.h
|
ayu/ui/boxes/server_read_confirmation_box.h
|
||||||
ayu/ui/boxes/message_history_box.cpp
|
|
||||||
ayu/ui/boxes/message_history_box.h
|
|
||||||
ayu/ui/boxes/confirmation_box.cpp
|
|
||||||
ayu/ui/boxes/confirmation_box.h
|
|
||||||
ayu/ui/boxes/edit_deleted_mark.cpp
|
ayu/ui/boxes/edit_deleted_mark.cpp
|
||||||
ayu/ui/boxes/edit_deleted_mark.h
|
ayu/ui/boxes/edit_deleted_mark.h
|
||||||
ayu/ui/boxes/edit_edited_mark.cpp
|
ayu/ui/boxes/edit_edited_mark.cpp
|
||||||
ayu/ui/boxes/edit_edited_mark.h
|
ayu/ui/boxes/edit_edited_mark.h
|
||||||
ayu/ui/boxes/font_selector.cpp
|
ayu/ui/boxes/font_selector.cpp
|
||||||
ayu/ui/boxes/font_selector.h
|
ayu/ui/boxes/font_selector.h
|
||||||
|
ayu/ui/boxes/theme_selector_box.cpp
|
||||||
|
ayu/ui/boxes/theme_selector_box.h
|
||||||
|
ayu/ui/boxes/message_shot_box.cpp
|
||||||
|
ayu/ui/boxes/message_shot_box.h
|
||||||
|
ayu/ui/components/image_view.cpp
|
||||||
|
ayu/ui/components/image_view.h
|
||||||
ayu/sync/ayu_sync_controller.cpp
|
ayu/sync/ayu_sync_controller.cpp
|
||||||
ayu/sync/ayu_sync_controller.h
|
ayu/sync/ayu_sync_controller.h
|
||||||
ayu/sync/models.h
|
ayu/sync/models.h
|
||||||
|
@ -164,6 +166,8 @@ PRIVATE
|
||||||
ayu/features/streamer_mode/streamer_mode_windows.cpp
|
ayu/features/streamer_mode/streamer_mode_windows.cpp
|
||||||
ayu/features/streamer_mode/streamer_mode_linux.cpp
|
ayu/features/streamer_mode/streamer_mode_linux.cpp
|
||||||
ayu/features/streamer_mode/streamer_mode.h
|
ayu/features/streamer_mode/streamer_mode.h
|
||||||
|
ayu/features/messageshot/message_shot.cpp
|
||||||
|
ayu/features/messageshot/message_shot.h
|
||||||
ayu/database/entities.h
|
ayu/database/entities.h
|
||||||
ayu/database/ayu_database.cpp
|
ayu/database/ayu_database.cpp
|
||||||
ayu/database/ayu_database.h
|
ayu/database/ayu_database.h
|
||||||
|
|
|
@ -4799,6 +4799,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"ayu_MonospaceFont" = "Monospace font";
|
"ayu_MonospaceFont" = "Monospace font";
|
||||||
"ayu_FontDefault" = "Default";
|
"ayu_FontDefault" = "Default";
|
||||||
"ayu_CustomizeFontTitle" = "Customize font";
|
"ayu_CustomizeFontTitle" = "Customize font";
|
||||||
|
"ayu_MessageShotTopBarText" = "Shot";
|
||||||
|
"ayu_MessageShotPreview" = "Preview";
|
||||||
|
"ayu_MessageShotPreferences" = "Preferences";
|
||||||
|
"ayu_MessageShotCopy" = "Copy";
|
||||||
|
"ayu_MessageShotSave" = "Save";
|
||||||
|
"ayu_MessageShotTheme" = "Theme";
|
||||||
|
"ayu_MessageShotThemeDefault" = "Default";
|
||||||
|
"ayu_MessageShotThemeSelectTitle" = "Select message theme";
|
||||||
|
"ayu_MessageShotThemeApply" = "Apply";
|
||||||
|
"ayu_MessageShotShowDate" = "Show date";
|
||||||
|
"ayu_MessageShotShowReactions" = "Show reactions";
|
||||||
|
"ayu_MessageShotShowColorfulReplies" = "Show colorful replies";
|
||||||
|
"ayu_SendAsSticker" = "Send as Sticker";
|
||||||
"ayu_AyuForwardStatusForwarding" = "Forwarding messages…";
|
"ayu_AyuForwardStatusForwarding" = "Forwarding messages…";
|
||||||
"ayu_AyuForwardStatusLoadingMedia" = "Loading media…";
|
"ayu_AyuForwardStatusLoadingMedia" = "Loading media…";
|
||||||
"ayu_AyuForwardForwardingDescription" = "Please keep this window open while AyuGram is forwarding your messages.";
|
"ayu_AyuForwardForwardingDescription" = "Please keep this window open while AyuGram is forwarding your messages.";
|
||||||
|
|
425
Telegram/SourceFiles/ayu/features/messageshot/message_shot.cpp
Normal file
425
Telegram/SourceFiles/ayu/features/messageshot/message_shot.cpp
Normal file
|
@ -0,0 +1,425 @@
|
||||||
|
// 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, 2023
|
||||||
|
#include "message_shot.h"
|
||||||
|
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
|
#include "data/data_cloud_themes.h"
|
||||||
|
#include "data/data_photo.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "history/history_inner_widget.h"
|
||||||
|
#include "history/view/media/history_view_media.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "qguiapplication.h"
|
||||||
|
#include "ayu/ui/boxes/message_shot_box.h"
|
||||||
|
#include "boxes/abstract_box.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/view/history_view_message.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_ayu_styles.h"
|
||||||
|
#include "ui/layers/box_content.h"
|
||||||
|
#include "ui/effects/path_shift_gradient.h"
|
||||||
|
|
||||||
|
namespace AyuFeatures::MessageShot
|
||||||
|
{
|
||||||
|
|
||||||
|
ShotConfig *config;
|
||||||
|
|
||||||
|
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 choosingTheme = false;
|
||||||
|
|
||||||
|
rpl::event_stream<Data::CloudTheme> themeChosenStream;
|
||||||
|
rpl::event_stream<style::palette> paletteChosenStream;
|
||||||
|
|
||||||
|
void setShotConfig(ShotConfig &config)
|
||||||
|
{
|
||||||
|
MessageShot::config = &config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetShotConfig()
|
||||||
|
{
|
||||||
|
config = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShotConfig getShotConfig()
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (!config) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ignoreDate = !config->showDate;
|
||||||
|
const auto ignoreReactions = !config->showReactions;
|
||||||
|
|
||||||
|
return isTakingShot() &&
|
||||||
|
((part == RenderPart::Date && ignoreDate) ||
|
||||||
|
(part == RenderPart::Reactions && ignoreReactions));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTakingShot()
|
||||||
|
{
|
||||||
|
return takingShot;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setChoosingTheme(bool val)
|
||||||
|
{
|
||||||
|
choosingTheme = val;
|
||||||
|
return choosingTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isChoosingTheme()
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageShotDelegate(
|
||||||
|
not_null<QWidget *> parent,
|
||||||
|
not_null<Ui::ChatStyle *> st,
|
||||||
|
Fn<void()> update);
|
||||||
|
|
||||||
|
bool elementAnimationsPaused() override;
|
||||||
|
not_null<Ui::PathShiftGradient *> elementPathShiftGradient() override;
|
||||||
|
HistoryView::Context elementContext() override;
|
||||||
|
bool elementIsChatWide() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const not_null<QWidget *> _parent;
|
||||||
|
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageShotDelegate::MessageShotDelegate(
|
||||||
|
not_null<QWidget *> parent,
|
||||||
|
not_null<Ui::ChatStyle *> st,
|
||||||
|
Fn<void()> update)
|
||||||
|
: _parent(parent)
|
||||||
|
, _pathGradient(HistoryView::MakePathShiftGradient(st, update))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageShotDelegate::elementAnimationsPaused()
|
||||||
|
{
|
||||||
|
return _parent->window()->isActiveWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MessageShotDelegate::elementPathShiftGradient()
|
||||||
|
-> not_null<Ui::PathShiftGradient *>
|
||||||
|
{
|
||||||
|
return _pathGradient.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryView::Context MessageShotDelegate::elementContext()
|
||||||
|
{
|
||||||
|
return HistoryView::Context::AdminLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageShotDelegate::elementIsChatWide()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage removePadding(const QImage &original)
|
||||||
|
{
|
||||||
|
if (original.isNull()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int minX = original.width();
|
||||||
|
int minY = original.height();
|
||||||
|
int maxX = 0;
|
||||||
|
int maxY = 0;
|
||||||
|
|
||||||
|
for (int x = 0; x < original.width(); ++x) {
|
||||||
|
for (int y = 0; y < original.height(); ++y) {
|
||||||
|
if (qAlpha(original.pixel(x, y)) != 0) {
|
||||||
|
minX = std::min(minX, x);
|
||||||
|
minY = std::min(minY, y);
|
||||||
|
maxX = std::max(maxX, x);
|
||||||
|
maxY = std::max(maxY, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minX > maxX || minY > maxY) {
|
||||||
|
LOG(("Image is fully transparent ?"));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect bounds(minX, minY, maxX - minX + 1, maxY - minY + 1);
|
||||||
|
return original.copy(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage addPadding(const QImage &original, int padding)
|
||||||
|
{
|
||||||
|
if (original.isNull()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage paddedImage(
|
||||||
|
original.width() + padding * 2 * style::DevicePixelRatio(),
|
||||||
|
original.height() + padding * 2 * style::DevicePixelRatio(),
|
||||||
|
QImage::Format_ARGB32_Premultiplied
|
||||||
|
);
|
||||||
|
paddedImage.fill(Qt::transparent);
|
||||||
|
|
||||||
|
Painter painter(&paddedImage);
|
||||||
|
painter.drawImage(padding, padding, original);
|
||||||
|
painter.end();
|
||||||
|
|
||||||
|
return paddedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Make(not_null<QWidget *> box, const ShotConfig &config)
|
||||||
|
{
|
||||||
|
const auto controller = config.controller;
|
||||||
|
const auto st = config.st;
|
||||||
|
const auto messages = config.messages;
|
||||||
|
|
||||||
|
if (messages.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
takingShot = true;
|
||||||
|
|
||||||
|
auto delegate = std::make_unique<MessageShotDelegate>(box,
|
||||||
|
st.get(),
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
box->update();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::unordered_map<not_null<HistoryItem *>, std::shared_ptr<HistoryView::Element>> createdViews;
|
||||||
|
createdViews.reserve(messages.size());
|
||||||
|
for (const auto &message : messages) {
|
||||||
|
createdViews.emplace(message, message->createView(delegate.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto getView = [=](not_null<HistoryItem *> msg)
|
||||||
|
{
|
||||||
|
return createdViews.at(msg).get();
|
||||||
|
};
|
||||||
|
|
||||||
|
// recalculate blocks
|
||||||
|
if (messages.size() > 1) {
|
||||||
|
auto currentMsg = messages[0].get();
|
||||||
|
|
||||||
|
for (auto i = 1; i != messages.size(); ++i) {
|
||||||
|
const auto nextMsg = messages[i].get();
|
||||||
|
if (getView(nextMsg)->isHidden()) {
|
||||||
|
getView(nextMsg)->setDisplayDate(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const auto viewDate = getView(currentMsg)->dateTime();
|
||||||
|
const auto nextDate = getView(nextMsg)->dateTime();
|
||||||
|
getView(nextMsg)->setDisplayDate(nextDate.date() != viewDate.date());
|
||||||
|
auto attached = getView(nextMsg)->computeIsAttachToPrevious(getView(currentMsg));
|
||||||
|
getView(nextMsg)->setAttachToPrevious(attached, getView(currentMsg));
|
||||||
|
getView(currentMsg)->setAttachToNext(attached, getView(nextMsg));
|
||||||
|
currentMsg = nextMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getView(messages[messages.size() - 1])->setAttachToNext(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getView(messages[0])->setAttachToPrevious(false);
|
||||||
|
getView(messages[0])->setAttachToNext(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the size of the image
|
||||||
|
int width = st::msgMaxWidth + (st::boxPadding.left() + st::boxPadding.right());
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < messages.size(); i++) {
|
||||||
|
const auto &message = messages[i];
|
||||||
|
const auto view = getView(message);
|
||||||
|
|
||||||
|
view->itemDataChanged(); // refresh reactions
|
||||||
|
height += view->resizeGetHeight(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// width *= style::DevicePixelRatio();
|
||||||
|
height *= style::DevicePixelRatio();
|
||||||
|
|
||||||
|
// create the image
|
||||||
|
QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
|
||||||
|
const auto viewport = QRect(0, 0, width, height);
|
||||||
|
|
||||||
|
Painter p(&image);
|
||||||
|
|
||||||
|
// draw the messages
|
||||||
|
int y = 0;
|
||||||
|
for (int i = 0; i < messages.size(); i++) {
|
||||||
|
const auto &message = messages[i];
|
||||||
|
const auto view = getView(message);
|
||||||
|
|
||||||
|
const auto displayUserpic = view->displayFromPhoto() || message->isPost();
|
||||||
|
|
||||||
|
const auto rect = QRect(0, y, width, view->height());
|
||||||
|
|
||||||
|
auto context = controller->defaultChatTheme()->preparePaintContext(
|
||||||
|
st.get(),
|
||||||
|
viewport,
|
||||||
|
rect,
|
||||||
|
true);
|
||||||
|
|
||||||
|
// hides too much
|
||||||
|
// if (AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
|
// context.skipDrawingParts = Ui::ChatPaintContext::SkipDrawingParts::Surrounding;
|
||||||
|
// }
|
||||||
|
|
||||||
|
p.translate(0, y);
|
||||||
|
view->draw(p, context);
|
||||||
|
p.translate(0, -y);
|
||||||
|
|
||||||
|
if (displayUserpic) {
|
||||||
|
const auto picX = st::msgMargin.left();
|
||||||
|
const auto picY = y + view->height() - st::msgPhotoSize;
|
||||||
|
|
||||||
|
auto userpicView =
|
||||||
|
!message->displayFrom()->activeUserpicView().null()
|
||||||
|
? message->displayFrom()->activeUserpicView()
|
||||||
|
: message->displayFrom()->createUserpicView();
|
||||||
|
message->displayFrom()->paintUserpic(p, userpicView, picX, picY, st::msgPhotoSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += view->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
takingShot = false;
|
||||||
|
|
||||||
|
const auto overlay = addPadding(removePadding(image), 4);
|
||||||
|
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wrapper(not_null<HistoryView::ListWidget *> widget)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
| ranges::views::transform([=](const auto item)
|
||||||
|
{
|
||||||
|
return gsl::not_null(session->data().message(item));
|
||||||
|
})
|
||||||
|
| ranges::to_vector;
|
||||||
|
|
||||||
|
const AyuFeatures::MessageShot::ShotConfig config = {
|
||||||
|
controller,
|
||||||
|
std::make_shared<Ui::ChatStyle>(controller->chatStyle()),
|
||||||
|
messages,
|
||||||
|
};
|
||||||
|
auto box = Box<MessageShotBox>(config);
|
||||||
|
Ui::show(std::move(box));
|
||||||
|
}
|
||||||
|
}
|
69
Telegram/SourceFiles/ayu/features/messageshot/message_shot.h
Normal file
69
Telegram/SourceFiles/ayu/features/messageshot/message_shot.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// 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, 2023
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
#include "history/view/history_view_list_widget.h"
|
||||||
|
#include "ui/chat/chat_style.h"
|
||||||
|
#include "window/themes/window_themes_embedded.h"
|
||||||
|
|
||||||
|
namespace AyuFeatures::MessageShot {
|
||||||
|
|
||||||
|
struct ShotConfig {
|
||||||
|
not_null<Window::SessionController*> controller;
|
||||||
|
std::shared_ptr<Ui::ChatStyle> st;
|
||||||
|
std::vector<not_null<HistoryItem*>> messages;
|
||||||
|
|
||||||
|
bool showDate;
|
||||||
|
bool showReactions;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RenderPart
|
||||||
|
{
|
||||||
|
Date,
|
||||||
|
Reactions,
|
||||||
|
};
|
||||||
|
|
||||||
|
void setShotConfig(ShotConfig& config);
|
||||||
|
void resetShotConfig();
|
||||||
|
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 isTakingShot();
|
||||||
|
|
||||||
|
bool isChoosingTheme();
|
||||||
|
bool setChoosingTheme(bool val);
|
||||||
|
|
||||||
|
void setTheme(Data::CloudTheme theme);
|
||||||
|
rpl::producer<Data::CloudTheme> themeChosen();
|
||||||
|
|
||||||
|
void setPalette(style::palette& palette);
|
||||||
|
rpl::producer<style::palette> paletteChosen();
|
||||||
|
|
||||||
|
QImage Make(not_null<QWidget*> box, const ShotConfig &config);
|
||||||
|
|
||||||
|
void Wrapper(not_null<HistoryView::ListWidget*> widget);
|
||||||
|
|
||||||
|
}
|
|
@ -23,3 +23,5 @@ cpSpacingY: 8px;
|
||||||
cpIconSize: 64px;
|
cpIconSize: 64px;
|
||||||
|
|
||||||
recentStickersLimitPadding: margins(22px, 4px, 22px, 8px);
|
recentStickersLimitPadding: margins(22px, 4px, 22px, 8px);
|
||||||
|
imageViewPadding: margins(22px, 10px, 22px, 10px);
|
||||||
|
imageViewInnerPadding: margins(16px, 16px, 16px, 16px);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
// Copyright @Radolyn, 2023
|
// Copyright @Radolyn, 2023
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "lang/lang_cloud_manager.h"
|
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "base/binary_guard.h"
|
#include "base/binary_guard.h"
|
||||||
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
// 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, 2023
|
|
||||||
#include "message_history_box.h"
|
|
||||||
#include "ayu/ayu_settings.h"
|
|
||||||
#include "ayu/database/ayu_database.h"
|
|
||||||
#include "ayu/messages/ayu_messages_controller.h"
|
|
||||||
|
|
||||||
#include "history/history.h"
|
|
||||||
#include "settings/settings_common.h"
|
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "styles/style_layers.h"
|
|
||||||
#include "ui/effects/scroll_content_shadow.h"
|
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
|
|
||||||
using namespace Settings;
|
|
||||||
|
|
||||||
namespace AyuUi
|
|
||||||
{
|
|
||||||
|
|
||||||
MessageHistoryBox::MessageHistoryBox(QWidget *, HistoryItem *item)
|
|
||||||
: _content(this), _scroll(base::make_unique_q<Ui::ScrollArea>(this, st::boxScroll))
|
|
||||||
{
|
|
||||||
setupControls();
|
|
||||||
addEditedMessagesToLayout(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageHistoryBox::setupControls()
|
|
||||||
{
|
|
||||||
_content.create(this);
|
|
||||||
|
|
||||||
_content->resizeToWidth(st::boxWideWidth);
|
|
||||||
_content->moveToLeft(0, 0);
|
|
||||||
|
|
||||||
_content->heightValue(
|
|
||||||
) | start_to_stream(_contentHeight, _content->lifetime());
|
|
||||||
|
|
||||||
_scroll->setOwnedWidget(
|
|
||||||
object_ptr<RpWidget>::fromRaw(_content));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageHistoryBox::resizeEvent(QResizeEvent *e)
|
|
||||||
{
|
|
||||||
_scroll->resize(width(), height() - st::boxPhotoPadding.top() - st::boxPadding.bottom());
|
|
||||||
_scroll->move(0, st::boxPadding.top());
|
|
||||||
|
|
||||||
if (_content) {
|
|
||||||
_content->resize(_scroll->width(), _content->height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageHistoryBox::prepare()
|
|
||||||
{
|
|
||||||
setTitle(tr::ayu_EditsHistoryTitle());
|
|
||||||
|
|
||||||
setDimensions(st::boxWideWidth, 900);
|
|
||||||
SetupShadowsToScrollContent(this, _scroll, _contentHeight.events());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageHistoryBox::addEditedMessagesToLayout(HistoryItem *item)
|
|
||||||
{
|
|
||||||
auto messages = AyuMessages::getInstance().getEditedMessages(item);
|
|
||||||
if (messages.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &message : messages) {
|
|
||||||
AddSkip(_content);
|
|
||||||
AddDividerText(_content, rpl::single(QString::fromStdString(message.text)));
|
|
||||||
AddSkip(_content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
// 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, 2023
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "history/history_item.h"
|
|
||||||
#include "ui/layers/box_content.h"
|
|
||||||
#include "ui/widgets/scroll_area.h"
|
|
||||||
#include "ui/wrap/vertical_layout.h"
|
|
||||||
|
|
||||||
namespace AyuUi
|
|
||||||
{
|
|
||||||
|
|
||||||
class MessageHistoryBox : public Ui::BoxContent
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MessageHistoryBox(QWidget *, HistoryItem *item);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void prepare() override;
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setupControls();
|
|
||||||
|
|
||||||
void addEditedMessagesToLayout(HistoryItem *item);
|
|
||||||
|
|
||||||
object_ptr<Ui::VerticalLayout> _content;
|
|
||||||
const base::unique_qptr<Ui::ScrollArea> _scroll;
|
|
||||||
|
|
||||||
rpl::event_stream<int> _contentHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
202
Telegram/SourceFiles/ayu/ui/boxes/message_shot_box.cpp
Normal file
202
Telegram/SourceFiles/ayu/ui/boxes/message_shot_box.cpp
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
// 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, 2023
|
||||||
|
#include "message_shot_box.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include "styles/style_ayu_styles.h"
|
||||||
|
|
||||||
|
#include "boxes/abstract_box.h"
|
||||||
|
#include "ayu/ui/components/image_view.h"
|
||||||
|
#include "core/core_settings.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "lang_auto.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_common.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
|
#include "theme_selector_box.h"
|
||||||
|
#include "ayu/ayu_settings.h"
|
||||||
|
|
||||||
|
MessageShotBox::MessageShotBox(
|
||||||
|
QWidget *parent,
|
||||||
|
AyuFeatures::MessageShot::ShotConfig config)
|
||||||
|
: _config(std::move(config))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotBox::prepare()
|
||||||
|
{
|
||||||
|
setupContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShotBox::setupContent()
|
||||||
|
{
|
||||||
|
_selectedPalette = std::make_shared<style::palette>();
|
||||||
|
|
||||||
|
const auto settings = &AyuSettings::getInstance();
|
||||||
|
const auto savedShowColorfulReplies = !settings->simpleQuotesAndReplies;
|
||||||
|
|
||||||
|
using namespace Settings;
|
||||||
|
|
||||||
|
AyuFeatures::MessageShot::setShotConfig(_config);
|
||||||
|
|
||||||
|
setTitle(rpl::single(QString("Message Shot")));
|
||||||
|
|
||||||
|
auto wrap = object_ptr<Ui::VerticalLayout>(this);
|
||||||
|
const auto content = wrap.data();
|
||||||
|
setInnerWidget(object_ptr<Ui::OverrideMargins>(this, std::move(wrap)));
|
||||||
|
|
||||||
|
AddSubsectionTitle(content, tr::ayu_MessageShotPreview());
|
||||||
|
|
||||||
|
const auto imageView = content->add(object_ptr<ImageView>(content), st::imageViewPadding);
|
||||||
|
|
||||||
|
AddSkip(content);
|
||||||
|
AddDivider(content);
|
||||||
|
AddSkip(content);
|
||||||
|
AddSubsectionTitle(content, tr::ayu_MessageShotPreferences());
|
||||||
|
|
||||||
|
const auto updatePreview = [=]
|
||||||
|
{
|
||||||
|
const auto image = AyuFeatures::MessageShot::Make(this, _config);
|
||||||
|
imageView->setImage(image);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto selectedTheme =
|
||||||
|
content->lifetime().make_state<rpl::variable<QString> >(tr::ayu_MessageShotThemeDefault(tr::now));
|
||||||
|
|
||||||
|
AddButtonWithLabel(
|
||||||
|
content,
|
||||||
|
tr::ayu_MessageShotTheme(),
|
||||||
|
selectedTheme->value(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->addClickHandler(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
AyuFeatures::MessageShot::setChoosingTheme(true);
|
||||||
|
|
||||||
|
auto box = Box<ThemeSelectorBox>(_config.controller);
|
||||||
|
box->paletteSelected() | rpl::start_with_next(
|
||||||
|
[=](const style::palette &palette) mutable
|
||||||
|
{
|
||||||
|
_selectedPalette->reset();
|
||||||
|
_selectedPalette->load(palette.save());
|
||||||
|
|
||||||
|
_config.st = std::make_shared<Ui::ChatStyle>(
|
||||||
|
_selectedPalette.get());
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
box->themeNameChanged() | rpl::start_with_next(
|
||||||
|
[=](const QString &name)
|
||||||
|
{
|
||||||
|
selectedTheme->force_assign(name);
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
box->boxClosing() | rpl::start_with_next(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
AyuFeatures::MessageShot::setChoosingTheme(false);
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
Ui::show(std::move(box), Ui::LayerOption::KeepOther);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddButtonWithIcon(
|
||||||
|
content,
|
||||||
|
tr::ayu_MessageShotShowDate(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(rpl::single(false)
|
||||||
|
)->toggledValue(
|
||||||
|
) | start_with_next(
|
||||||
|
[=](bool enabled)
|
||||||
|
{
|
||||||
|
_config.showDate = enabled;
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
AddButtonWithIcon(
|
||||||
|
content,
|
||||||
|
tr::ayu_MessageShotShowReactions(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(rpl::single(false)
|
||||||
|
)->toggledValue(
|
||||||
|
) | start_with_next(
|
||||||
|
[=](bool enabled)
|
||||||
|
{
|
||||||
|
_config.showReactions = enabled;
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
AddButtonWithIcon(
|
||||||
|
content,
|
||||||
|
tr::ayu_MessageShotShowColorfulReplies(),
|
||||||
|
st::settingsButtonNoIcon
|
||||||
|
)->toggleOn(rpl::single(savedShowColorfulReplies)
|
||||||
|
)->toggledValue(
|
||||||
|
) | start_with_next(
|
||||||
|
[=](bool enabled)
|
||||||
|
{
|
||||||
|
const auto settings = &AyuSettings::getInstance();
|
||||||
|
settings->set_simpleQuotesAndReplies(!enabled);
|
||||||
|
|
||||||
|
_config.st = std::make_shared<Ui::ChatStyle>(_config.st.get());
|
||||||
|
updatePreview();
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
AddSkip(content);
|
||||||
|
|
||||||
|
addButton(tr::ayu_MessageShotSave(),
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
const auto image = imageView->getImage();
|
||||||
|
const auto path = QFileDialog::getSaveFileName(
|
||||||
|
this,
|
||||||
|
tr::lng_save_file(tr::now),
|
||||||
|
QString(),
|
||||||
|
"*.png");
|
||||||
|
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
image.save(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addButton(tr::ayu_MessageShotCopy(),
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
QGuiApplication::clipboard()->setImage(imageView->getImage());
|
||||||
|
});
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
|
||||||
|
const auto boxWidth = imageView->getImage().width() + (st::boxPadding.left() + st::boxPadding.right()) * 4;
|
||||||
|
|
||||||
|
boxClosing() | rpl::start_with_next(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
AyuFeatures::MessageShot::resetCustomSelected();
|
||||||
|
AyuFeatures::MessageShot::resetDefaultSelected();
|
||||||
|
AyuFeatures::MessageShot::resetShotConfig();
|
||||||
|
|
||||||
|
const auto settings = &AyuSettings::getInstance();
|
||||||
|
settings->set_simpleQuotesAndReplies(!savedShowColorfulReplies);
|
||||||
|
},
|
||||||
|
content->lifetime());
|
||||||
|
|
||||||
|
setDimensionsToContent(boxWidth, content);
|
||||||
|
}
|
25
Telegram/SourceFiles/ayu/ui/boxes/message_shot_box.h
Normal file
25
Telegram/SourceFiles/ayu/ui/boxes/message_shot_box.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// 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, 2023
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
#include "ui/layers/box_content.h"
|
||||||
|
|
||||||
|
class MessageShotBox : public Ui::BoxContent {
|
||||||
|
public:
|
||||||
|
MessageShotBox(QWidget* parent, AyuFeatures::MessageShot::ShotConfig config);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void prepare() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupContent();
|
||||||
|
|
||||||
|
AyuFeatures::MessageShot::ShotConfig _config;
|
||||||
|
std::shared_ptr<style::palette> _selectedPalette;
|
||||||
|
|
||||||
|
};
|
|
@ -4,15 +4,14 @@
|
||||||
// but be respectful and credit the original author.
|
// but be respectful and credit the original author.
|
||||||
//
|
//
|
||||||
// Copyright @Radolyn, 2023
|
// Copyright @Radolyn, 2023
|
||||||
#include "confirmation_box.h"
|
#include "server_read_confirmation_box.h"
|
||||||
|
|
||||||
#include "lang_auto.h"
|
#include "lang_auto.h"
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "ui/text/text_utilities.h"
|
|
||||||
#include "window/window_peer_menu.h"
|
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
namespace AyuUi
|
namespace AyuUi
|
190
Telegram/SourceFiles/ayu/ui/boxes/theme_selector_box.cpp
Normal file
190
Telegram/SourceFiles/ayu/ui/boxes/theme_selector_box.cpp
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
// 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, 2023
|
||||||
|
#include "theme_selector_box.h"
|
||||||
|
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "lang_auto.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_chat.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/wrap/slide_wrap.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/themes/window_theme_preview.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
|
#include "window/themes/window_themes_cloud_list.h"
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
ThemeSelectorBox::ThemeSelectorBox(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::SessionController *> controller)
|
||||||
|
: _controller(controller)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<style::palette> ThemeSelectorBox::paletteSelected()
|
||||||
|
{
|
||||||
|
return _palettes.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> ThemeSelectorBox::themeNameChanged()
|
||||||
|
{
|
||||||
|
return _themeNames.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSelectorBox::prepare()
|
||||||
|
{
|
||||||
|
setupContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSelectorBox::setupContent()
|
||||||
|
{
|
||||||
|
using namespace Settings;
|
||||||
|
|
||||||
|
setTitle(tr::ayu_MessageShotThemeSelectTitle());
|
||||||
|
|
||||||
|
auto wrap2 = object_ptr<Ui::VerticalLayout>(this);
|
||||||
|
const auto container = wrap2.data();
|
||||||
|
|
||||||
|
setInnerWidget(object_ptr<Ui::OverrideMargins>(
|
||||||
|
this,
|
||||||
|
std::move(wrap2)));
|
||||||
|
|
||||||
|
AddSubsectionTitle(container, tr::lng_settings_themes());
|
||||||
|
AddSkip(container, st::settingsThemesTopSkip);
|
||||||
|
|
||||||
|
Settings::SetupDefaultThemes(&_controller->window(), container);
|
||||||
|
|
||||||
|
AddSkip(container);
|
||||||
|
|
||||||
|
using namespace Window::Theme;
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
|
const auto wrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout> >(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::VerticalLayout>(container))
|
||||||
|
)->setDuration(0);
|
||||||
|
const auto inner = wrap->entity();
|
||||||
|
|
||||||
|
AddDivider(inner);
|
||||||
|
AddSkip(inner);
|
||||||
|
|
||||||
|
const auto title = AddSubsectionTitle(
|
||||||
|
inner,
|
||||||
|
tr::lng_settings_bg_cloud_themes());
|
||||||
|
const auto showAll = Ui::CreateChild<Ui::LinkButton>(
|
||||||
|
inner,
|
||||||
|
tr::lng_settings_bg_show_all(tr::now));
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
title->topValue(),
|
||||||
|
inner->widthValue(),
|
||||||
|
showAll->widthValue()
|
||||||
|
) | rpl::start_with_next([=](int top, int outerWidth, int width)
|
||||||
|
{
|
||||||
|
showAll->moveToRight(
|
||||||
|
st::defaultSubsectionTitlePadding.left(),
|
||||||
|
top,
|
||||||
|
outerWidth);
|
||||||
|
},
|
||||||
|
showAll->lifetime());
|
||||||
|
|
||||||
|
Ui::AddSkip(inner, st::settingsThemesTopSkip);
|
||||||
|
|
||||||
|
const auto list = inner->lifetime().make_state<CloudList>(
|
||||||
|
inner,
|
||||||
|
_controller);
|
||||||
|
inner->add(
|
||||||
|
list->takeWidget(),
|
||||||
|
style::margins(
|
||||||
|
st::settingsButtonNoIcon.padding.left(),
|
||||||
|
0,
|
||||||
|
st::settingsButtonNoIcon.padding.right(),
|
||||||
|
0));
|
||||||
|
|
||||||
|
list->allShown(
|
||||||
|
) | rpl::start_with_next([=](bool shown)
|
||||||
|
{
|
||||||
|
showAll->setVisible(!shown);
|
||||||
|
},
|
||||||
|
showAll->lifetime());
|
||||||
|
|
||||||
|
showAll->addClickHandler([=]
|
||||||
|
{
|
||||||
|
list->showAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
wrap->setDuration(0)->toggleOn(list->empty() | rpl::map(!_1));
|
||||||
|
|
||||||
|
_controller->session().data().cloudThemes().refresh();
|
||||||
|
|
||||||
|
AyuFeatures::MessageShot::themeChosen(
|
||||||
|
) | rpl::start_with_next(
|
||||||
|
[=](Data::CloudTheme theme)
|
||||||
|
{
|
||||||
|
const auto document = _controller->session().data().document(theme.documentId);
|
||||||
|
const auto documentView = document->createMediaView();
|
||||||
|
|
||||||
|
document->save(
|
||||||
|
Data::FileOriginTheme(theme.id, theme.accessHash),
|
||||||
|
QString());
|
||||||
|
|
||||||
|
const auto innerCallback = [=]
|
||||||
|
{
|
||||||
|
auto preview = Window::Theme::PreviewFromFile(
|
||||||
|
documentView->bytes(),
|
||||||
|
document->location().name(),
|
||||||
|
theme);
|
||||||
|
|
||||||
|
_selectedPalette = preview->instance.palette;
|
||||||
|
|
||||||
|
auto name = theme.title;
|
||||||
|
_themeNames.fire(std::move(name));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (documentView->loaded()) {
|
||||||
|
innerCallback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_controller->session().downloaderTaskFinished(
|
||||||
|
) | rpl::filter(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
return documentView->loaded();
|
||||||
|
}) | rpl::start_with_next(
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
innerCallback();
|
||||||
|
},
|
||||||
|
lifetime());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lifetime());
|
||||||
|
|
||||||
|
AyuFeatures::MessageShot::paletteChosen(
|
||||||
|
) | rpl::start_with_next([=](const auto &palette)
|
||||||
|
{
|
||||||
|
_themeNames.fire(tr::ayu_MessageShotThemeDefault(tr::now));
|
||||||
|
_selectedPalette = palette;
|
||||||
|
},
|
||||||
|
lifetime());
|
||||||
|
|
||||||
|
addButton(tr::ayu_MessageShotThemeApply(),
|
||||||
|
[=]
|
||||||
|
{
|
||||||
|
_palettes.fire(std::move(_selectedPalette));
|
||||||
|
closeBox();
|
||||||
|
});
|
||||||
|
|
||||||
|
setDimensionsToContent(st::boxWidth, container);
|
||||||
|
}
|
35
Telegram/SourceFiles/ayu/ui/boxes/theme_selector_box.h
Normal file
35
Telegram/SourceFiles/ayu/ui/boxes/theme_selector_box.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// 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, 2023
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/style/style_core_palette.h"
|
||||||
|
#include "ui/layers/box_content.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
|
using Callback = Fn<void(style::palette&)>;
|
||||||
|
|
||||||
|
class ThemeSelectorBox : public Ui::BoxContent {
|
||||||
|
public:
|
||||||
|
ThemeSelectorBox(QWidget* parent, not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
|
rpl::producer<style::palette> paletteSelected();
|
||||||
|
rpl::producer<QString> themeNameChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void prepare() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupContent();
|
||||||
|
|
||||||
|
not_null<Window::SessionController*> _controller;
|
||||||
|
|
||||||
|
rpl::event_stream<style::palette> _palettes;
|
||||||
|
rpl::event_stream<QString> _themeNames;
|
||||||
|
|
||||||
|
style::palette _selectedPalette;
|
||||||
|
|
||||||
|
};
|
|
@ -1,117 +0,0 @@
|
||||||
// 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, 2023
|
|
||||||
#include "ui/boxes/confirm_box.h"
|
|
||||||
|
|
||||||
#include "voice_confirmation_box.h"
|
|
||||||
#include "lang/lang_keys.h"
|
|
||||||
#include "styles/style_layers.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
|
|
||||||
namespace AyuUi
|
|
||||||
{
|
|
||||||
|
|
||||||
void VoiceConfirmBox(not_null<Ui::GenericBox *> box, Ui::ConfirmBoxArgs &&args)
|
|
||||||
{
|
|
||||||
const auto weak = MakeWeak(box);
|
|
||||||
const auto lifetime = box->lifetime().make_state<rpl::lifetime>();
|
|
||||||
|
|
||||||
v::match(args.text, [](v::null_t)
|
|
||||||
{
|
|
||||||
}, [&](auto &&)
|
|
||||||
{
|
|
||||||
const auto label = box->addRow(
|
|
||||||
object_ptr<Ui::FlatLabel>(
|
|
||||||
box.get(),
|
|
||||||
v::text::take_marked(std::move(args.text)),
|
|
||||||
args.labelStyle ? *args.labelStyle : st::boxLabel),
|
|
||||||
st::boxPadding);
|
|
||||||
if (args.labelFilter) {
|
|
||||||
label->setClickHandlerFilter(std::move(args.labelFilter));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto prepareCallback = [&](Ui::ConfirmBoxArgs::Callback &callback)
|
|
||||||
{
|
|
||||||
return [=, confirmed = std::move(callback)]()
|
|
||||||
{
|
|
||||||
if (const auto callbackPtr = std::get_if<1>(&confirmed)) {
|
|
||||||
if (auto callback = (*callbackPtr)) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (const auto callbackPtr = std::get_if<2>(&confirmed)) {
|
|
||||||
if (auto callback = (*callbackPtr)) {
|
|
||||||
callback(crl::guard(weak, [=]
|
|
||||||
{ weak->closeBox(); }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (weak) {
|
|
||||||
weak->closeBox();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &defaultButtonStyle = box->getDelegate()->style().button;
|
|
||||||
|
|
||||||
const auto confirmButton = box->addButton(
|
|
||||||
v::text::take_plain(std::move(args.confirmText), tr::lng_box_ok()),
|
|
||||||
[=, c = prepareCallback(args.confirmed)]()
|
|
||||||
{
|
|
||||||
lifetime->destroy();
|
|
||||||
c();
|
|
||||||
|
|
||||||
weak->closeBox();
|
|
||||||
},
|
|
||||||
args.confirmStyle ? *args.confirmStyle : defaultButtonStyle);
|
|
||||||
box->events(
|
|
||||||
) | start_with_next([=](not_null<QEvent *> e)
|
|
||||||
{
|
|
||||||
if ((e->type() != QEvent::KeyPress) || !confirmButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto k = static_cast<QKeyEvent *>(e.get());
|
|
||||||
if (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return) {
|
|
||||||
confirmButton->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
|
|
||||||
}
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
if (!args.inform) {
|
|
||||||
const auto cancelButton = box->addButton(
|
|
||||||
v::text::take_plain(std::move(args.cancelText), tr::lng_cancel()),
|
|
||||||
crl::guard(weak, [=, c = prepareCallback(args.cancelled)]()
|
|
||||||
{
|
|
||||||
lifetime->destroy();
|
|
||||||
c();
|
|
||||||
}),
|
|
||||||
args.cancelStyle ? *args.cancelStyle : defaultButtonStyle);
|
|
||||||
|
|
||||||
box->boxClosing(
|
|
||||||
) | start_with_next(crl::guard(cancelButton, [=]
|
|
||||||
{
|
|
||||||
cancelButton->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
|
|
||||||
}), *lifetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.strictCancel) {
|
|
||||||
lifetime->destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::GenericBox> MakeConfirmBox(Ui::ConfirmBoxArgs &&args)
|
|
||||||
{
|
|
||||||
return Box(VoiceConfirmBox, std::move(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::GenericBox> MakeInformBox(v::text::data text)
|
|
||||||
{
|
|
||||||
return MakeConfirmBox({
|
|
||||||
.text = std::move(text),
|
|
||||||
.inform = true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AyuUi
|
|
|
@ -1,23 +0,0 @@
|
||||||
// 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, 2023
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ui/boxes/confirm_box.h"
|
|
||||||
#include "ui/layers/generic_box.h"
|
|
||||||
#include "ui/text/text_variant.h"
|
|
||||||
|
|
||||||
namespace AyuUi
|
|
||||||
{
|
|
||||||
|
|
||||||
void VoiceConfirmBox(not_null<Ui::GenericBox *> box, Ui::ConfirmBoxArgs &&args);
|
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::GenericBox> MakeConfirmBox(
|
|
||||||
Ui::ConfirmBoxArgs &&args);
|
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::GenericBox> MakeInformBox(v::text::data text);
|
|
||||||
|
|
||||||
} // namespace Ui
|
|
112
Telegram/SourceFiles/ayu/ui/components/image_view.cpp
Normal file
112
Telegram/SourceFiles/ayu/ui/components/image_view.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
// 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, 2023
|
||||||
|
#include "image_view.h"
|
||||||
|
|
||||||
|
#include "styles/style_ayu_styles.h"
|
||||||
|
|
||||||
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
|
||||||
|
ImageView::ImageView(QWidget *parent)
|
||||||
|
: RpWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::setImage(const QImage &image)
|
||||||
|
{
|
||||||
|
if (this->image == image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto set = [=] {
|
||||||
|
this->prevImage = this->image;
|
||||||
|
this->image = image;
|
||||||
|
|
||||||
|
setMinimumSize(image.size().grownBy(st::imageViewInnerPadding));
|
||||||
|
|
||||||
|
if (this->animation.animating()) {
|
||||||
|
this->animation.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->prevImage.isNull()) {
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->animation.start(
|
||||||
|
[=]
|
||||||
|
{ update(); }, 0.0, 1.0, 300, anim::easeInCubic);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this->image.isNull()) {
|
||||||
|
set();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchToMainThread(set, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ImageView::getImage() const
|
||||||
|
{
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::paintEvent(QPaintEvent *e)
|
||||||
|
{
|
||||||
|
Painter p(this);
|
||||||
|
// PainterHighQualityEnabler hq(p);
|
||||||
|
|
||||||
|
auto brush = QBrush(st::boxBg); // copy
|
||||||
|
|
||||||
|
if (Window::Theme::IsNightMode()) {
|
||||||
|
brush.setColor(brush.color().lighter(120));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
brush.setColor(brush.color().darker(105));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath path;
|
||||||
|
path.addRoundedRect(rect(), st::bubbleRadiusLarge, st::bubbleRadiusLarge);
|
||||||
|
|
||||||
|
p.fillPath(path, brush);
|
||||||
|
|
||||||
|
if (!prevImage.isNull()) {
|
||||||
|
const auto realRect = rect().marginsRemoved(st::imageViewInnerPadding);
|
||||||
|
|
||||||
|
const auto resizedRect = QRect(
|
||||||
|
(realRect.width() - prevImage.width()) / 2 + st::imageViewInnerPadding.left(),
|
||||||
|
(realRect.height() - prevImage.height()) / 2 + st::imageViewInnerPadding.top(),
|
||||||
|
prevImage.width(),
|
||||||
|
prevImage.height());
|
||||||
|
|
||||||
|
const auto opacity = 1.0 - animation.value(1.0);
|
||||||
|
p.setOpacity(opacity);
|
||||||
|
p.drawImage(resizedRect, prevImage);
|
||||||
|
p.setOpacity(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image.isNull()) {
|
||||||
|
const auto realRect = rect().marginsRemoved(st::imageViewInnerPadding);
|
||||||
|
|
||||||
|
const auto resizedRect = QRect(
|
||||||
|
(realRect.width() - image.width()) / 2 + st::imageViewInnerPadding.left(),
|
||||||
|
(realRect.height() - image.height()) / 2 + st::imageViewInnerPadding.top(),
|
||||||
|
image.width(),
|
||||||
|
image.height());
|
||||||
|
|
||||||
|
const auto opacity = animation.value(1.0);
|
||||||
|
p.setOpacity(opacity);
|
||||||
|
p.drawImage(resizedRect, image);
|
||||||
|
p.setOpacity(1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::mousePressEvent(QMouseEvent *e)
|
||||||
|
{
|
||||||
|
}
|
31
Telegram/SourceFiles/ayu/ui/components/image_view.h
Normal file
31
Telegram/SourceFiles/ayu/ui/components/image_view.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// 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, 2023
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
|
||||||
|
class ImageView : public Ui::RpWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageView(QWidget *parent);
|
||||||
|
|
||||||
|
void setImage(const QImage& image);
|
||||||
|
QImage getImage() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage image;
|
||||||
|
QImage prevImage;
|
||||||
|
|
||||||
|
Ui::Animations::Simple animation;
|
||||||
|
|
||||||
|
};
|
|
@ -256,11 +256,14 @@ void AddMessageDetailsAction(not_null<Ui::PopupMenu *> menu, HistoryItem *item)
|
||||||
|
|
||||||
if (isSticker) {
|
if (isSticker) {
|
||||||
const auto authorId = media->document()->sticker()->set.id >> 32;
|
const auto authorId = media->document()->sticker()->set.id >> 32;
|
||||||
menu2->addAction(Ui::ContextActionStickerAuthor(
|
|
||||||
menu2->menu(),
|
if (authorId != 0) {
|
||||||
&item->history()->session(),
|
menu2->addAction(Ui::ContextActionStickerAuthor(
|
||||||
authorId
|
menu2->menu(),
|
||||||
));
|
&item->history()->session(),
|
||||||
|
authorId
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -65,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -623,6 +624,36 @@ void SendFilesBox::addMenuButton() {
|
||||||
[=] { sendWhenOnline(); },
|
[=] { sendWhenOnline(); },
|
||||||
&_st.tabbed.icons);
|
&_st.tabbed.icons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ImageInfo = Ui::PreparedFileInformation::Image;
|
||||||
|
if (_list.files.size() == 1 && std::get_if<ImageInfo>(&_list.files[0].information->media)) {
|
||||||
|
_menu->addAction(
|
||||||
|
tr::ayu_SendAsSticker(tr::now),
|
||||||
|
[=]() mutable
|
||||||
|
{
|
||||||
|
const auto file = std::move(_list.files[0]);
|
||||||
|
_list.files.clear();
|
||||||
|
|
||||||
|
const auto sourceImage = std::get_if<ImageInfo>(&file.information->media);
|
||||||
|
|
||||||
|
QByteArray targetArray;
|
||||||
|
QBuffer buffer(&targetArray);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
sourceImage->data.save(&buffer, "WEBP");
|
||||||
|
|
||||||
|
QImage targetImage;
|
||||||
|
targetImage.loadFromData(targetArray, "WEBP");
|
||||||
|
|
||||||
|
addFiles(Storage::PrepareMediaFromImage(std::move(targetImage),
|
||||||
|
std::move(targetArray),
|
||||||
|
st::sendMediaPreviewSize));
|
||||||
|
_list.overrideSendImagesAsPhotos = false;
|
||||||
|
initSendWay();
|
||||||
|
|
||||||
|
send({}, false);
|
||||||
|
},
|
||||||
|
&st::menuIconStickers);
|
||||||
|
}
|
||||||
_menu->popup(QCursor::pos());
|
_menu->popup(QCursor::pos());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -1400,7 +1431,7 @@ void SendFilesBox::send(
|
||||||
{
|
{
|
||||||
DEBUG_LOG(("[AyuGram] Scheduling files"));
|
DEBUG_LOG(("[AyuGram] Scheduling files"));
|
||||||
auto current = base::unixtime::now();
|
auto current = base::unixtime::now();
|
||||||
options.scheduled = current + 60; // well, files can be really big...
|
options.scheduled = current + 60; // well, files can be huge...
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_sendType == Api::SendType::Scheduled
|
if ((_sendType == Api::SendType::Scheduled
|
||||||
|
|
|
@ -67,6 +67,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -2458,7 +2459,7 @@ void HistoryItem::updateReactionsUnknown() {
|
||||||
|
|
||||||
const std::vector<Data::MessageReaction> &HistoryItem::reactions() const {
|
const std::vector<Data::MessageReaction> &HistoryItem::reactions() const {
|
||||||
static const auto kEmpty = std::vector<Data::MessageReaction>();
|
static const auto kEmpty = std::vector<Data::MessageReaction>();
|
||||||
return _reactions ? _reactions->list() : kEmpty;
|
return _reactions && !AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Reactions) ? _reactions->list() : kEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryItem::reactionsAreTags() const {
|
bool HistoryItem::reactionsAreTags() const {
|
||||||
|
|
|
@ -171,6 +171,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
#include "ayu/ui/boxes/message_shot_box.h"
|
||||||
|
#include "boxes/abstract_box.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -824,6 +827,10 @@ HistoryWidget::HistoryWidget(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmDeleteSelected();
|
confirmDeleteSelected();
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
_topBar->messageShotSelectionRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
messageShotSelected();
|
||||||
|
}, _topBar->lifetime());
|
||||||
_topBar->clearSelectionRequest(
|
_topBar->clearSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
clearSelected();
|
clearSelected();
|
||||||
|
@ -7717,6 +7724,29 @@ void HistoryWidget::confirmDeleteSelected() {
|
||||||
controller()->show(std::move(box));
|
controller()->show(std::move(box));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::messageShotSelected() {
|
||||||
|
if (!_list) return;
|
||||||
|
|
||||||
|
auto items = getSelectedItems();
|
||||||
|
if (items.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto messages = ranges::views::all(items)
|
||||||
|
| ranges::views::transform([this](const auto fullId) {
|
||||||
|
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);
|
||||||
|
Ui::show(std::move(box));
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::escape() {
|
void HistoryWidget::escape() {
|
||||||
if (_composeSearch) {
|
if (_composeSearch) {
|
||||||
_composeSearch->hideAnimated();
|
_composeSearch->hideAnimated();
|
||||||
|
|
|
@ -261,6 +261,7 @@ public:
|
||||||
|
|
||||||
void forwardSelected();
|
void forwardSelected();
|
||||||
void confirmDeleteSelected();
|
void confirmDeleteSelected();
|
||||||
|
void messageShotSelected();
|
||||||
void clearSelected();
|
void clearSelected();
|
||||||
|
|
||||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||||
|
|
|
@ -42,7 +42,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/ui/boxes/voice_confirmation_box.h"
|
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1725,7 +1724,7 @@ void VoiceRecordBar::stopRecording(StopType type, bool ttlBeforeHide) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (settings->voiceConfirmation) {
|
if (settings->voiceConfirmation) {
|
||||||
Ui::show(AyuUi::MakeConfirmBox(
|
Ui::show(Ui::MakeConfirmBox(
|
||||||
{
|
{
|
||||||
.text = tr::ayu_ConfirmationVoice(),
|
.text = tr::ayu_ConfirmationVoice(),
|
||||||
.confirmed = sendVoiceCallback,
|
.confirmed = sendVoiceCallback,
|
||||||
|
@ -1820,7 +1819,7 @@ void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (settings->voiceConfirmation) {
|
if (settings->voiceConfirmation) {
|
||||||
Ui::show(AyuUi::MakeConfirmBox(
|
Ui::show(Ui::MakeConfirmBox(
|
||||||
{
|
{
|
||||||
.text = tr::ayu_ConfirmationVoice(),
|
.text = tr::ayu_ConfirmationVoice(),
|
||||||
.confirmed = sendVoiceCallback,
|
.confirmed = sendVoiceCallback,
|
||||||
|
|
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -132,7 +133,7 @@ TextState BottomInfo::textState(
|
||||||
}
|
}
|
||||||
const auto textWidth = _authorEditedDate.maxWidth();
|
const auto textWidth = _authorEditedDate.maxWidth();
|
||||||
auto withTicksWidth = textWidth;
|
auto withTicksWidth = textWidth;
|
||||||
if (_data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) {
|
if (!AyuFeatures::MessageShot::isTakingShot() && _data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) {
|
||||||
withTicksWidth += st::historySendStateSpace;
|
withTicksWidth += st::historySendStateSpace;
|
||||||
}
|
}
|
||||||
if (!_views.isEmpty()) {
|
if (!_views.isEmpty()) {
|
||||||
|
@ -263,7 +264,7 @@ void BottomInfo::paint(
|
||||||
|
|
||||||
auto right = position.x() + width();
|
auto right = position.x() + width();
|
||||||
const auto firstLineBottom = position.y() + st::msgDateFont->height;
|
const auto firstLineBottom = position.y() + st::msgDateFont->height;
|
||||||
if (_data.flags & Data::Flag::OutLayout) {
|
if (!AyuFeatures::MessageShot::isTakingShot() && _data.flags & Data::Flag::OutLayout) {
|
||||||
const auto &icon = (_data.flags & Data::Flag::Sending)
|
const auto &icon = (_data.flags & Data::Flag::Sending)
|
||||||
? (inverted
|
? (inverted
|
||||||
? st->historySendingInvertedIcon()
|
? st->historySendingInvertedIcon()
|
||||||
|
@ -332,7 +333,7 @@ void BottomInfo::paint(
|
||||||
firstLineBottom + st::historyViewsTop,
|
firstLineBottom + st::historyViewsTop,
|
||||||
outerWidth);
|
outerWidth);
|
||||||
}
|
}
|
||||||
if ((_data.flags & Data::Flag::Sending)
|
if (!AyuFeatures::MessageShot::isTakingShot() && (_data.flags & Data::Flag::Sending)
|
||||||
&& !(_data.flags & Data::Flag::OutLayout)) {
|
&& !(_data.flags & Data::Flag::OutLayout)) {
|
||||||
right -= st::historySendStateSpace;
|
right -= st::historySendStateSpace;
|
||||||
const auto &icon = inverted
|
const auto &icon = inverted
|
||||||
|
@ -558,7 +559,7 @@ void BottomInfo::layoutReactionsText() {
|
||||||
|
|
||||||
QSize BottomInfo::countOptimalSize() {
|
QSize BottomInfo::countOptimalSize() {
|
||||||
auto width = 0;
|
auto width = 0;
|
||||||
if (_data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) {
|
if (!AyuFeatures::MessageShot::isTakingShot() && _data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) {
|
||||||
width += st::historySendStateSpace;
|
width += st::historySendStateSpace;
|
||||||
}
|
}
|
||||||
width += _authorEditedDate.maxWidth();
|
width += _authorEditedDate.maxWidth();
|
||||||
|
|
|
@ -83,7 +83,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ayu/database/ayu_database.h"
|
#include "ayu/database/ayu_database.h"
|
||||||
#include "ayu/messages/ayu_messages_controller.h"
|
#include "ayu/messages/ayu_messages_controller.h"
|
||||||
#include "ayu/ui/context_menu/context_menu.h"
|
#include "ayu/ui/context_menu/context_menu.h"
|
||||||
#include "ayu/ui/boxes/message_history_box.h"
|
|
||||||
#include "ayu/ui/sections/edited/edited_log_section.h"
|
#include "ayu/ui/sections/edited/edited_log_section.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -306,6 +310,10 @@ void UnreadBar::paint(
|
||||||
int y,
|
int y,
|
||||||
int w,
|
int w,
|
||||||
bool chatWide) const {
|
bool chatWide) const {
|
||||||
|
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto st = context.st;
|
const auto st = context.st;
|
||||||
const auto bottom = y + height();
|
const auto bottom = y + height();
|
||||||
y += marginTop();
|
y += marginTop();
|
||||||
|
@ -668,6 +676,10 @@ bool Element::isTopicRootReply() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Element::skipBlockWidth() const {
|
int Element::skipBlockWidth() const {
|
||||||
|
if (AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
|
return st::msgDateDelta.x();
|
||||||
|
}
|
||||||
|
|
||||||
return st::msgDateSpace + infoWidth() - st::msgDateDelta.x();
|
return st::msgDateSpace + infoWidth() - st::msgDateDelta.x();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,6 +1189,10 @@ void Element::destroyUnreadBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Element::displayedDateHeight() const {
|
int Element::displayedDateHeight() const {
|
||||||
|
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto date = Get<DateBadge>()) {
|
if (auto date = Get<DateBadge>()) {
|
||||||
return date->height();
|
return date->height();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -853,10 +857,14 @@ int Message::marginTop() const {
|
||||||
}
|
}
|
||||||
result += displayedDateHeight();
|
result += displayedDateHeight();
|
||||||
if (const auto bar = Get<UnreadBar>()) {
|
if (const auto bar = Get<UnreadBar>()) {
|
||||||
result += bar->height();
|
if (!AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
result += bar->height();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (const auto service = Get<ServicePreMessage>()) {
|
if (const auto service = Get<ServicePreMessage>()) {
|
||||||
result += service->height;
|
if (!AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
result += service->height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +918,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
||||||
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
|
auto mediaOnTop = (mediaDisplayed && media->isBubbleTop()) || (entry && entry->isBubbleTop());
|
||||||
|
|
||||||
const auto displayInfo = needInfoDisplay();
|
const auto displayInfo = needInfoDisplay() && !AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date);
|
||||||
const auto reactionsInBubble = _reactions && embedReactionsInBubble();
|
const auto reactionsInBubble = _reactions && embedReactionsInBubble();
|
||||||
|
|
||||||
auto mediaSelectionIntervals = (!context.selected() && mediaDisplayed)
|
auto mediaSelectionIntervals = (!context.selected() && mediaDisplayed)
|
||||||
|
@ -3359,6 +3367,10 @@ bool Message::displayRightActionComments() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QSize> Message::rightActionSize() const {
|
std::optional<QSize> Message::rightActionSize() const {
|
||||||
|
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (displayRightActionComments()) {
|
if (displayRightActionComments()) {
|
||||||
const auto views = data()->Get<HistoryMessageViews>();
|
const auto views = data()->Get<HistoryMessageViews>();
|
||||||
Assert(views != nullptr);
|
Assert(views != nullptr);
|
||||||
|
|
|
@ -53,6 +53,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include <QtCore/QMimeData>
|
#include <QtCore/QMimeData>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -143,6 +147,10 @@ PinnedWidget::PinnedWidget(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmDeleteSelected();
|
confirmDeleteSelected();
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
_topBar->messageShotSelectionRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
AyuFeatures::MessageShot::Wrapper(_inner);
|
||||||
|
}, _topBar->lifetime());
|
||||||
_topBar->forwardSelectionRequest(
|
_topBar->forwardSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmForwardSelected();
|
confirmForwardSelected();
|
||||||
|
|
|
@ -96,6 +96,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include <QtCore/QMimeData>
|
#include <QtCore/QMimeData>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -283,6 +287,10 @@ RepliesWidget::RepliesWidget(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmDeleteSelected();
|
confirmDeleteSelected();
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
_topBar->messageShotSelectionRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
AyuFeatures::MessageShot::Wrapper(_inner);
|
||||||
|
}, _topBar->lifetime());
|
||||||
_topBar->forwardSelectionRequest(
|
_topBar->forwardSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmForwardSelected();
|
confirmForwardSelected();
|
||||||
|
|
|
@ -66,6 +66,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include <QtCore/QMimeData>
|
#include <QtCore/QMimeData>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
||||||
|
@ -136,6 +140,10 @@ ScheduledWidget::ScheduledWidget(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmDeleteSelected();
|
confirmDeleteSelected();
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
_topBar->messageShotSelectionRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
AyuFeatures::MessageShot::Wrapper(_inner);
|
||||||
|
}, _topBar->lifetime());
|
||||||
_topBar->clearSelectionRequest(
|
_topBar->clearSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
clearSelected();
|
clearSelected();
|
||||||
|
|
|
@ -31,6 +31,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -110,6 +114,10 @@ SublistWidget::SublistWidget(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmDeleteSelected();
|
confirmDeleteSelected();
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
_topBar->messageShotSelectionRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
AyuFeatures::MessageShot::Wrapper(_inner);
|
||||||
|
}, _topBar->lifetime());
|
||||||
_topBar->forwardSelectionRequest(
|
_topBar->forwardSelectionRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
confirmForwardSelected();
|
confirmForwardSelected();
|
||||||
|
|
|
@ -119,6 +119,7 @@ TopBarWidget::TopBarWidget(
|
||||||
, _forward(this, tr::lng_selected_forward(), st::defaultActiveButton)
|
, _forward(this, tr::lng_selected_forward(), st::defaultActiveButton)
|
||||||
, _sendNow(this, tr::lng_selected_send_now(), st::defaultActiveButton)
|
, _sendNow(this, tr::lng_selected_send_now(), st::defaultActiveButton)
|
||||||
, _delete(this, tr::lng_selected_delete(), st::defaultActiveButton)
|
, _delete(this, tr::lng_selected_delete(), st::defaultActiveButton)
|
||||||
|
, _messageShot(this, tr::ayu_MessageShotTopBarText(), st::defaultActiveButton)
|
||||||
, _back(this, st::historyTopBarBack)
|
, _back(this, st::historyTopBarBack)
|
||||||
, _cancelChoose(this, st::topBarCloseChoose)
|
, _cancelChoose(this, st::topBarCloseChoose)
|
||||||
, _call(this, st::topBarCall)
|
, _call(this, st::topBarCall)
|
||||||
|
@ -141,6 +142,8 @@ TopBarWidget::TopBarWidget(
|
||||||
_sendNow->setWidthChangedCallback([=] { updateControlsGeometry(); });
|
_sendNow->setWidthChangedCallback([=] { updateControlsGeometry(); });
|
||||||
_delete->setClickedCallback([=] { _deleteSelection.fire({}); });
|
_delete->setClickedCallback([=] { _deleteSelection.fire({}); });
|
||||||
_delete->setWidthChangedCallback([=] { updateControlsGeometry(); });
|
_delete->setWidthChangedCallback([=] { updateControlsGeometry(); });
|
||||||
|
_messageShot->setClickedCallback([=] { _messageShotSelection.fire({}); });
|
||||||
|
_messageShot->setWidthChangedCallback([=] { updateControlsGeometry(); });
|
||||||
_clear->setClickedCallback([=] { _clearSelection.fire({}); });
|
_clear->setClickedCallback([=] { _clearSelection.fire({}); });
|
||||||
_call->setClickedCallback([=] { call(); });
|
_call->setClickedCallback([=] { call(); });
|
||||||
_groupCall->setClickedCallback([=] { groupCall(); });
|
_groupCall->setClickedCallback([=] { groupCall(); });
|
||||||
|
@ -970,6 +973,7 @@ void TopBarWidget::updateControlsGeometry() {
|
||||||
auto buttonsWidth = (_forward->isHidden() ? 0 : _forward->contentWidth())
|
auto buttonsWidth = (_forward->isHidden() ? 0 : _forward->contentWidth())
|
||||||
+ (_sendNow->isHidden() ? 0 : _sendNow->contentWidth())
|
+ (_sendNow->isHidden() ? 0 : _sendNow->contentWidth())
|
||||||
+ (_delete->isHidden() ? 0 : _delete->contentWidth())
|
+ (_delete->isHidden() ? 0 : _delete->contentWidth())
|
||||||
|
+ (_messageShot->isHidden() ? 0 : _messageShot->contentWidth())
|
||||||
+ _clear->width();
|
+ _clear->width();
|
||||||
buttonsWidth += buttonsLeft + st::topBarActionSkip * 3;
|
buttonsWidth += buttonsLeft + st::topBarActionSkip * 3;
|
||||||
|
|
||||||
|
@ -978,6 +982,7 @@ void TopBarWidget::updateControlsGeometry() {
|
||||||
_forward->setFullWidth(buttonFullWidth);
|
_forward->setFullWidth(buttonFullWidth);
|
||||||
_sendNow->setFullWidth(buttonFullWidth);
|
_sendNow->setFullWidth(buttonFullWidth);
|
||||||
_delete->setFullWidth(buttonFullWidth);
|
_delete->setFullWidth(buttonFullWidth);
|
||||||
|
_messageShot->setFullWidth(buttonFullWidth);
|
||||||
|
|
||||||
selectedButtonsTop += (height() - _forward->height()) / 2;
|
selectedButtonsTop += (height() - _forward->height()) / 2;
|
||||||
|
|
||||||
|
@ -992,6 +997,12 @@ void TopBarWidget::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_delete->moveToLeft(buttonsLeft, selectedButtonsTop);
|
_delete->moveToLeft(buttonsLeft, selectedButtonsTop);
|
||||||
|
if (!_delete->isHidden()) {
|
||||||
|
buttonsLeft += _delete->width() + st::topBarActionSkip;
|
||||||
|
}
|
||||||
|
|
||||||
|
_messageShot->moveToLeft(buttonsLeft, selectedButtonsTop);
|
||||||
|
|
||||||
_clear->moveToRight(st::topBarActionSkip, selectedButtonsTop);
|
_clear->moveToRight(st::topBarActionSkip, selectedButtonsTop);
|
||||||
|
|
||||||
if (!_cancelChoose->isHidden()) {
|
if (!_cancelChoose->isHidden()) {
|
||||||
|
@ -1091,6 +1102,7 @@ void TopBarWidget::updateControlsVisibility() {
|
||||||
}
|
}
|
||||||
_clear->show();
|
_clear->show();
|
||||||
_delete->setVisible(_canDelete);
|
_delete->setVisible(_canDelete);
|
||||||
|
_messageShot->setVisible(true);
|
||||||
_forward->setVisible(_canForward);
|
_forward->setVisible(_canForward);
|
||||||
_sendNow->setVisible(_canSendNow);
|
_sendNow->setVisible(_canSendNow);
|
||||||
|
|
||||||
|
@ -1266,10 +1278,12 @@ void TopBarWidget::showSelected(SelectedState state) {
|
||||||
_forward->setNumbersText(_selectedCount);
|
_forward->setNumbersText(_selectedCount);
|
||||||
_sendNow->setNumbersText(_selectedCount);
|
_sendNow->setNumbersText(_selectedCount);
|
||||||
_delete->setNumbersText(_selectedCount);
|
_delete->setNumbersText(_selectedCount);
|
||||||
|
_messageShot->setNumbersText(_selectedCount);
|
||||||
if (!wasSelectedState) {
|
if (!wasSelectedState) {
|
||||||
_forward->finishNumbersAnimation();
|
_forward->finishNumbersAnimation();
|
||||||
_sendNow->finishNumbersAnimation();
|
_sendNow->finishNumbersAnimation();
|
||||||
_delete->finishNumbersAnimation();
|
_delete->finishNumbersAnimation();
|
||||||
|
_messageShot->finishNumbersAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (visibilityChanged) {
|
if (visibilityChanged) {
|
||||||
|
|
|
@ -100,6 +100,9 @@ public:
|
||||||
[[nodiscard]] rpl::producer<> deleteSelectionRequest() const {
|
[[nodiscard]] rpl::producer<> deleteSelectionRequest() const {
|
||||||
return _deleteSelection.events();
|
return _deleteSelection.events();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] rpl::producer<> messageShotSelectionRequest() const {
|
||||||
|
return _messageShotSelection.events();
|
||||||
|
}
|
||||||
[[nodiscard]] rpl::producer<> clearSelectionRequest() const {
|
[[nodiscard]] rpl::producer<> clearSelectionRequest() const {
|
||||||
return _clearSelection.events();
|
return _clearSelection.events();
|
||||||
}
|
}
|
||||||
|
@ -206,7 +209,7 @@ private:
|
||||||
Ui::Animations::Simple _searchShown;
|
Ui::Animations::Simple _searchShown;
|
||||||
|
|
||||||
object_ptr<Ui::RoundButton> _clear;
|
object_ptr<Ui::RoundButton> _clear;
|
||||||
object_ptr<Ui::RoundButton> _forward, _sendNow, _delete;
|
object_ptr<Ui::RoundButton> _forward, _sendNow, _delete, _messageShot;
|
||||||
object_ptr<Ui::InputField> _searchField = { nullptr };
|
object_ptr<Ui::InputField> _searchField = { nullptr };
|
||||||
object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _chooseFromUser
|
object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _chooseFromUser
|
||||||
= { nullptr };
|
= { nullptr };
|
||||||
|
@ -252,6 +255,7 @@ private:
|
||||||
rpl::event_stream<> _forwardSelection;
|
rpl::event_stream<> _forwardSelection;
|
||||||
rpl::event_stream<> _sendNowSelection;
|
rpl::event_stream<> _sendNowSelection;
|
||||||
rpl::event_stream<> _deleteSelection;
|
rpl::event_stream<> _deleteSelection;
|
||||||
|
rpl::event_stream<> _messageShotSelection;
|
||||||
rpl::event_stream<> _clearSelection;
|
rpl::event_stream<> _clearSelection;
|
||||||
rpl::event_stream<> _cancelChooseForReport;
|
rpl::event_stream<> _cancelChooseForReport;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include <QSvgRenderer>
|
#include <QSvgRenderer>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -697,7 +701,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
}
|
}
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
if (displayMute) {
|
if (displayMute && !AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
auto muteRect = style::rtlrect(rthumb.x() + (rthumb.width() - st::historyVideoMessageMuteSize) / 2, rthumb.y() + st::msgDateImgDelta, st::historyVideoMessageMuteSize, st::historyVideoMessageMuteSize, width());
|
auto muteRect = style::rtlrect(rthumb.x() + (rthumb.width() - st::historyVideoMessageMuteSize) / 2, rthumb.y() + st::msgDateImgDelta, st::historyVideoMessageMuteSize, st::historyVideoMessageMuteSize, width());
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(sti->msgDateImgBg);
|
p.setBrush(sti->msgDateImgBg);
|
||||||
|
@ -714,7 +718,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
drawCornerStatus(p, context, QPoint());
|
drawCornerStatus(p, context, QPoint());
|
||||||
}
|
}
|
||||||
} else if (!skipDrawingSurrounding) {
|
} else if (!skipDrawingSurrounding) {
|
||||||
if (isRound) {
|
if (isRound && !AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
const auto mediaUnread = item->hasUnreadMediaFlag();
|
const auto mediaUnread = item->hasUnreadMediaFlag();
|
||||||
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
||||||
auto statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
auto statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||||
|
@ -820,7 +824,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
||||||
.selection = context.selection,
|
.selection = context.selection,
|
||||||
.highlight = highlightRequest ? &*highlightRequest : nullptr,
|
.highlight = highlightRequest ? &*highlightRequest : nullptr,
|
||||||
});
|
});
|
||||||
} else if (!inWebPage && !skipDrawingSurrounding) {
|
} else if (!inWebPage && !skipDrawingSurrounding && !AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
auto fullRight = paintx + usex + usew;
|
auto fullRight = paintx + usex + usew;
|
||||||
auto fullBottom = painty + painth;
|
auto fullBottom = painty + painth;
|
||||||
auto maxRight = _parent->width() - st::msgMargin.left();
|
auto maxRight = _parent->width() - st::msgMargin.left();
|
||||||
|
@ -1023,7 +1027,7 @@ void Gif::drawCornerStatus(
|
||||||
const auto padding = st::msgDateImgPadding;
|
const auto padding = st::msgDateImgPadding;
|
||||||
const auto radial = _animation && _animation->radial.animating();
|
const auto radial = _animation && _animation->radial.animating();
|
||||||
const auto cornerDownload = downloadInCorner() && !dataLoaded() && !_data->loadedInMediaCache();
|
const auto cornerDownload = downloadInCorner() && !dataLoaded() && !_data->loadedInMediaCache();
|
||||||
const auto cornerMute = _streamed && _data->isVideoFile() && !cornerDownload;
|
const auto cornerMute = _streamed && _data->isVideoFile() && !cornerDownload && !AyuFeatures::MessageShot::isTakingShot();
|
||||||
const auto addLeft = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : 0;
|
const auto addLeft = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : 0;
|
||||||
const auto addRight = cornerMute ? st::historyVideoMuteSize : 0;
|
const auto addRight = cornerMute ? st::historyVideoMuteSize : 0;
|
||||||
const auto downloadWidth = cornerDownload ? st::normalFont->width(_downloadSize) : 0;
|
const auto downloadWidth = cornerDownload ? st::normalFont->width(_downloadSize) : 0;
|
||||||
|
@ -2056,11 +2060,20 @@ bool Gif::needInfoDisplay() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gif::needCornerStatusDisplay() const {
|
bool Gif::needCornerStatusDisplay() const {
|
||||||
|
if (AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return _data->isVideoFile()
|
return _data->isVideoFile()
|
||||||
|| needInfoDisplay();
|
|| needInfoDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif::ensureTranscribeButton() const {
|
void Gif::ensureTranscribeButton() const {
|
||||||
|
if (AyuFeatures::MessageShot::isTakingShot()) {
|
||||||
|
_transcribe = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_data->isVideoMessage()
|
if (_data->isVideoMessage()
|
||||||
&& !_parent->data()->media()->ttlSeconds()
|
&& !_parent->data()->media()->ttlSeconds()
|
||||||
&& (_data->session().premium()
|
&& (_data->session().premium()
|
||||||
|
|
|
@ -39,6 +39,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
// AyuGran includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -902,6 +906,10 @@ bool Photo::dataLoaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Photo::needInfoDisplay() const {
|
bool Photo::needInfoDisplay() const {
|
||||||
|
if (AyuFeatures::MessageShot::ignoreRender(AyuFeatures::MessageShot::RenderPart::Date)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_parent->data()->isFakeBotAbout()) {
|
if (_parent->data()->isFakeBotAbout()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace HistoryView::Reactions {
|
namespace HistoryView::Reactions {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -484,7 +488,7 @@ void InlineList::paint(
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!animations.empty()) {
|
if (!animations.empty() && !AyuFeatures::MessageShot::isTakingShot()) { // fix crash when taking shot
|
||||||
const auto now = context.now;
|
const auto now = context.now;
|
||||||
context.reactionInfo->effectPaint = [
|
context.reactionInfo->effectPaint = [
|
||||||
now,
|
now,
|
||||||
|
|
|
@ -72,6 +72,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/ui/settings/settings_ayu.h"
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
#include "window/themes/window_theme_preview.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -247,7 +253,7 @@ void ColorsPalette::show(Type type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
list.insert(list.begin(), scheme->accentColor);
|
list.insert(list.begin(), scheme->accentColor);
|
||||||
const auto color = Core::App().settings().themesAccentColors().get(type);
|
const auto color = AyuFeatures::MessageShot::isChoosingTheme() ? AyuFeatures::MessageShot::getSelectedColorFromDefault() : Core::App().settings().themesAccentColors().get(type);
|
||||||
const auto current = color.value_or(scheme->accentColor);
|
const auto current = color.value_or(scheme->accentColor);
|
||||||
const auto i = ranges::find(list, current);
|
const auto i = ranges::find(list, current);
|
||||||
if (i == end(list)) {
|
if (i == end(list)) {
|
||||||
|
@ -1290,7 +1296,19 @@ void SetupDefaultThemes(
|
||||||
container.get(),
|
container.get(),
|
||||||
container.get());
|
container.get());
|
||||||
|
|
||||||
|
const auto updateMessageShotPalette = [=](const QString &path)
|
||||||
|
{
|
||||||
|
const Data::CloudTheme theme;
|
||||||
|
if (const auto preview = PreviewFromFile(QByteArray(), path, theme)) {
|
||||||
|
AyuFeatures::MessageShot::setPalette(preview->instance.palette);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const auto chosen = [] {
|
const auto chosen = [] {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
return AyuFeatures::MessageShot::getSelectedFromDefault();
|
||||||
|
}
|
||||||
|
|
||||||
const auto &object = Background()->themeObject();
|
const auto &object = Background()->themeObject();
|
||||||
if (object.cloud.id) {
|
if (object.cloud.id) {
|
||||||
return Type(-1);
|
return Type(-1);
|
||||||
|
@ -1328,6 +1346,12 @@ void SetupDefaultThemes(
|
||||||
const auto schemeClicked = [=](
|
const auto schemeClicked = [=](
|
||||||
const Scheme &scheme,
|
const Scheme &scheme,
|
||||||
Qt::KeyboardModifiers modifiers) {
|
Qt::KeyboardModifiers modifiers) {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
AyuFeatures::MessageShot::setDefaultSelected(scheme.type);
|
||||||
|
updateMessageShotPalette(scheme.path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
apply(scheme);
|
apply(scheme);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1371,6 +1395,16 @@ void SetupDefaultThemes(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (i != end(checks)) {
|
if (i != end(checks)) {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
if (const auto color = AyuFeatures::MessageShot::getSelectedColorFromDefault()) {
|
||||||
|
const auto colorizer = ColorizerFrom(*scheme, color.value());
|
||||||
|
i->second->setColors(ColorsFromScheme(*scheme, colorizer));
|
||||||
|
} else {
|
||||||
|
i->second->setColors(ColorsFromScheme(*scheme));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto color = colors.get(type)) {
|
if (const auto color = colors.get(type)) {
|
||||||
const auto colorizer = ColorizerFrom(*scheme, *color);
|
const auto colorizer = ColorizerFrom(*scheme, *color);
|
||||||
i->second->setColors(ColorsFromScheme(*scheme, colorizer));
|
i->second->setColors(ColorsFromScheme(*scheme, colorizer));
|
||||||
|
@ -1380,6 +1414,21 @@ void SetupDefaultThemes(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
group->setChangedCallback([=](Type type) {
|
group->setChangedCallback([=](Type type) {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
palette->show(type);
|
||||||
|
refreshColorizer(type);
|
||||||
|
group->setValue(type);
|
||||||
|
AyuFeatures::MessageShot::setDefaultSelected(type);
|
||||||
|
|
||||||
|
const auto scheme = ranges::find(kSchemesList, type, &Scheme::type);
|
||||||
|
if (scheme == end(kSchemesList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMessageShotPalette(scheme->path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
group->setValue(chosen());
|
group->setValue(chosen());
|
||||||
});
|
});
|
||||||
for (const auto &scheme : kSchemesList) {
|
for (const auto &scheme : kSchemesList) {
|
||||||
|
@ -1430,8 +1479,32 @@ void SetupDefaultThemes(
|
||||||
}
|
}
|
||||||
}, block->lifetime());
|
}, block->lifetime());
|
||||||
|
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
palette->selected() | rpl::start_with_next([=](QColor color) {
|
||||||
|
AyuFeatures::MessageShot::setDefaultSelectedColor(color);
|
||||||
|
refreshColorizer(AyuFeatures::MessageShot::getSelectedFromDefault());
|
||||||
|
|
||||||
|
const auto type = chosen();
|
||||||
|
const auto scheme = ranges::find(kSchemesList, type, &Scheme::type);
|
||||||
|
if (scheme == end(kSchemesList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMessageShotPalette(scheme->path);
|
||||||
|
}, container->lifetime());
|
||||||
|
|
||||||
|
AyuFeatures::MessageShot::resetDefaultSelectedEvents() | rpl::start_with_next([=] {
|
||||||
|
refreshColorizer(AyuFeatures::MessageShot::getSelectedFromDefault()); // hide colorizer
|
||||||
|
group->setValue(Type(-1));
|
||||||
|
}, container->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
palette->selected(
|
palette->selected(
|
||||||
) | rpl::start_with_next([=](QColor color) {
|
) | rpl::start_with_next([=](QColor color) {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Background()->editingTheme()) {
|
if (Background()->editingTheme()) {
|
||||||
// We don't remember old accent color to revert it properly
|
// We don't remember old accent color to revert it properly
|
||||||
// in Window::Theme::Revert which is called by Editor.
|
// in Window::Theme::Revert which is called by Editor.
|
||||||
|
|
|
@ -35,6 +35,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
#include <QtGui/QClipboard>
|
#include <QtGui/QClipboard>
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -332,11 +336,21 @@ rpl::producer<bool> CloudList::allShown() const {
|
||||||
|
|
||||||
void CloudList::setup() {
|
void CloudList::setup() {
|
||||||
_group->setChangedCallback([=](int selected) {
|
_group->setChangedCallback([=](int selected) {
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto &object = Background()->themeObject();
|
const auto &object = Background()->themeObject();
|
||||||
_group->setValue(groupValueForId(
|
_group->setValue(groupValueForId(
|
||||||
object.cloud.id ? object.cloud.id : kFakeCloudThemeId));
|
object.cloud.id ? object.cloud.id : kFakeCloudThemeId));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
AyuFeatures::MessageShot::resetCustomSelectedEvents() | rpl::start_with_next([=] {
|
||||||
|
_group->setValue(-1);
|
||||||
|
}, _outer->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
auto cloudListChanges = rpl::single(rpl::empty) | rpl::then(
|
auto cloudListChanges = rpl::single(rpl::empty) | rpl::then(
|
||||||
_window->session().data().cloudThemes().updated()
|
_window->session().data().cloudThemes().updated()
|
||||||
);
|
);
|
||||||
|
@ -436,6 +450,13 @@ bool CloudList::applyChangesFrom(std::vector<Data::CloudTheme> &&list) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
_group->setValue(groupValueForId(id));
|
_group->setValue(groupValueForId(id));
|
||||||
|
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
if (const auto selected = AyuFeatures::MessageShot::getSelectedFromCustom()) {
|
||||||
|
_group->setValue(groupValueForId(selected.value().id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +542,14 @@ void CloudList::insert(int index, const Data::CloudTheme &theme) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto &cloud = i->theme;
|
const auto &cloud = i->theme;
|
||||||
|
|
||||||
|
if (AyuFeatures::MessageShot::isChoosingTheme()) {
|
||||||
|
AyuFeatures::MessageShot::setTheme(cloud);
|
||||||
|
AyuFeatures::MessageShot::setCustomSelected(cloud);
|
||||||
|
_group->setValue(groupValueForId(cloud.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (button == Qt::RightButton) {
|
if (button == Qt::RightButton) {
|
||||||
showMenu(*i);
|
showMenu(*i);
|
||||||
} else if (cloud.documentId) {
|
} else if (cloud.documentId) {
|
||||||
|
|
|
@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "ui/style/style_palette_colorizer.h"
|
#include "ui/style/style_palette_colorizer.h"
|
||||||
|
|
||||||
|
// AyuGram includes
|
||||||
|
#include "ayu/features/messageshot/message_shot.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -188,7 +192,7 @@ style::colorizer ColorizerForTheme(const QString &absolutePath) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto &colors = Core::App().settings().themesAccentColors();
|
const auto &colors = Core::App().settings().themesAccentColors();
|
||||||
if (const auto accent = colors.get(i->type)) {
|
if (const auto accent = AyuFeatures::MessageShot::isChoosingTheme() ? AyuFeatures::MessageShot::getSelectedColorFromDefault() : colors.get(i->type)) {
|
||||||
return ColorizerFrom(*i, *accent);
|
return ColorizerFrom(*i, *accent);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -75,7 +75,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
// AyuGram includes
|
// AyuGram includes
|
||||||
#include "ayu/ayu_settings.h"
|
#include "ayu/ayu_settings.h"
|
||||||
#include "ayu/utils/telegram_helpers.h"
|
#include "ayu/utils/telegram_helpers.h"
|
||||||
#include "ayu/ui/boxes/confirmation_box.h"
|
#include "ayu/ui/boxes/server_read_confirmation_box.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "ayu/features/streamer_mode/streamer_mode.h"
|
#include "ayu/features/streamer_mode/streamer_mode.h"
|
||||||
#include "styles/style_ayu_icons.h"
|
#include "styles/style_ayu_icons.h"
|
||||||
|
|
Loading…
Add table
Reference in a new issue