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 b517e1f8d..db9afbe0e 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/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index fbe98a496..c3cad02eb 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/settings/settings_local_passcode.cpp b/Telegram/SourceFiles/settings/settings_local_passcode.cpp index db21f717b..01562905a 100644 --- a/Telegram/SourceFiles/settings/settings_local_passcode.cpp +++ b/Telegram/SourceFiles/settings/settings_local_passcode.cpp @@ -518,38 +518,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); } 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/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