diff --git a/apps/desktop/src/config_center/config_center.cpp b/apps/desktop/src/config_center/config_center.cpp index e71998ff..8b08d659 100644 --- a/apps/desktop/src/config_center/config_center.cpp +++ b/apps/desktop/src/config_center/config_center.cpp @@ -52,6 +52,10 @@ int ConfigCenter::Load() { ini_->Delete(section_, "enable_desktop_quality_optimization"); persist_config_migration |= ini_->Delete(section_, "enable_minimize_to_tray"); + // The old global flag has no version information. Prompt once for the + // current release, then remember its version when the user dismisses it. + persist_config_migration |= + ini_->Delete(section_, "sponsorship_prompt_dismissed"); const long language_value = ini_->GetLongValue(section_, "language", static_cast(language_)); @@ -131,8 +135,8 @@ int ConfigCenter::Load() { portable_service_prompt_suppressed_ = ini_->GetBoolValue(section_, "portable_service_prompt_suppressed", portable_service_prompt_suppressed_); - sponsorship_prompt_dismissed_ = - ini_->GetBoolValue(section_, "sponsorship_prompt_dismissed", false); + sponsorship_prompt_dismissed_version_ = + ini_->GetValue(section_, "sponsorship_prompt_dismissed_version", ""); const char* file_transfer_save_path_value = ini_->GetValue(section_, "file_transfer_save_path", nullptr); @@ -223,8 +227,8 @@ int ConfigCenter::Save() { save_remote_previews_.load()); ini_->SetBoolValue(section_, "portable_service_prompt_suppressed", portable_service_prompt_suppressed_); - ini_->SetBoolValue(section_, "sponsorship_prompt_dismissed", - sponsorship_prompt_dismissed_); + ini_->SetValue(section_, "sponsorship_prompt_dismissed_version", + sponsorship_prompt_dismissed_version_.c_str()); ini_->SetValue(section_, "file_transfer_save_path", file_transfer_save_path_.c_str()); @@ -399,12 +403,13 @@ int ConfigCenter::SetPortableServicePromptSuppressed(bool suppressed) { return 0; } -int ConfigCenter::SetSponsorshipPromptDismissed(bool dismissed) { - if (StoreValues({{"sponsorship_prompt_dismissed", - dismissed ? "true" : "false"}}) != 0) { +int ConfigCenter::SetSponsorshipPromptDismissedVersion( + const std::string& version) { + if (version.empty() || + StoreValues({{"sponsorship_prompt_dismissed_version", version}}) != 0) { return -1; } - sponsorship_prompt_dismissed_ = dismissed; + sponsorship_prompt_dismissed_version_ = version; return 0; } @@ -476,8 +481,8 @@ bool ConfigCenter::IsPortableServicePromptSuppressed() const { return portable_service_prompt_suppressed_; } -bool ConfigCenter::IsSponsorshipPromptDismissed() const { - return sponsorship_prompt_dismissed_; +std::string ConfigCenter::GetSponsorshipPromptDismissedVersion() const { + return sponsorship_prompt_dismissed_version_; } int ConfigCenter::SetFileTransferSavePath(const std::string& path) { diff --git a/apps/desktop/src/config_center/config_center.h b/apps/desktop/src/config_center/config_center.h index 055a761d..14a37367 100644 --- a/apps/desktop/src/config_center/config_center.h +++ b/apps/desktop/src/config_center/config_center.h @@ -49,7 +49,7 @@ class ConfigCenter { int SetPrivacyScreen(bool enable_privacy_screen); int SetSaveRemotePreviews(bool enabled); int SetPortableServicePromptSuppressed(bool suppressed); - int SetSponsorshipPromptDismissed(bool dismissed); + int SetSponsorshipPromptDismissedVersion(const std::string& version); int SetFileTransferSavePath(const std::string& path); // read config @@ -74,7 +74,7 @@ class ConfigCenter { bool IsEnablePrivacyScreen() const; bool IsSaveRemotePreviews() const; bool IsPortableServicePromptSuppressed() const; - bool IsSponsorshipPromptDismissed() const; + std::string GetSponsorshipPromptDismissedVersion() const; std::string GetFileTransferSavePath() const; int Load(); @@ -104,7 +104,7 @@ class ConfigCenter { std::atomic enable_privacy_screen_{true}; std::atomic save_remote_previews_{true}; bool portable_service_prompt_suppressed_ = false; - bool sponsorship_prompt_dismissed_ = false; + std::string sponsorship_prompt_dismissed_version_; std::string file_transfer_save_path_ = ""; }; } // namespace crossdesk diff --git a/apps/desktop/src/gui/application/gui_application.cpp b/apps/desktop/src/gui/application/gui_application.cpp index 4b4ad8db..488487cd 100644 --- a/apps/desktop/src/gui/application/gui_application.cpp +++ b/apps/desktop/src/gui/application/gui_application.cpp @@ -1267,7 +1267,7 @@ void GuiApplication::InitializeUi() { #endif ui_ = std::make_unique(); ui_->sponsorship_prompt_pending = - !config_center_->IsSponsorshipPromptDismissed(); + config_center_->GetSponsorshipPromptDismissedVersion() != CROSSDESK_VERSION; ui_->video_presenter = std::make_unique(*video_renderer_); #if _WIN32 @@ -1752,7 +1752,7 @@ void GuiApplication::BindMainCallbacks(bool gallery_window) { main->on_dismiss_sponsorship([this, main] { main->set_sponsorship_open(false); ui_->sponsorship_prompt_pending = false; - if (config_center_->SetSponsorshipPromptDismissed(true) != 0) { + if (config_center_->SetSponsorshipPromptDismissedVersion(CROSSDESK_VERSION) != 0) { LOG_WARN("Could not save sponsorship prompt dismissal"); } }); diff --git a/apps/desktop/src/gui/assets/localization/localization_data.h b/apps/desktop/src/gui/assets/localization/localization_data.h index 0a1f0817..2749f5fc 100644 --- a/apps/desktop/src/gui/assets/localization/localization_data.h +++ b/apps/desktop/src/gui/assets/localization/localization_data.h @@ -293,9 +293,9 @@ struct TranslationRow { X(sponsorship_message, u8"如果 CrossDesk 对你有帮助,欢迎赞助支持项目的持续开发、跨平台测试与日常维护。感谢你的支持!", \ "If CrossDesk is useful to you, consider supporting its continued development, cross-platform testing, and maintenance. Thank you for your support!", \ u8"Если CrossDesk вам полезен, поддержите его дальнейшую разработку, тестирование на разных платформах и сопровождение. Спасибо за вашу поддержку!") \ - X(sponsorship_dismiss_hint, u8"关闭后不再自动弹出,你仍可在「关于」中找到赞助入口。", \ - "This prompt will not appear again after you close it. Sponsorship links remain available in About.", \ - u8"После закрытия это окно больше не появится автоматически. Ссылки для поддержки останутся в разделе «О программе».") \ + X(sponsorship_dismiss_hint, u8"关闭后本版本不再提示,升级后再次显示。赞助入口仍在「关于」中。", \ + "Once closed, this prompt stays hidden until the version changes. Sponsorship links remain available in About.", \ + u8"После закрытия это окно появится только при смене версии. Ссылки для поддержки останутся в разделе «О программе».") \ X(sponsor_via_afdian, u8"爱发电", "AFDIAN", "AFDIAN") \ X(notification, u8"通知", "Notification", u8"Уведомление") \ X(new_version, u8"新版本", "New version", u8"Новая версия") \ diff --git a/apps/desktop/src/gui/ui/main_window.slint b/apps/desktop/src/gui/ui/main_window.slint index df0127cb..94ad3d0b 100644 --- a/apps/desktop/src/gui/ui/main_window.slint +++ b/apps/desktop/src/gui/ui/main_window.slint @@ -2289,15 +2289,16 @@ export component MainWindow inherits Window { width: min(480px, parent.width - 40px); height: self.content-top + sponsorship-content.preferred-height + 24px; title: UiStrings.sponsorship-title; - close-label: MessageStrings.close; - close => { root.dismiss-sponsorship(); } + show-close-button: false; sponsorship-content := VerticalLayout { x: 24px; y: parent.content-top; width: parent.width - 48px; height: self.preferred-height; - padding: 0px; spacing: 18px; + padding: 0px; spacing: 20px; Text { text: UiStrings.sponsorship-message; - color: WorkbenchStyle.text; font-size: 13px; wrap: word-wrap; + color: WorkbenchStyle.text; font-size: 14px; wrap: word-wrap; + // Match message bodies' 1.5em line height for wrapped text. + font-family: "CrossDesk Message Spacing"; } SponsorshipSection { show-title: false; @@ -2308,6 +2309,7 @@ export component MainWindow inherits Window { Text { text: UiStrings.sponsorship-dismiss-hint; color: WorkbenchStyle.muted; font-size: 12px; wrap: word-wrap; + font-family: "CrossDesk Message Spacing"; } Rectangle { height: 1px; background: WorkbenchStyle.separator; } HorizontalLayout { diff --git a/apps/desktop/src/gui/ui/settings_controls.slint b/apps/desktop/src/gui/ui/settings_controls.slint index 1e244176..74224a55 100644 --- a/apps/desktop/src/gui/ui/settings_controls.slint +++ b/apps/desktop/src/gui/ui/settings_controls.slint @@ -49,6 +49,7 @@ export component SettingsButton inherits Rectangle { export component SettingsDialog inherits DialogSurface { in property title; in property close-label; + in property show-close-button: true; in property badge-count: 0; in property badge-label; in property header-status; @@ -92,7 +93,7 @@ export component SettingsDialog inherits DialogSurface { clicked => { root.action(); } action-label-metrics := Text { visible: false; text: root.action-text; font-size: 12px; } } - IconButton { + if root.show-close-button: IconButton { width: 28px; height: 28px; icon: FontAwesomeIcons.xmark; icon-size: 14px; icon-color: WorkbenchStyle.muted;