diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index 0bd3e89cc..c4dc6043d 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -959,10 +959,10 @@ PRIVATE
history/history_view_highlight_manager.h
history/history_widget.cpp
history/history_widget.h
- info/bot/earn/info_earn_inner_widget.cpp
- info/bot/earn/info_earn_inner_widget.h
- info/bot/earn/info_earn_widget.cpp
- info/bot/earn/info_earn_widget.h
+ info/bot/earn/info_bot_earn_list.cpp
+ info/bot/earn/info_bot_earn_list.h
+ info/bot/earn/info_bot_earn_widget.cpp
+ info/bot/earn/info_bot_earn_widget.h
info/channel_statistics/boosts/create_giveaway_box.cpp
info/channel_statistics/boosts/create_giveaway_box.h
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.cpp
@@ -971,10 +971,10 @@ PRIVATE
info/channel_statistics/boosts/info_boosts_inner_widget.h
info/channel_statistics/boosts/info_boosts_widget.cpp
info/channel_statistics/boosts/info_boosts_widget.h
- info/channel_statistics/earn/info_earn_inner_widget.cpp
- info/channel_statistics/earn/info_earn_inner_widget.h
- info/channel_statistics/earn/info_earn_widget.cpp
- info/channel_statistics/earn/info_earn_widget.h
+ info/channel_statistics/earn/info_channel_earn_list.cpp
+ info/channel_statistics/earn/info_channel_earn_list.h
+ info/channel_statistics/earn/info_channel_earn_widget.cpp
+ info/channel_statistics/earn/info_channel_earn_widget.h
info/common_groups/info_common_groups_inner_widget.cpp
info/common_groups/info_common_groups_inner_widget.h
info/common_groups/info_common_groups_widget.cpp
diff --git a/Telegram/Resources/icons/menu/passcode_watch.png b/Telegram/Resources/icons/menu/passcode_watch.png
new file mode 100644
index 000000000..161da4e87
Binary files /dev/null and b/Telegram/Resources/icons/menu/passcode_watch.png differ
diff --git a/Telegram/Resources/icons/menu/passcode_watch@2x.png b/Telegram/Resources/icons/menu/passcode_watch@2x.png
new file mode 100644
index 000000000..516e313b7
Binary files /dev/null and b/Telegram/Resources/icons/menu/passcode_watch@2x.png differ
diff --git a/Telegram/Resources/icons/menu/passcode_watch@3x.png b/Telegram/Resources/icons/menu/passcode_watch@3x.png
new file mode 100644
index 000000000..2b5f71f72
Binary files /dev/null and b/Telegram/Resources/icons/menu/passcode_watch@3x.png differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 3a05b3558..9213a3203 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -687,6 +687,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_use_winhello_about" = "You need to enter your passcode once before unlocking Telegram with Windows Hello.";
"lng_settings_use_touchid" = "Unlock with Touch ID";
"lng_settings_use_touchid_about" = "You need to enter your passcode once before unlocking Telegram with Touch ID.";
+"lng_settings_use_applewatch" = "Unlock with Apple Watch";
+"lng_settings_use_applewatch_about" = "You need to enter your passcode once before unlocking Telegram with Apple Watch.";
+"lng_settings_use_systempwd" = "Unlock with System Password";
+"lng_settings_use_systempwd_about" = "You need to enter your passcode once before unlocking Telegram with System Password.";
"lng_settings_password_disable" = "Disable Cloud Password";
"lng_settings_password_abort" = "Abort two-step verification setup";
"lng_settings_about_bio" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco";
@@ -998,6 +1002,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passcode_logout" = "Log out";
"lng_passcode_winhello" = "You need to enter your passcode\nbefore you can use Windows Hello.";
"lng_passcode_touchid" = "You need to enter your passcode\nbefore you can use Touch ID.";
+"lng_passcode_applewatch" = "You need to enter your passcode\nbefore you can use Watch to unlock.";
+"lng_passcode_systempwd" = "You need to enter your passcode\nbefore you can use system password.";
"lng_passcode_winhello_unlock" = "Telegram wants to unlock with Windows Hello.";
"lng_passcode_touchid_unlock" = "unlock";
"lng_passcode_create_button" = "Save Passcode";
diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index 6358fd7a8..53203464b 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -10,7 +10,7 @@
+ Version="5.2.2.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index a0add328c..ae26d7f19 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 5,2,0,0
- PRODUCTVERSION 5,2,0,0
+ FILEVERSION 5,2,2,0
+ PRODUCTVERSION 5,2,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
- VALUE "FileVersion", "5.2.0.0"
+ VALUE "FileVersion", "5.2.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "5.2.0.0"
+ VALUE "ProductVersion", "5.2.2.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index f4d9012ed..5fb0f2a20 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 5,2,0,0
- PRODUCTVERSION 5,2,0,0
+ FILEVERSION 5,2,2,0
+ PRODUCTVERSION 5,2,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop Updater"
- VALUE "FileVersion", "5.2.0.0"
+ VALUE "FileVersion", "5.2.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "5.2.0.0"
+ VALUE "ProductVersion", "5.2.2.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style
index 096adc10d..c549948e0 100644
--- a/Telegram/SourceFiles/boxes/boxes.style
+++ b/Telegram/SourceFiles/boxes/boxes.style
@@ -293,6 +293,8 @@ passcodeSkip: 23px;
passcodeSystemUnlock: IconButton(defaultIconButton) {
width: 32px;
height: 36px;
+ icon: icon{{ "menu/passcode_winhello", lightButtonFg }};
+ iconOver: icon{{ "menu/passcode_winhello", lightButtonFg }};
iconPosition: point(4px, 4px);
rippleAreaSize: 32px;
rippleAreaPosition: point(0px, 0px);
@@ -300,14 +302,9 @@ passcodeSystemUnlock: IconButton(defaultIconButton) {
color: lightButtonBgOver;
}
}
-passcodeSystemWinHello: IconButton(passcodeSystemUnlock) {
- icon: icon{{ "menu/passcode_winhello", lightButtonFg }};
- iconOver: icon{{ "menu/passcode_winhello", lightButtonFg }};
-}
-passcodeSystemTouchID: IconButton(passcodeSystemUnlock) {
- icon: icon{{ "menu/passcode_finger", lightButtonFg }};
- iconOver: icon{{ "menu/passcode_finger", lightButtonFg }};
-}
+passcodeSystemTouchID: icon{{ "menu/passcode_finger", lightButtonFg }};
+passcodeSystemAppleWatch: icon{{ "menu/passcode_watch", lightButtonFg }};
+passcodeSystemSystemPwd: icon{{ "menu/permissions", lightButtonFg }};
passcodeSystemUnlockLater: FlatLabel(defaultFlatLabel) {
align: align(top);
textFg: windowSubTextFg;
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
index 5623bea94..0ba6354f9 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp
@@ -43,7 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_premium_limits.h"
#include "data/data_user.h"
#include "history/admin_log/history_admin_log_section.h"
-#include "info/bot/earn/info_earn_widget.h"
+#include "info/bot/earn/info_bot_earn_widget.h"
#include "info/channel_statistics/boosts/info_boosts_widget.h"
#include "info/profile/info_profile_values.h"
#include "info/info_memento.h"
@@ -2200,8 +2200,11 @@ void Controller::saveForum() {
channel->inputChannel,
MTP_bool(*_savingData.forum)
)).done([=](const MTPUpdates &result) {
+ const auto weak = base::make_weak(this);
channel->session().api().applyUpdates(result);
- continueSave();
+ if (weak) { // todo better to be able to save in closed already box.
+ continueSave();
+ }
}).fail([=](const MTP::Error &error) {
if (error.type() == u"CHAT_NOT_MODIFIED"_q) {
continueSave();
diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp
index db9a85b88..4540e704b 100644
--- a/Telegram/SourceFiles/core/application.cpp
+++ b/Telegram/SourceFiles/core/application.cpp
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/battery_saving.h"
#include "base/event_filter.h"
#include "base/concurrent_timer.h"
+#include "base/options.h"
#include "base/qt_signal_producer.h"
#include "base/timer.h"
#include "base/unixtime.h"
@@ -144,10 +145,18 @@ void SetCrashAnnotationsGL() {
#endif // DESKTOP_APP_USE_ANGLE
}
+base::options::toggle OptionSkipUrlSchemeRegister({
+ .id = kOptionSkipUrlSchemeRegister,
+ .name = "Skip URL scheme register",
+ .description = "Don't re-register tg:// URL scheme on autoupdate.",
+});
+
} // namespace
Application *Application::Instance = nullptr;
+const char kOptionSkipUrlSchemeRegister[] = "skip-url-scheme-register";
+
struct Application::Private {
base::Timer quitTimer;
UiIntegration uiIntegration;
@@ -265,9 +274,14 @@ void Application::run() {
refreshGlobalProxy(); // Depends on app settings being read.
- if (const auto old = Local::oldSettingsVersion(); old < AppVersion) {
- InvokeQueued(this, [] { RegisterUrlScheme(); });
- Platform::NewVersionLaunched(old);
+ if (const auto old = Local::oldSettingsVersion()) {
+ if (old < AppVersion) {
+ autoRegisterUrlScheme();
+ Platform::NewVersionLaunched(old);
+ }
+ } else {
+ // Initial launch.
+ autoRegisterUrlScheme();
}
if (cAutoStart() && !Platform::AutostartSupported()) {
@@ -409,6 +423,12 @@ void Application::run() {
processCreatedWindow(_lastActivePrimaryWindow);
}
+void Application::autoRegisterUrlScheme() {
+ if (!OptionSkipUrlSchemeRegister.value()) {
+ InvokeQueued(this, [] { RegisterUrlScheme(); });
+ }
+}
+
void Application::showAccount(not_null account) {
if (const auto separate = separateWindowFor(account)) {
_lastActivePrimaryWindow = separate;
diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h
index 28975d474..e73878ef2 100644
--- a/Telegram/SourceFiles/core/application.h
+++ b/Telegram/SourceFiles/core/application.h
@@ -126,6 +126,8 @@ enum class QuitReason {
QtQuitEvent,
};
+extern const char kOptionSkipUrlSchemeRegister[];
+
class Application final : public QObject {
public:
struct ProxyChange {
@@ -352,6 +354,7 @@ private:
friend bool IsAppLaunched();
friend Application &App();
+ void autoRegisterUrlScheme();
void clearEmojiSourceImages();
[[nodiscard]] auto prepareEmojiSourceImages()
-> std::shared_ptr;
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index b3a93d830..5db1682b1 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs;
constexpr auto AppNameOld = "AyuGram for Windows"_cs;
constexpr auto AppName = "AyuGram Desktop"_cs;
constexpr auto AppFile = "AyuGram"_cs;
-constexpr auto AppVersion = 5002000;
-constexpr auto AppVersionStr = "5.2";
+constexpr auto AppVersion = 5002002;
+constexpr auto AppVersionStr = "5.2.2";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
index 1ac569e9c..cb33e8a9a 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
@@ -3690,6 +3690,9 @@ bool InnerWidget::chooseCollapsedRow(Qt::KeyboardModifiers modifiers) {
}
void InnerWidget::switchToFilter(FilterId filterId) {
+ if (_controller->windowId().type != Window::SeparateType::Primary) {
+ return;
+ }
const auto &list = session().data().chatsFilters().list();
const auto filterIt = filterId
? ranges::find(list, filterId, &Data::ChatFilter::id)
diff --git a/Telegram/SourceFiles/dialogs/dialogs_key.cpp b/Telegram/SourceFiles/dialogs/dialogs_key.cpp
index 544c48cca..db5df9627 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_key.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_key.cpp
@@ -100,7 +100,9 @@ ChatSearchTab SearchState::defaultTabForMe() const {
}
bool SearchState::filterChatsList() const {
- return !inChat && (tab == ChatSearchTab::MyMessages);
+ using Tab = ChatSearchTab;
+ return !inChat // ThisPeer can be in opened forum.
+ && (tab == Tab::MyMessages || tab == Tab::ThisPeer);
}
} // namespace Dialogs
diff --git a/Telegram/SourceFiles/dialogs/ui/chat_search_in.cpp b/Telegram/SourceFiles/dialogs/ui/chat_search_in.cpp
index 5fcc8f78b..42e8c33d7 100644
--- a/Telegram/SourceFiles/dialogs/ui/chat_search_in.cpp
+++ b/Telegram/SourceFiles/dialogs/ui/chat_search_in.cpp
@@ -29,6 +29,7 @@ public:
std::shared_ptr icon,
const QString &label,
bool chosen);
+ ~Action();
bool isEnabled() const override;
not_null action() const override;
@@ -111,6 +112,10 @@ Action::Action(
enableMouseSelecting();
}
+Action::~Action() {
+ _icon->subscribeToUpdates(nullptr);
+}
+
void Action::resolveMinWidth() {
const auto maxWidth = st::dialogsSearchInPhotoPadding
+ st::dialogsSearchInPhotoSize
diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp
index 5be5fb12d..094e99221 100644
--- a/Telegram/SourceFiles/history/history_inner_widget.cpp
+++ b/Telegram/SourceFiles/history/history_inner_widget.cpp
@@ -1736,7 +1736,9 @@ std::unique_ptr HistoryInner::prepareDrag() {
updateDragSelection(nullptr, nullptr, false);
_selectScroll.cancel();
- if (!urls.isEmpty()) mimeData->setUrls(urls);
+ if (!urls.isEmpty()) {
+ mimeData->setUrls(urls);
+ }
if (uponSelected && !_controller->adaptive().isOneColumn()) {
auto selectedState = getSelectionState();
if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) {
@@ -1757,21 +1759,21 @@ std::unique_ptr HistoryInner::prepareDrag() {
== forwardSelectionState.canForwardCount)) {
forwardIds = getSelectedItems();
} else if (_mouseCursorState == CursorState::Date) {
- forwardIds = session().data().itemOrItsGroup(_mouseActionItem);
+ const auto item = _mouseActionItem;
+ if (item && item->allowsForward()) {
+ forwardIds = session().data().itemOrItsGroup(item);
+ }
} else if ((pressedView->isHiddenByGroup() && pressedHandler)
|| (pressedView->media()
&& pressedView->media()->dragItemByHandler(pressedHandler))) {
const auto item = _dragStateItem
? _dragStateItem
: _mouseActionItem;
- forwardIds = MessageIdsList(1, item->fullId());
+ if (item && item->allowsForward()) {
+ forwardIds = MessageIdsList(1, item->fullId());
+ }
}
- if (forwardIds.empty()) {
- return nullptr;
- }
- session().data().setMimeForwardIds(std::move(forwardIds));
- auto result = std::make_unique();
- result->setData(u"application/x-td-forward"_q, "1");
+
if (pressedHandler) {
const auto lnkDocument = reinterpret_cast(
pressedHandler->property(
@@ -1779,12 +1781,23 @@ std::unique_ptr HistoryInner::prepareDrag() {
if (lnkDocument) {
const auto filepath = lnkDocument->filepath(true);
if (!filepath.isEmpty()) {
- QList urls;
urls.push_back(QUrl::fromLocalFile(filepath));
- result->setUrls(urls);
}
}
}
+
+ if (forwardIds.empty() && urls.isEmpty()) {
+ return nullptr;
+ }
+
+ auto result = std::make_unique();
+ if (!forwardIds.empty()) {
+ session().data().setMimeForwardIds(std::move(forwardIds));
+ result->setData(u"application/x-td-forward"_q, "1");
+ }
+ if (!urls.isEmpty()) {
+ result->setUrls(urls);
+ }
return result;
}
return nullptr;
diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp
index 7f4392202..0f6d808b5 100644
--- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp
@@ -3786,12 +3786,7 @@ std::unique_ptr ListWidget::prepareDrag() {
forwardIds = MessageIdsList(1, exactItem->fullId());
}
}
- if (forwardIds.empty()) {
- return nullptr;
- }
- session().data().setMimeForwardIds(std::move(forwardIds));
- auto result = std::make_unique();
- result->setData(u"application/x-td-forward"_q, "1");
+
if (pressedHandler) {
const auto lnkDocument = reinterpret_cast(
pressedHandler->property(
@@ -3799,12 +3794,23 @@ std::unique_ptr ListWidget::prepareDrag() {
if (lnkDocument) {
const auto filepath = lnkDocument->filepath(true);
if (!filepath.isEmpty()) {
- QList urls;
urls.push_back(QUrl::fromLocalFile(filepath));
- result->setUrls(urls);
}
}
}
+
+ if (forwardIds.empty() && urls.isEmpty()) {
+ return nullptr;
+ }
+
+ auto result = std::make_unique();
+ if (!forwardIds.empty()) {
+ session().data().setMimeForwardIds(std::move(forwardIds));
+ result->setData(u"application/x-td-forward"_q, "1");
+ }
+ if (!urls.isEmpty()) {
+ result->setUrls(urls);
+ }
return result;
}
return nullptr;
diff --git a/Telegram/SourceFiles/info/bot/earn/info_earn_inner_widget.cpp b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp
similarity index 99%
rename from Telegram/SourceFiles/info/bot/earn/info_earn_inner_widget.cpp
rename to Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp
index 2b152ad6f..169fe8883 100644
--- a/Telegram/SourceFiles/info/bot/earn/info_earn_inner_widget.cpp
+++ b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp
@@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
-#include "info/bot/earn/info_earn_inner_widget.h"
+#include "info/bot/earn/info_bot_earn_list.h"
#include "api/api_credits.h"
#include "api/api_filter_updates.h"
@@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/stickers/data_custom_emoji.h"
-#include "info/bot/earn/info_earn_widget.h"
+#include "info/bot/earn/info_bot_earn_widget.h"
#include "info/channel_statistics/earn/earn_format.h"
#include "info/info_controller.h"
#include "info/statistics/info_statistics_inner_widget.h" // FillLoading.
diff --git a/Telegram/SourceFiles/info/bot/earn/info_earn_inner_widget.h b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.h
similarity index 100%
rename from Telegram/SourceFiles/info/bot/earn/info_earn_inner_widget.h
rename to Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.h
diff --git a/Telegram/SourceFiles/info/bot/earn/info_earn_widget.cpp b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_widget.cpp
similarity index 96%
rename from Telegram/SourceFiles/info/bot/earn/info_earn_widget.cpp
rename to Telegram/SourceFiles/info/bot/earn/info_bot_earn_widget.cpp
index 59ddb37aa..03ad190ce 100644
--- a/Telegram/SourceFiles/info/bot/earn/info_earn_widget.cpp
+++ b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_widget.cpp
@@ -5,9 +5,9 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
-#include "info/bot/earn/info_earn_widget.h"
+#include "info/bot/earn/info_bot_earn_widget.h"
-#include "info/bot/earn/info_earn_inner_widget.h"
+#include "info/bot/earn/info_bot_earn_list.h"
#include "info/info_controller.h"
#include "info/info_memento.h"
#include "lang/lang_keys.h"
diff --git a/Telegram/SourceFiles/info/bot/earn/info_earn_widget.h b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_widget.h
similarity index 100%
rename from Telegram/SourceFiles/info/bot/earn/info_earn_widget.h
rename to Telegram/SourceFiles/info/bot/earn/info_bot_earn_widget.h
diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp
similarity index 99%
rename from Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp
rename to Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp
index 9fea4508c..84ad81390 100644
--- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp
+++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp
@@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
-#include "info/channel_statistics/earn/info_earn_inner_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_list.h"
#include "api/api_credits.h"
#include "api/api_earn.h"
@@ -24,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/stickers/data_custom_emoji.h"
#include "history/view/controls/history_view_webpage_processor.h"
#include "info/channel_statistics/earn/earn_format.h"
-#include "info/channel_statistics/earn/info_earn_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_widget.h"
#include "info/info_controller.h"
#include "info/profile/info_profile_values.h" // Info::Profile::NameValue.
#include "info/statistics/info_statistics_inner_widget.h" // FillLoading.
diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.h b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.h
similarity index 95%
rename from Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.h
rename to Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.h
index d9f43192e..061d69b7e 100644
--- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.h
+++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.h
@@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
-#include "info/channel_statistics/earn/info_earn_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_widget.h"
#include "ui/widgets/scroll_area.h"
#include "ui/wrap/vertical_layout.h"
diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_widget.cpp
similarity index 95%
rename from Telegram/SourceFiles/info/channel_statistics/earn/info_earn_widget.cpp
rename to Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_widget.cpp
index b0c38e1ad..dabd5e6ea 100644
--- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_widget.cpp
+++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_widget.cpp
@@ -5,9 +5,9 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
-#include "info/channel_statistics/earn/info_earn_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_widget.h"
-#include "info/channel_statistics/earn/info_earn_inner_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_list.h"
#include "info/info_controller.h"
#include "info/info_memento.h"
#include "lang/lang_keys.h"
diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_widget.h b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_widget.h
similarity index 100%
rename from Telegram/SourceFiles/info/channel_statistics/earn/info_earn_widget.h
rename to Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_widget.h
diff --git a/Telegram/SourceFiles/iv/iv_controller.cpp b/Telegram/SourceFiles/iv/iv_controller.cpp
index c717c8625..10e1e506b 100644
--- a/Telegram/SourceFiles/iv/iv_controller.cpp
+++ b/Telegram/SourceFiles/iv/iv_controller.cpp
@@ -346,9 +346,11 @@ void Controller::createWindow() {
_window = std::make_unique();
const auto window = _window.get();
- window->windowActiveValue(
- ) | rpl::filter([=](bool active) {
- return _webview && active;
+ base::qt_signal_producer(
+ window->window()->windowHandle(),
+ &QWindow::activeChanged
+ ) | rpl::filter([=] {
+ return _webview && window->window()->windowHandle()->isActive();
}) | rpl::start_with_next([=] {
setInnerFocus();
}, window->lifetime());
diff --git a/Telegram/SourceFiles/iv/iv_data.cpp b/Telegram/SourceFiles/iv/iv_data.cpp
index 5258e6c9f..16f9c0d51 100644
--- a/Telegram/SourceFiles/iv/iv_data.cpp
+++ b/Telegram/SourceFiles/iv/iv_data.cpp
@@ -71,6 +71,12 @@ bool Data::partial() const {
Data::~Data() = default;
+void Data::updateCachedViews(int cachedViews) {
+ _source->updatedCachedViews = std::max(
+ _source->updatedCachedViews,
+ cachedViews);
+}
+
void Data::prepare(const Options &options, Fn done) const {
crl::async([source = *_source, options, done = std::move(done)] {
done(Prepare(source, options));
diff --git a/Telegram/SourceFiles/iv/iv_data.h b/Telegram/SourceFiles/iv/iv_data.h
index 87900bce3..cdb2d8708 100644
--- a/Telegram/SourceFiles/iv/iv_data.h
+++ b/Telegram/SourceFiles/iv/iv_data.h
@@ -45,6 +45,8 @@ public:
[[nodiscard]] QString id() const;
[[nodiscard]] bool partial() const;
+ void updateCachedViews(int cachedViews);
+
void prepare(const Options &options, Fn done) const;
private:
diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp
index 69df5f772..d070c93d2 100644
--- a/Telegram/SourceFiles/iv/iv_instance.cpp
+++ b/Telegram/SourceFiles/iv/iv_instance.cpp
@@ -57,6 +57,7 @@ constexpr auto kGeoPointScale = 1;
constexpr auto kGeoPointZoomMin = 13;
constexpr auto kMaxLoadParts = 5;
constexpr auto kKeepLoadingParts = 8;
+constexpr auto kAllowPageReloadAfter = 3 * crl::time(1000);
} // namespace
@@ -815,19 +816,19 @@ void Instance::show(
}
break;
case Type::OpenPage:
- case Type::OpenLink:
+ case Type::OpenLink: {
if (!urlChecked) {
break;
}
- _fullRequested[_shownSession].emplace(event.url);
- _shownSession->api().request(MTPmessages_GetWebPage(
- MTP_string(event.url),
- MTP_int(0)
+ const auto session = _shownSession;
+ const auto url = event.url;
+ auto &requested = _fullRequested[session][url];
+ requested.lastRequestedAt = crl::now();
+ session->api().request(MTPmessages_GetWebPage(
+ MTP_string(url),
+ MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) {
- _shownSession->data().processUsers(result.data().vusers());
- _shownSession->data().processChats(result.data().vchats());
- const auto page = _shownSession->data().processWebpage(
- result.data().vwebpage());
+ const auto page = processReceivedPage(session, url, result);
if (page && page->iv) {
const auto parts = event.url.split('#');
const auto hash = (parts.size() > 1) ? parts[1] : u""_q;
@@ -838,7 +839,7 @@ void Instance::show(
}).fail([=] {
UrlClickHandler::Open(event.url);
}).send();
- break;
+ } break;
case Type::Report:
if (const auto controller = _shownSession->tryResolveWindow()) {
controller->window().activate();
@@ -954,15 +955,13 @@ void Instance::openWithIvPreferred(
};
_ivRequestSession = session;
_ivRequestUri = uri;
- _fullRequested[session].emplace(url);
+ auto &requested = _fullRequested[session][url];
+ requested.lastRequestedAt = crl::now();
_ivRequestId = session->api().request(MTPmessages_GetWebPage(
MTP_string(url),
- MTP_int(0)
+ MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) {
- const auto &data = result.data();
- session->data().processUsers(data.vusers());
- session->data().processChats(data.vchats());
- finish(session->data().processWebpage(data.vwebpage()));
+ finish(processReceivedPage(session, url, result));
}).fail([=] {
finish(nullptr);
}).send();
@@ -971,24 +970,53 @@ void Instance::openWithIvPreferred(
void Instance::requestFull(
not_null session,
const QString &id) {
- if (!_tracking.contains(session)
- || !_fullRequested[session].emplace(id).second) {
+ if (!_tracking.contains(session)) {
return;
}
+ auto &requested = _fullRequested[session][id];
+ const auto last = requested.lastRequestedAt;
+ const auto now = crl::now();
+ if (last && (now - last) < kAllowPageReloadAfter) {
+ return;
+ }
+ requested.lastRequestedAt = now;
session->api().request(MTPmessages_GetWebPage(
MTP_string(id),
- MTP_int(0)
+ MTP_int(requested.hash)
)).done([=](const MTPmessages_WebPage &result) {
- session->data().processUsers(result.data().vusers());
- session->data().processChats(result.data().vchats());
- const auto page = session->data().processWebpage(
- result.data().vwebpage());
+ const auto page = processReceivedPage(session, id, result);
if (page && page->iv && _shown && _shownSession == session) {
_shown->update(page->iv.get());
}
}).send();
}
+WebPageData *Instance::processReceivedPage(
+ not_null session,
+ const QString &url,
+ const MTPmessages_WebPage &result) {
+ const auto &data = result.data();
+ const auto owner = &session->data();
+ owner->processUsers(data.vusers());
+ owner->processChats(data.vchats());
+ auto &requested = _fullRequested[session][url];
+ const auto &mtp = data.vwebpage();
+ mtp.match([&](const MTPDwebPageNotModified &data) {
+ const auto page = requested.page;
+ if (const auto views = data.vcached_page_views()) {
+ if (page && page->iv) {
+ page->iv->updateCachedViews(views->v);
+ }
+ }
+ }, [&](const MTPDwebPage &data) {
+ requested.hash = data.vhash().v;
+ requested.page = owner->processWebpage(data).get();
+ }, [&](const auto &) {
+ requested.page = owner->processWebpage(mtp).get();
+ });
+ return requested.page;
+}
+
void Instance::processOpenChannel(const QString &context) {
if (!_shownSession) {
return;
diff --git a/Telegram/SourceFiles/iv/iv_instance.h b/Telegram/SourceFiles/iv/iv_instance.h
index 1299bbddd..9083734ad 100644
--- a/Telegram/SourceFiles/iv/iv_instance.h
+++ b/Telegram/SourceFiles/iv/iv_instance.h
@@ -61,12 +61,23 @@ public:
[[nodiscard]] rpl::lifetime &lifetime();
private:
+ struct FullResult {
+ crl::time lastRequestedAt = 0;
+ WebPageData *page = nullptr;
+ int32 hash = 0;
+ };
+
void processOpenChannel(const QString &context);
void processJoinChannel(const QString &context);
void requestFull(not_null session, const QString &id);
void trackSession(not_null session);
+ WebPageData *processReceivedPage(
+ not_null session,
+ const QString &url,
+ const MTPmessages_WebPage &result);
+
const not_null _delegate;
std::unique_ptr _shown;
@@ -77,7 +88,7 @@ private:
base::flat_set>> _joining;
base::flat_map<
not_null,
- base::flat_set> _fullRequested;
+ base::flat_map> _fullRequested;
base::flat_map<
not_null,
diff --git a/Telegram/SourceFiles/iv/iv_prepare.cpp b/Telegram/SourceFiles/iv/iv_prepare.cpp
index d5f537524..15d5edaa7 100644
--- a/Telegram/SourceFiles/iv/iv_prepare.cpp
+++ b/Telegram/SourceFiles/iv/iv_prepare.cpp
@@ -229,7 +229,9 @@ Parser::Parser(const Source &source, const Options &options)
_result.name = source.name;
_result.rtl = source.page.data().is_rtl();
- const auto views = source.page.data().vviews().value_or_empty();
+ const auto views = std::max(
+ source.page.data().vviews().value_or_empty(),
+ source.updatedCachedViews);
const auto content = list(source.page.data().vblocks());
_result.content = wrap(content, views);
}
diff --git a/Telegram/SourceFiles/iv/iv_prepare.h b/Telegram/SourceFiles/iv/iv_prepare.h
index a896c79e0..ef919db2f 100644
--- a/Telegram/SourceFiles/iv/iv_prepare.h
+++ b/Telegram/SourceFiles/iv/iv_prepare.h
@@ -18,6 +18,7 @@ struct Source {
std::optional webpagePhoto;
std::optional webpageDocument;
QString name;
+ int updatedCachedViews = 0;
};
[[nodiscard]] Prepared Prepare(const Source &source, const Options &options);
diff --git a/Telegram/SourceFiles/main/main_domain.cpp b/Telegram/SourceFiles/main/main_domain.cpp
index 9b4b12067..714f7e291 100644
--- a/Telegram/SourceFiles/main/main_domain.cpp
+++ b/Telegram/SourceFiles/main/main_domain.cpp
@@ -403,6 +403,8 @@ bool Domain::removePasscodeIfEmpty() {
return false;
}
_local->setPasscode(QByteArray());
+ Core::App().settings().setSystemUnlockEnabled(false);
+ Core::App().saveSettingsDelayed();
return true;
}
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index fe56772d0..bfcda6f69 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -1193,9 +1193,11 @@ void MainWidget::setInnerFocus() {
_mainSection->setInnerFocus();
} else if (!_hider && _thirdSection) {
_thirdSection->setInnerFocus();
- } else {
- Assert(_dialogs != nullptr);
+ } else if (_dialogs) {
_dialogs->setInnerFocus();
+ } else {
+ // Maybe we're just closing a child window, content is destroyed.
+ _history->setFocus();
}
} else if (_mainSection) {
_mainSection->setInnerFocus();
@@ -1294,8 +1296,9 @@ void MainWidget::showHistory(
}
const auto unavailable = peer->computeUnavailableReason();
if (!unavailable.isEmpty()) {
- Assert(isPrimary()); // windows todo
- if (params.activation != anim::activation::background) {
+ if (!isPrimary()) {
+ _controller->window().close();
+ } else if (params.activation != anim::activation::background) {
_controller->show(Ui::MakeInformBox(unavailable));
_controller->window().activate();
}
@@ -1951,10 +1954,9 @@ void MainWidget::showNonPremiumLimitToast(bool download) {
});
}
-void MainWidget::showBackFromStack(
- const SectionShow ¶ms) {
+bool MainWidget::showBackFromStack(const SectionShow ¶ms) {
if (preventsCloseSection([=] { showBackFromStack(params); }, params)) {
- return;
+ return false;
}
if (_stack.empty()) {
@@ -1964,7 +1966,7 @@ void MainWidget::showBackFromStack(
crl::on_main(this, [=] {
_controller->widget()->setInnerFocus();
});
- return;
+ return (_dialogs != nullptr);
}
auto item = std::move(_stack.back());
_stack.pop_back();
@@ -1996,6 +1998,7 @@ void MainWidget::showBackFromStack(
anim::activation::background));
}
+ return true;
}
void MainWidget::orderWidgets() {
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index 07b960fdd..6c30d38b1 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -152,8 +152,7 @@ public:
const SectionShow ¶ms);
void updateColumnLayout();
bool stackIsEmpty() const;
- void showBackFromStack(
- const SectionShow ¶ms);
+ bool showBackFromStack(const SectionShow ¶ms);
void orderWidgets();
QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms);
void checkMainSectionToLayer();
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
index 41c75c3e4..8895cde1f 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
@@ -510,15 +510,15 @@ OverlayWidget::OverlayWidget()
return base::EventFilterResult::Cancel;
}
} else if (e->type() == QEvent::WindowStateChange) {
- const auto state = _window->windowState();
- if (state & Qt::WindowMinimized || Platform::IsMac()) {
- } else if (state & Qt::WindowMaximized) {
+ const auto state = window()->windowState();
+ if (state == Qt::WindowMinimized || Platform::IsMac()) {
+ } else if (state == Qt::WindowMaximized) {
if (_fullscreen || _windowed) {
_fullscreen = _windowed = false;
savePosition();
}
} else if (_fullscreen || _windowed) {
- } else if (state & Qt::WindowFullScreen) {
+ } else if (state == Qt::WindowFullScreen) {
_fullscreen = true;
savePosition();
} else {
@@ -3856,16 +3856,12 @@ void OverlayWidget::updatePowerSaveBlocker(
&& !IsPausedOrPausing(state.state)
&& !IsStoppedOrStopping(state.state);
- _window->shownValue() | rpl::filter([=](bool shown) {
- return shown;
- }) | rpl::take(1) | rpl::start_with_next([=] {
- base::UpdatePowerSaveBlocker(
- _streamed->powerSaveBlocker,
- block,
- base::PowerSaveBlockType::PreventDisplaySleep,
- [] { return u"Video playback is active"_q; },
- [=] { return window(); });
- }, lifetime());
+ base::UpdatePowerSaveBlocker(
+ _streamed->powerSaveBlocker,
+ block,
+ base::PowerSaveBlockType::PreventDisplaySleep,
+ [] { return u"Video playback is active"_q; },
+ [=] { return _window->windowHandle(); });
}
QImage OverlayWidget::transformedShownContent() const {
diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
index 93865a587..4ab0ce839 100644
--- a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
+++ b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp
@@ -65,7 +65,7 @@ QByteArray DnsUserAgent() {
static const auto kResult = QByteArray(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/124.0.0.0 Safari/537.36");
+ "Chrome/126.0.0.0 Safari/537.36");
return kResult;
}
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 07ad565a5..25ac88992 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/linux/specific_linux.h"
+#include "base/openssl_help.h"
#include "base/random.h"
#include "base/platform/base_platform_info.h"
#include "base/platform/linux/base_linux_dbus_utilities.h"
@@ -480,6 +481,16 @@ void InstallLauncher() {
});
}
+[[nodiscard]] QByteArray HashForSocketPath(const QByteArray &data) {
+ constexpr auto kHashForSocketPathLength = 24;
+
+ const auto binary = openssl::Sha256(bytes::make_span(data));
+ const auto base64 = QByteArray(
+ reinterpret_cast(binary.data()),
+ binary.size()).toBase64(QByteArray::Base64UrlEncoding);
+ return base64.mid(0, kHashForSocketPathLength);
+}
+
} // namespace
namespace Platform {
@@ -686,8 +697,8 @@ void start() {
Webview::WebKitGTK::SetSocketPath(u"%1/%2-%3-webview-%4"_q.arg(
QDir::tempPath(),
- h,
- QCoreApplication::applicationName(),
+ HashForSocketPath(d),
+ u"TD"_q,//QCoreApplication::applicationName(), - make path smaller.
u"%1"_q).toStdString());
InstallLauncher();
diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
index 3e720ba59..648a64900 100644
--- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
+++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp
@@ -280,10 +280,7 @@ void FillCreditOptions(
inner->paintRequest(
) | rpl::start_with_next([=](const QRect &rect) {
auto p = QPainter(inner);
- p.drawImage(
- 0,
- (buttonHeight - stars.height()) / 2,
- stars);
+ p.drawImage(0, 0, stars);
const auto textLeft = diffBetweenTextAndStar
+ stars.width() / style::DevicePixelRatio();
p.setPen(st.textFg);
diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp
index 93e9e74dc..f578bce82 100644
--- a/Telegram/SourceFiles/settings/settings_experimental.cpp
+++ b/Telegram/SourceFiles/settings/settings_experimental.cpp
@@ -152,6 +152,7 @@ void SetupExperimental(
addToggle(kOptionAutoScrollInactiveChat);
addToggle(Window::Notifications::kOptionGNotification);
addToggle(Core::kOptionFreeType);
+ addToggle(Core::kOptionSkipUrlSchemeRegister);
addToggle(Data::kOptionExternalVideoPlayer);
addToggle(Window::kOptionNewWindowsSizeAsFirst);
}
diff --git a/Telegram/SourceFiles/settings/settings_local_passcode.cpp b/Telegram/SourceFiles/settings/settings_local_passcode.cpp
index db21f717b..193445caf 100644
--- a/Telegram/SourceFiles/settings/settings_local_passcode.cpp
+++ b/Telegram/SourceFiles/settings/settings_local_passcode.cpp
@@ -80,6 +80,7 @@ private:
rpl::event_stream<> _setInnerFocus;
rpl::event_stream _showOther;
rpl::event_stream<> _showBack;
+ bool _systemUnlockWithBiometric = false;
};
@@ -97,6 +98,13 @@ rpl::producer LocalPasscodeEnter::title() {
void LocalPasscodeEnter::setupContent() {
const auto content = Ui::CreateChild(this);
+ base::SystemUnlockStatus(
+ true
+ ) | rpl::start_with_next([=](base::SystemUnlockAvailability status) {
+ _systemUnlockWithBiometric = status.available
+ && status.withBiometrics;
+ }, lifetime());
+
const auto isCreate = (enterType() == EnterType::Create);
const auto isCheck = (enterType() == EnterType::Check);
[[maybe_unused]] const auto isChange = (enterType() == EnterType::Change);
@@ -242,8 +250,10 @@ void LocalPasscodeEnter::setupContent() {
}
SetPasscode(_controller, newText);
if (isCreate) {
- Core::App().settings().setSystemUnlockEnabled(true);
- Core::App().saveSettingsDelayed();
+ if (Platform::IsWindows() || _systemUnlockWithBiometric) {
+ Core::App().settings().setSystemUnlockEnabled(true);
+ Core::App().saveSettingsDelayed();
+ }
_showOther.fire(LocalPasscodeManageId());
} else if (isChange) {
_showBack.fire({});
@@ -518,38 +528,77 @@ void LocalPasscodeManage::setupContent() {
)->setDuration(0);
const auto systemUnlockContent = systemUnlockWrap->entity();
- Ui::AddSkip(systemUnlockContent);
+ enum class UnlockType {
+ None,
+ Default,
+ Biometrics,
+ Companion,
+ };
+ const auto unlockType = systemUnlockContent->lifetime().make_state<
+ rpl::variable
+ >(base::SystemUnlockStatus(
+ true
+ ) | rpl::map([](base::SystemUnlockAvailability status) {
+ return status.withBiometrics
+ ? UnlockType::Biometrics
+ : status.withCompanion
+ ? UnlockType::Companion
+ : status.available
+ ? UnlockType::Default
+ : UnlockType::None;
+ }));
+
+ unlockType->value(
+ ) | rpl::start_with_next([=](UnlockType type) {
+ while (systemUnlockContent->count()) {
+ delete systemUnlockContent->widgetAt(0);
+ }
+
+ Ui::AddSkip(systemUnlockContent);
+
+ AddButtonWithIcon(
+ systemUnlockContent,
+ (Platform::IsWindows()
+ ? tr::lng_settings_use_winhello()
+ : (type == UnlockType::Biometrics)
+ ? tr::lng_settings_use_touchid()
+ : (type == UnlockType::Companion)
+ ? tr::lng_settings_use_applewatch()
+ : tr::lng_settings_use_systempwd()),
+ st::settingsButton,
+ { Platform::IsWindows()
+ ? &st::menuIconWinHello
+ : (type == UnlockType::Biometrics)
+ ? &st::menuIconTouchID
+ : (type == UnlockType::Companion)
+ ? &st::menuIconAppleWatch
+ : &st::menuIconSystemPwd }
+ )->toggleOn(
+ rpl::single(Core::App().settings().systemUnlockEnabled())
+ )->toggledChanges(
+ ) | rpl::filter([=](bool value) {
+ return value != Core::App().settings().systemUnlockEnabled();
+ }) | rpl::start_with_next([=](bool value) {
+ Core::App().settings().setSystemUnlockEnabled(value);
+ Core::App().saveSettingsDelayed();
+ }, systemUnlockContent->lifetime());
+
+ Ui::AddSkip(systemUnlockContent);
+
+ Ui::AddDividerText(
+ systemUnlockContent,
+ (Platform::IsWindows()
+ ? tr::lng_settings_use_winhello_about()
+ : (type == UnlockType::Biometrics)
+ ? tr::lng_settings_use_touchid_about()
+ : (type == UnlockType::Companion)
+ ? tr::lng_settings_use_applewatch_about()
+ : tr::lng_settings_use_systempwd_about()));
- AddButtonWithIcon(
- systemUnlockContent,
- (Platform::IsWindows()
- ? tr::lng_settings_use_winhello()
- : tr::lng_settings_use_touchid()),
- st::settingsButton,
- { Platform::IsWindows()
- ? &st::menuIconWinHello
- : &st::menuIconTouchID }
- )->toggleOn(
- rpl::single(Core::App().settings().systemUnlockEnabled())
- )->toggledChanges(
- ) | rpl::filter([=](bool value) {
- return value != Core::App().settings().systemUnlockEnabled();
- }) | rpl::start_with_next([=](bool value) {
- Core::App().settings().setSystemUnlockEnabled(value);
- Core::App().saveSettingsDelayed();
}, systemUnlockContent->lifetime());
- Ui::AddSkip(systemUnlockContent);
-
- Ui::AddDividerText(
- systemUnlockContent,
- (Platform::IsWindows()
- ? tr::lng_settings_use_winhello_about()
- : tr::lng_settings_use_touchid_about()));
-
- using namespace rpl::mappers;
- systemUnlockWrap->toggleOn(base::SystemUnlockStatus(
- ) | rpl::map(_1 == base::SystemUnlockAvailability::Available));
+ systemUnlockWrap->toggleOn(unlockType->value(
+ ) | rpl::map(rpl::mappers::_1 != UnlockType::None));
Ui::ResizeFitChild(this, content);
}
@@ -562,6 +611,8 @@ QPointer LocalPasscodeManage::createPinnedToBottom(
.text = tr::lng_settings_passcode_disable_sure(),
.confirmed = [=](Fn &&close) {
SetPasscode(_controller, QString());
+ Core::App().settings().setSystemUnlockEnabled(false);
+ Core::App().saveSettingsDelayed();
close();
_showBack.fire({});
diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style
index ce1670203..96838e8a5 100644
--- a/Telegram/SourceFiles/ui/menu_icons.style
+++ b/Telegram/SourceFiles/ui/menu_icons.style
@@ -157,6 +157,8 @@ menuIconFont: icon {{ "menu/fonts", menuIconColor }};
menuIconFactcheck: icon {{ "menu/factcheck", menuIconColor }};
menuIconWinHello: icon {{ "menu/passcode_winhello", menuIconColor }};
menuIconTouchID: icon {{ "menu/passcode_finger", menuIconColor }};
+menuIconAppleWatch: icon {{ "menu/passcode_watch", menuIconColor }};
+menuIconSystemPwd: menuIconPermissions;
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
menuIconTTLAnyTextPosition: point(11px, 22px);
diff --git a/Telegram/SourceFiles/window/window_lock_widgets.cpp b/Telegram/SourceFiles/window/window_lock_widgets.cpp
index e6453fbf2..02350886e 100644
--- a/Telegram/SourceFiles/window/window_lock_widgets.cpp
+++ b/Telegram/SourceFiles/window/window_lock_widgets.cpp
@@ -110,8 +110,17 @@ PasscodeLockWidget::PasscodeLockWidget(
using namespace rpl::mappers;
if (Core::App().settings().systemUnlockEnabled()) {
- _systemUnlockAvailable = base::SystemUnlockStatus()
- | rpl::map(_1 == base::SystemUnlockAvailability::Available);
+ _systemUnlockAvailable = base::SystemUnlockStatus(
+ true
+ ) | rpl::map([](base::SystemUnlockAvailability status) {
+ return status.withBiometrics
+ ? SystemUnlockType::Biometrics
+ : status.withCompanion
+ ? SystemUnlockType::Companion
+ : status.available
+ ? SystemUnlockType::Default
+ : SystemUnlockType::None;
+ });
if (Core::App().domain().started()) {
_systemUnlockAllowed = _systemUnlockAvailable.value();
setupSystemUnlock();
@@ -122,11 +131,22 @@ PasscodeLockWidget::PasscodeLockWidget(
}
void PasscodeLockWidget::setupSystemUnlockInfo() {
+ const auto macos = [&] {
+ return _systemUnlockAvailable.value(
+ ) | rpl::map([](SystemUnlockType type) {
+ return (type == SystemUnlockType::Biometrics)
+ ? tr::lng_passcode_touchid()
+ : (type == SystemUnlockType::Companion)
+ ? tr::lng_passcode_applewatch()
+ : tr::lng_passcode_systempwd();
+ }) | rpl::flatten_latest();
+ };
+ auto text = Platform::IsWindows()
+ ? tr::lng_passcode_winhello()
+ : macos();
const auto info = Ui::CreateChild(
this,
- (Platform::IsWindows()
- ? tr::lng_passcode_winhello()
- : tr::lng_passcode_touchid()),
+ std::move(text),
st::passcodeSystemUnlockLater);
_logout->geometryValue(
) | rpl::start_with_next([=](QRect logout) {
@@ -137,7 +157,8 @@ void PasscodeLockWidget::setupSystemUnlockInfo() {
st::boxRowPadding.left(),
logout.y() + logout.height() + st::passcodeSystemUnlockSkip);
}, info->lifetime());
- info->showOn(_systemUnlockAvailable.value());
+ info->showOn(_systemUnlockAvailable.value(
+ ) | rpl::map(rpl::mappers::_1 != SystemUnlockType::None));
}
void PasscodeLockWidget::setupSystemUnlock() {
@@ -152,10 +173,21 @@ void PasscodeLockWidget::setupSystemUnlock() {
const auto button = Ui::CreateChild(
_passcode.data(),
- (Platform::IsWindows()
- ? st::passcodeSystemWinHello
- : st::passcodeSystemTouchID));
- button->showOn(_systemUnlockAllowed.value());
+ st::passcodeSystemUnlock);
+ if (!Platform::IsWindows()) {
+ using namespace base;
+ _systemUnlockAllowed.value(
+ ) | rpl::start_with_next([=](SystemUnlockType type) {
+ const auto icon = (type == SystemUnlockType::Biometrics)
+ ? &st::passcodeSystemTouchID
+ : (type == SystemUnlockType::Companion)
+ ? &st::passcodeSystemAppleWatch
+ : &st::passcodeSystemSystemPwd;
+ button->setIconOverride(icon, icon);
+ }, button->lifetime());
+ }
+ button->showOn(_systemUnlockAllowed.value(
+ ) | rpl::map(rpl::mappers::_1 != SystemUnlockType::None));
_passcode->sizeValue() | rpl::start_with_next([=](QSize size) {
button->moveToRight(0, size.height() - button->height());
}, button->lifetime());
@@ -177,7 +209,7 @@ void PasscodeLockWidget::suggestSystemUnlock() {
using namespace base;
_systemUnlockAllowed.value(
) | rpl::filter(
- rpl::mappers::_1
+ rpl::mappers::_1 != SystemUnlockType::None
) | rpl::take(1) | rpl::start_with_next([=] {
const auto weak = Ui::MakeWeak(this);
const auto done = [weak](SystemUnlockResult result) {
diff --git a/Telegram/SourceFiles/window/window_lock_widgets.h b/Telegram/SourceFiles/window/window_lock_widgets.h
index 8c48850fb..03c6b59b3 100644
--- a/Telegram/SourceFiles/window/window_lock_widgets.h
+++ b/Telegram/SourceFiles/window/window_lock_widgets.h
@@ -65,6 +65,13 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
+ enum class SystemUnlockType : uchar {
+ None,
+ Default,
+ Biometrics,
+ Companion,
+ };
+
void paintContent(QPainter &p) override;
void setupSystemUnlockInfo();
@@ -75,8 +82,8 @@ private:
void submit();
void error();
- rpl::variable _systemUnlockAvailable = false;
- rpl::variable _systemUnlockAllowed = false;
+ rpl::variable _systemUnlockAvailable;
+ rpl::variable _systemUnlockAllowed;
object_ptr _passcode;
object_ptr _submit;
object_ptr _logout;
diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp
index e4b892a3e..9398d33a1 100644
--- a/Telegram/SourceFiles/window/window_peer_menu.cpp
+++ b/Telegram/SourceFiles/window/window_peer_menu.cpp
@@ -67,7 +67,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/info_controller.h"
#include "info/info_memento.h"
#include "info/channel_statistics/boosts/info_boosts_widget.h"
-#include "info/channel_statistics/earn/info_earn_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_widget.h"
#include "info/profile/info_profile_values.h"
#include "info/statistics/info_statistics_widget.h"
#include "info/stories/info_stories_widget.h"
@@ -694,8 +694,9 @@ void Filler::addNewWindow() {
_addAction(tr::lng_context_new_window(tr::now), [=] {
Ui::PreventDelayedActivation();
if (const auto strong = weak.get()) {
+ const auto forum = !strong->asTopic() && peer->isForum();
controller->showInNewWindow(SeparateId(
- peer->isForum() ? SeparateType::Forum : SeparateType::Chat,
+ forum ? SeparateType::Forum : SeparateType::Chat,
strong));
}
}, &st::menuIconNewWindow);
diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp
index 7ab87cd80..34c7f9c0b 100644
--- a/Telegram/SourceFiles/window/window_session_controller.cpp
+++ b/Telegram/SourceFiles/window/window_session_controller.cpp
@@ -17,7 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "window/window_filters_menu.h"
#include "window/window_separate_id.h"
-#include "info/channel_statistics/earn/info_earn_inner_widget.h"
+#include "info/channel_statistics/earn/info_channel_earn_list.h"
#include "info/info_memento.h"
#include "info/info_controller.h"
#include "inline_bots/bot_attach_web_view.h"
@@ -1668,8 +1668,9 @@ void SessionController::showForum(
) | rpl::start_with_next([=, history = forum->history()] {
const auto now = activeChatCurrent().owningHistory();
const auto showHistory = !now || (now == history);
+ const auto weak = base::make_weak(this);
closeForum();
- if (showHistory) {
+ if (weak && showHistory) {
showPeerHistory(history, {
SectionShow::Way::Backward,
anim::type::normal,
@@ -1684,7 +1685,7 @@ void SessionController::closeForum() {
if (const auto forum = _shownForum.current()) {
const auto id = windowId();
if (id.type == SeparateType::Forum) {
- const auto initial = id.thread->asForum();
+ const auto initial = id.forum();
if (!initial || initial == forum) {
Core::App().closeWindow(_window);
} else {
@@ -2537,7 +2538,13 @@ void SessionController::showBackFromStack(const SectionShow ¶ms) {
return topic && topic->forum()->topicDeleted(topic->rootId());
};
do {
- content()->showBackFromStack(params);
+ const auto empty = content()->stackIsEmpty();
+ const auto shown = content()->showBackFromStack(params);
+ if (empty && !shown && content()->stackIsEmpty() && bad()) {
+ clearSectionStack(anim::type::instant);
+ window().close();
+ break;
+ }
} while (bad());
}
diff --git a/Telegram/build/version b/Telegram/build/version
index fdada4a89..553191613 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 5002000
+AppVersion 5002002
AppVersionStrMajor 5.2
-AppVersionStrSmall 5.2
-AppVersionStr 5.2.0
+AppVersionStrSmall 5.2.2
+AppVersionStr 5.2.2
BetaChannel 0
AlphaVersion 0
-AppVersionOriginal 5.2
+AppVersionOriginal 5.2.2
diff --git a/Telegram/lib_base b/Telegram/lib_base
index b512eead3..f30400147 160000
--- a/Telegram/lib_base
+++ b/Telegram/lib_base
@@ -1 +1 @@
-Subproject commit b512eead302cb7b509869778348d60fef64bc19b
+Subproject commit f30400147d997fedc787e214467d305db6c159e7
diff --git a/Telegram/lib_spellcheck b/Telegram/lib_spellcheck
index 59d922617..0b7622ff3 160000
--- a/Telegram/lib_spellcheck
+++ b/Telegram/lib_spellcheck
@@ -1 +1 @@
-Subproject commit 59d92261783ae403e8708f972c36be3d21ab064d
+Subproject commit 0b7622ff38778e9cd03d3997de59351973480a1f
diff --git a/changelog.txt b/changelog.txt
index ad1f99ab1..6e398bcc6 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,16 @@
+5.2.2 (02.07.24)
+
+- Fix topics search in topic groups.
+- Fix Instant View pages content updating.
+
+5.2.1 (01.07.24)
+
+- Fix crash when opening topic in a new window.
+- Fix crash in topic search scope dropdown.
+- Fix crash in video player.
+- Fix feeze and crash in Instant View (Windows).
+- Allow unlock by Apple Watch or System Password (macOS).
+
5.2 (30.06.24)
- Pay for content with Telegram Stars.