diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 37c9339492..afa0c3956b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -337,8 +337,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_bg_use_default" = "Use default color theme"; "lng_settings_bg_from_gallery" = "Choose from gallery"; "lng_settings_bg_from_file" = "Choose from file"; -"lng_settings_bg_edit_theme" = "Launch theme editor"; -"lng_settings_bg_create_theme" = "Create new theme"; +"lng_settings_bg_theme_edit" = "Edit theme"; +"lng_settings_bg_theme_create" = "Create new theme"; "lng_settings_bg_cloud_themes" = "Custom themes"; "lng_settings_bg_show_all" = "Show all themes"; "lng_settings_bg_tile" = "Tile background"; diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 027d933ec7..95a5af6e60 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -1084,8 +1084,7 @@ void SetupDefaultThemes(not_null container) { base::ObservableViewer( *Window::Theme::Background() ) | rpl::filter([](const Update &update) { - return (update.type == Update::Type::ApplyingTheme - || update.type == Update::Type::New); + return (update.type == Update::Type::ApplyingTheme); }) | rpl::map([=] { return chosen(); }) | rpl::start_with_next([=](Type type) { @@ -1149,6 +1148,8 @@ void SetupDefaultThemes(not_null container) { void SetupThemeOptions( not_null controller, not_null container) { + using namespace Window::Theme; + AddSkip(container, st::settingsPrivacySkip); AddSubsectionTitle(container, tr::lng_settings_themes()); @@ -1156,20 +1157,38 @@ void SetupThemeOptions( AddSkip(container, st::settingsThemesTopSkip); SetupDefaultThemes(container); AddSkip(container, st::settingsThemesBottomSkip); - auto canEdit = rpl::single(false); + + const auto canEditCurrent = [=] { + const auto userId = controller->session().userId(); + return (Background()->themeObject().cloud.createdBy == userId); + }; + auto canEdit = rpl::single(BackgroundUpdate( + BackgroundUpdate::Type::ApplyingTheme, + Background()->tile() + )) | rpl::then(base::ObservableViewer( + *Background() + )) | rpl::filter([](const BackgroundUpdate &update) { + return (update.type == BackgroundUpdate::Type::ApplyingTheme); + }) | rpl::map([=] { + return canEditCurrent(); + }); AddButton( container, rpl::conditional( std::move(canEdit), - tr::lng_settings_bg_edit_theme(), - tr::lng_settings_bg_create_theme()), + tr::lng_settings_bg_theme_edit(), + tr::lng_settings_bg_theme_create()), st::settingsChatButton, &st::settingsIconThemes, st::settingsChatIconLeft )->addClickHandler([=] { - controller->window().show(Box( - Window::Theme::CreateBox, - &controller->window())); + if (canEditCurrent()) { + StartEditor( + &controller->window(), + Background()->themeObject().cloud); + } else { + controller->window().show(Box(CreateBox, &controller->window())); + } }); AddSkip(container); diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 23692971e9..f4129f51fe 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -4201,21 +4201,17 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) { auto &cache = result.cache; theme.stream >> object.content; theme.stream >> tag >> object.pathAbsolute; - const auto isCloud = (object.pathAbsolute == kThemePathAbsoluteCloud); if (tag == kThemeNewPathRelativeTag) { - if (isCloud) { - auto creator = qint32(); - theme.stream - >> object.cloud.id - >> object.cloud.accessHash - >> object.cloud.slug - >> object.cloud.title - >> object.cloud.documentId - >> creator; - object.cloud.createdBy = creator; - } else { - theme.stream >> object.pathRelative; - } + auto creator = qint32(); + theme.stream + >> object.pathRelative + >> object.cloud.id + >> object.cloud.accessHash + >> object.cloud.slug + >> object.cloud.title + >> object.cloud.documentId + >> creator; + object.cloud.createdBy = creator; } else { object.pathRelative = tag; } @@ -4224,7 +4220,7 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) { } auto ignoreCache = false; - if (!isCloud) { + if (!object.cloud.id) { QFile file(object.pathRelative); if (object.pathRelative.isEmpty() || !file.exists()) { file.setFileName(object.pathAbsolute); @@ -4299,33 +4295,30 @@ void writeTheme(const Window::Theme::Saved &saved) { const auto &object = saved.object; const auto &cache = saved.cache; const auto tag = QString(kThemeNewPathRelativeTag); - const auto isCloud = (saved.object.pathAbsolute == kThemePathAbsoluteCloud); - quint32 size = Serialize::bytearraySize(object.content); - size += Serialize::stringSize(tag) + Serialize::stringSize(object.pathAbsolute); - if (isCloud) { - size += sizeof(uint64) * 3 - + Serialize::stringSize(object.cloud.slug) - + Serialize::stringSize(object.cloud.title) - + sizeof(qint32); - } else { - size += Serialize::stringSize(object.pathRelative); - } - size += sizeof(int32) * 2 + Serialize::bytearraySize(cache.colors) + Serialize::bytearraySize(cache.background) + sizeof(quint32); + quint32 size = Serialize::bytearraySize(object.content) + + Serialize::stringSize(tag) + + Serialize::stringSize(object.pathAbsolute) + + Serialize::stringSize(object.pathRelative) + + sizeof(uint64) * 3 + + Serialize::stringSize(object.cloud.slug) + + Serialize::stringSize(object.cloud.title) + + sizeof(qint32) + + sizeof(qint32) * 2 + + Serialize::bytearraySize(cache.colors) + + Serialize::bytearraySize(cache.background) + + sizeof(quint32); EncryptedDescriptor data(size); - data.stream << object.content; - data.stream << tag << object.pathAbsolute; - if (isCloud) { - data.stream - << object.cloud.id - << object.cloud.accessHash - << object.cloud.slug - << object.cloud.title - << object.cloud.documentId - << qint32(object.cloud.createdBy); - } else { - data.stream << object.pathRelative; - } data.stream + << object.content + << tag + << object.pathAbsolute + << object.pathRelative + << object.cloud.id + << object.cloud.accessHash + << object.cloud.slug + << object.cloud.title + << object.cloud.documentId + << qint32(object.cloud.createdBy) << cache.paletteChecksum << cache.contentChecksum << cache.colors diff --git a/Telegram/SourceFiles/ui/widgets/checkbox.cpp b/Telegram/SourceFiles/ui/widgets/checkbox.cpp index 608c343a3a..d075bf9e95 100644 --- a/Telegram/SourceFiles/ui/widgets/checkbox.cpp +++ b/Telegram/SourceFiles/ui/widgets/checkbox.cpp @@ -413,7 +413,7 @@ Checkbox::Checkbox( text, _checkboxOptions, countTextMinWidth()) { - _check->setUpdateCallback([=] { updateCheck(); }); + _check->setUpdateCallback([=] { update(); }); resizeToText(); setCursor(style::cur_pointer); } diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 4e31eae852..7e2e3f6876 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -590,8 +590,8 @@ void MainWindow::reActivateWindow() { } void MainWindow::showRightColumn(object_ptr widget) { - auto wasWidth = width(); - auto wasRightWidth = _rightColumn ? _rightColumn->width() : 0; + const auto wasWidth = width(); + const auto wasRightWidth = _rightColumn ? _rightColumn->width() : 0; _rightColumn = std::move(widget); if (_rightColumn) { _rightColumn->setParent(this); @@ -600,13 +600,14 @@ void MainWindow::showRightColumn(object_ptr widget) { } else if (App::wnd()) { App::wnd()->setInnerFocus(); } - auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0; - setMinimumWidth(st::windowMinWidth + nowRightWidth); + const auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0; + const auto wasMaximized = isMaximized(); if (!isMaximized()) { tryToExtendWidthBy(wasWidth + nowRightWidth - wasRightWidth - width()); } else { updateControlsGeometry(); } + setMinimumWidth(st::windowMinWidth + nowRightWidth); } int MainWindow::maximalExtendBy() const { diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index eddb966241..83673e7af1 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -1065,8 +1065,10 @@ void Unload() { GlobalApplying = Applying(); } -bool Apply(const QString &filepath) { - if (auto preview = PreviewFromFile(filepath, {}, {})) { +bool Apply( + const QString &filepath, + const Data::CloudTheme &cloud) { + if (auto preview = PreviewFromFile(filepath, {}, cloud)) { return Apply(std::move(preview)); } return false; diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index 76766e8d20..0042a128b2 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -18,7 +18,6 @@ namespace Window { namespace Theme { inline constexpr auto kThemeSchemeSizeLimit = 1024 * 1024; -inline const auto kThemePathAbsoluteCloud = qstr("special://cloud"); struct Object { QString pathRelative; @@ -53,7 +52,9 @@ struct Preview { QImage preview; }; -bool Apply(const QString &filepath); +bool Apply( + const QString &filepath, + const Data::CloudTheme &cloud = Data::CloudTheme()); bool Apply(std::unique_ptr preview); void ApplyDefaultWithPath(const QString &themePath); bool ApplyEditedPalette(const QString &path, const QByteArray &content); diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index 7906635e6c..f6a421fab9 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -262,21 +262,6 @@ void WriteDefaultPalette(const QString &path) { } } -void StartEditor( - not_null window, - const QString &title) { - const auto path = EditingPalettePath(); - if (!Local::copyThemeColorsToPalette(path)) { - WriteDefaultPalette(path); - } - if (!Apply(path)) { - window->show(Box(tr::lng_theme_editor_error(tr::now))); - return; - } - KeepApplied(); - window->showRightColumn(Box(window)); -} - [[nodiscard]] QString GenerateSlug() { const auto letters = uint8('Z' + 1 - 'A'); const auto digits = uint8('9' + 1 - '0'); @@ -500,6 +485,21 @@ Fn SaveTheme( } // namespace +void StartEditor( + not_null window, + const Data::CloudTheme &cloud) { + const auto path = EditingPalettePath(); + if (!Local::copyThemeColorsToPalette(path)) { + WriteDefaultPalette(path); + } + if (!Apply(path, cloud)) { + window->show(Box(tr::lng_theme_editor_error(tr::now))); + return; + } + KeepApplied(); + window->showRightColumn(Box(window)); +} + void CreateBox( not_null box, not_null window) { @@ -542,7 +542,9 @@ void CreateBox( return; } box->closeBox(); - StartEditor(window, title); + auto cloud = Data::CloudTheme(); + cloud.title = title; + StartEditor(window, cloud); }; Ui::Connect(name, &Ui::InputField::submitted, done); box->addButton(tr::lng_box_done(), done); diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.h b/Telegram/SourceFiles/window/themes/window_theme_editor_box.h index 75a106e22f..095c879d7d 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.h +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.h @@ -9,12 +9,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/generic_box.h" +namespace Data { +struct CloudTheme; +} // namespace Data + namespace Window { class Controller; namespace Theme { +void StartEditor( + not_null window, + const Data::CloudTheme &cloud); void CreateBox( not_null box, not_null window); diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index 211159fe62..9a72d1ef02 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -915,17 +915,12 @@ std::unique_ptr PreviewFromFile( auto result = std::make_unique(); auto &object = result->object; object.cloud = cloud; - if (cloud.documentId || filepath.isEmpty()) { - object.pathRelative = QString(); - object.pathAbsolute = QString(kThemePathAbsoluteCloud); - } else { - object.pathRelative = filepath.isEmpty() - ? QString() - : QDir().relativeFilePath(filepath); - object.pathAbsolute = filepath.isEmpty() - ? QString() - : QFileInfo(filepath).absoluteFilePath(); - } + object.pathRelative = filepath.isEmpty() + ? QString() + : QDir().relativeFilePath(filepath); + object.pathAbsolute = filepath.isEmpty() + ? QString() + : QFileInfo(filepath).absoluteFilePath(); if (bytes.isEmpty()) { if (!LoadFromFile(filepath, &result->instance, &object.content)) { return nullptr; diff --git a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp index 2022f0ae7b..10aaa43346 100644 --- a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp +++ b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp @@ -154,13 +154,13 @@ void CloudList::setup() { _window->session().data().cloudThemes().updated() ); - auto themeChanges = rpl::single( - BackgroundUpdate(BackgroundUpdate::Type::New, Background()->tile()) - ) | rpl::then(base::ObservableViewer( + auto themeChanges = rpl::single(BackgroundUpdate( + BackgroundUpdate::Type::ApplyingTheme, + Background()->tile() + )) | rpl::then(base::ObservableViewer( *Background() )) | rpl::filter([](const BackgroundUpdate &update) { - return (update.type == BackgroundUpdate::Type::ApplyingTheme) - || (update.type == BackgroundUpdate::Type::New); + return (update.type == BackgroundUpdate::Type::ApplyingTheme); }); rpl::combine(