From acea4309bb1b2e8d14b51e1429d2ae5d29e5eb61 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 5 Jan 2026 15:43:20 +0400 Subject: [PATCH 001/169] Fix monospace parsing --- Telegram/Common/TextStyleRun.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Common/TextStyleRun.cs b/Telegram/Common/TextStyleRun.cs index 69b84bcafa..927f5f89c8 100644 --- a/Telegram/Common/TextStyleRun.cs +++ b/Telegram/Common/TextStyleRun.cs @@ -230,7 +230,7 @@ private static bool ContainsLineBreaks(string text, int offset, int length) var starts = offset == 0 || _lineBreakChars.Contains(text[offset - 1]); var ends = offset + length == text.Length || _lineBreakChars.Contains(text[offset + length]); - return (starts && ends) || text.IndexOfAny(_lineBreakChars) >= 0; + return (starts && ends) || text.IndexOfAny(_lineBreakChars, offset, length) >= 0; } public static IList GetEntities(string text, IList runs) From ce2ca7ba1aa2c49b5299fddc9c2dea8edb6ae1ff Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 5 Jan 2026 15:44:04 +0400 Subject: [PATCH 002/169] More translated errors --- Telegram/Common/ExceptionSerializer.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Telegram/Common/ExceptionSerializer.cs b/Telegram/Common/ExceptionSerializer.cs index 6bf13c7d89..c3b144ae1a 100644 --- a/Telegram/Common/ExceptionSerializer.cs +++ b/Telegram/Common/ExceptionSerializer.cs @@ -574,7 +574,9 @@ private static string TranslateText(string text) case "Parametr jest niepoprawny.": case "Felaktig parameter.": case "매개 변수가 틀립니다.": + case "パラメーターが間違っています。": case "参数错误。": + case "參數錯誤。": return "The parameter is incorrect."; case "Geçersiz işaretçi": @@ -629,6 +631,7 @@ private static string TranslateText(string text) case "Ikke nok minneressurser tilgjengelig for å fullføre denne operasjonen.": case "Bu işlemi tamamlamak için yeterli bellek kaynağı yok.": case "Недостаточно ресурсов памяти для завершения операции.": + case "Недостаточно ресурсов памяти для обработки этой команды.": case "メモリ リソースが不足しているため、この操作を完了できません。": case "記憶體資源不足,無法完成此作業。": case "系统资源不足,无法完成请求的服务。": @@ -663,6 +666,7 @@ private static string TranslateText(string text) case "Operación anulada": case "Операция прервана": case "İşlem iptal edildi": + case "작업이 중단되었습니다.": return "Operation aborted"; case "Défaillance irrémédiable": @@ -715,9 +719,18 @@ private static string TranslateText(string text) case "Источник мультимедиа не может перейти из остановленного состояния в приостановленное.": return "A media source cannot go from the stopped state to the paused state."; + case "Un événement n’a pu invoquer aucun des abonnés.": case "Событие не смогло вызвать ни одного из абонентов": return "An event was unable to invoke any of the subscribers"; + case "Le package n'a pas de répertoire mutable.": + case "Пакет не имеет изменяемого каталога.": + return "The package does not have a mutable directory."; + + case "Die Ressource wurde auf dem falschen Renderziel erkannt.": + case "Kaynak yanlış işleme hedefinde gerçekleştirildi.": + return "The resource was realized on the wrong render target."; + default: return text; } From ad1b2efe53a09ea306ef427d330e20d45d284586 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 12:48:21 +0400 Subject: [PATCH 003/169] Use only first line for exception hash --- Telegram/Common/ExceptionSerializer.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Telegram/Common/ExceptionSerializer.cs b/Telegram/Common/ExceptionSerializer.cs index c3b144ae1a..bfe0d5ecf6 100644 --- a/Telegram/Common/ExceptionSerializer.cs +++ b/Telegram/Common/ExceptionSerializer.cs @@ -163,7 +163,16 @@ private static string Serialize(ErrorExceptionAndBinaries error, string id, stri hashBuilder.Append(report.ApplicationVersion); hashBuilder.Append(report.Type.ToLowerInvariant()); - hashBuilder.Append(report.Message.ToLowerInvariant()); + + var lineBreak = report.Message.IndexOf('\n'); + if (lineBreak != -1) + { + hashBuilder.Append(report.Message[..lineBreak].ToLowerInvariant()); + } + else + { + hashBuilder.Append(report.Message.ToLowerInvariant()); + } report.GroupHash = ComputeHash(hashBuilder.ToString()); @@ -461,7 +470,7 @@ private static int GetImageSize(IntPtr imageBase) private static string TranslateMessage(string message) { - var parts = message.Split(new[] { '\n' }); + var parts = message.Split('\n'); var builder = new StringBuilder(); for (int i = 0; i < parts.Length; i++) From cd1eaca94b9987e520599bee339c9736e9e28c83 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 12:48:52 +0400 Subject: [PATCH 004/169] Enqueue collection on UI thread --- .../InactivityGarbageCollectionMonitor.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Telegram/Common/InactivityGarbageCollectionMonitor.cs b/Telegram/Common/InactivityGarbageCollectionMonitor.cs index 3c5c05fde1..da67fa85cd 100644 --- a/Telegram/Common/InactivityGarbageCollectionMonitor.cs +++ b/Telegram/Common/InactivityGarbageCollectionMonitor.cs @@ -10,6 +10,7 @@ using System.Runtime.CompilerServices; using System.Threading; using Telegram.Native; +using Telegram.Navigation; using Telegram.Services; using Windows.Foundation; using Windows.System; @@ -168,10 +169,7 @@ public static void DisconnectUnusedReferenceSources() _count++; Logger.Info(); - - NativeUtils.Collect = true; - GC.Collect(2, GCCollectionMode.Optimized, blocking: true, compacting: false); - NativeUtils.Collect = false; + WindowContext.Main?.Dispatcher.Dispatch(BlockingCollect); } else { @@ -229,11 +227,22 @@ private static void TryTriggerCollection() _xamlCollectionRequested = false; _count++; - Logger.Info(); + Logger.Info($"{_count}/{_requested}"); + WindowContext.Main?.Dispatcher.Dispatch(Collect); + } + private static void Collect() + { NativeUtils.Collect = true; GC.Collect(); NativeUtils.Collect = false; } + + private static void BlockingCollect() + { + NativeUtils.Collect = true; + GC.Collect(2, GCCollectionMode.Optimized, blocking: true, compacting: false); + NativeUtils.Collect = false; + } } } From fa548249de9181ae02c2a2310d8ed1d63525aa03 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 12:49:10 +0400 Subject: [PATCH 005/169] Let the app close on 0x8001010A --- Telegram/Common/WatchDog.cs | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/Telegram/Common/WatchDog.cs b/Telegram/Common/WatchDog.cs index 12aeeec925..ec0b0e76f4 100644 --- a/Telegram/Common/WatchDog.cs +++ b/Telegram/Common/WatchDog.cs @@ -259,7 +259,8 @@ private static async Task HandleReportAsync(string reportPath) [HandleProcessCorruptedStateExceptions, SecurityCritical] private static void OnUnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs args) { - args.Handled = args.Exception is not LayoutCycleException; + args.Handled = args.Exception is not LayoutCycleException + && args.Exception.HResult != unchecked((int)0x8001010A); if (args.Exception is LayoutCycleException) { @@ -281,10 +282,6 @@ private static void OnUnhandledException(object sender, Windows.UI.Xaml.Unhandle return; } - else if (args.Exception is COMException { ErrorCode: -2147467259 }) - { - return; - } if (SettingsService.Current.Diagnostics.ShowMemoryUsage && Window.Current?.Content?.XamlRoot != null) { @@ -339,25 +336,6 @@ public static void FatalErrorCallback(FatalError error) ProcessException(error, false); } - private static Exception ToException(FatalError error) - { - if (error == null) - { - return null; - } - - if (error.StackTrace.Contains("libvlc.dll") || error.StackTrace.Contains("libvlccore.dll")) - { - return new VLCException(error.Message, error.StackTrace); - } - else if (error.StackTrace.Contains("Telegram.Native.Calls.dll")) - { - return new VoipException(error.Message, error.StackTrace); - } - - return new NativeException(error.Message, error.StackTrace); - } - public static void Launch(ApplicationExecutionState previousExecutionState) { // NotRunning: An app could be in this state because it hasn't been launched From ff83922808a6f2cd9eb64204d2386ce6ee0e5bd4 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 12:50:56 +0400 Subject: [PATCH 006/169] Fix null ref --- Telegram/Controls/Gallery/GalleryContent.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Controls/Gallery/GalleryContent.xaml.cs b/Telegram/Controls/Gallery/GalleryContent.xaml.cs index da80ecf354..3d9ea4738e 100644 --- a/Telegram/Controls/Gallery/GalleryContent.xaml.cs +++ b/Telegram/Controls/Gallery/GalleryContent.xaml.cs @@ -631,7 +631,7 @@ public async void RecognizeText() return; } - var viewModel = _window.ViewModel; + var viewModel = _window?.ViewModel; if (viewModel == null) { return; From a08d730a3046c5c9356263a3a6ad7683950e5bf9 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 12:51:20 +0400 Subject: [PATCH 007/169] Fix RhCollect monitoring --- Telegram.Native/NativeUtils.cpp | 54 ++++++++++++++++++++++++++++++++- Telegram.Native/NativeUtils.h | 16 +++++----- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/Telegram.Native/NativeUtils.cpp b/Telegram.Native/NativeUtils.cpp index 89b59d9d72..076abba821 100644 --- a/Telegram.Native/NativeUtils.cpp +++ b/Telegram.Native/NativeUtils.cpp @@ -33,9 +33,13 @@ namespace winrt::Telegram::Native::implementation PFN_RhGetCurrentObjSize NativeUtils::s_RhGetCurrentObjSize; PFN_RhCollect NativeUtils::s_RhCollect; + Application::Suspending_revoker NativeUtils::s_suspending = {}; + Application::Resuming_revoker NativeUtils::s_resuming = {}; + CollectCallback NativeUtils::s_collectCallback; std::mutex NativeUtils::s_collectLock; bool NativeUtils::s_collect = false; + bool NativeUtils::s_suspended = false; void NativeUtils::SetFatalErrorCallback(FatalErrorCallback callback) { @@ -94,6 +98,12 @@ namespace winrt::Telegram::Native::implementation } DetourTransactionCommit(); + + if (s_RhCollect) + { + s_suspending = Application::Current().Suspending(winrt::auto_revoke, &NativeUtils::OnSuspending); + s_resuming = Application::Current().Resuming(winrt::auto_revoke, &NativeUtils::OnResuming); + } } } } @@ -102,7 +112,7 @@ namespace winrt::Telegram::Native::implementation { std::lock_guard const guard(s_collectLock); - if (value == s_collect || !s_RhCollect) + if (value == s_collect || s_suspended || !s_RhCollect) { return; } @@ -128,6 +138,48 @@ namespace winrt::Telegram::Native::implementation } } + void NativeUtils::OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e) + { + std::lock_guard const guard(s_collectLock); + + if (s_suspended || !s_RhCollect) + { + return; + } + + s_suspended = true; + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100 && s_RhCollect) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); + DetourTransactionCommit(); + } + } + + void NativeUtils::OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e) + { + std::lock_guard const guard(s_collectLock); + + if (!s_suspended || !s_RhCollect) + { + return; + } + + s_suspended = false; + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100 && s_RhCollect) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); + DetourTransactionCommit(); + } + } + inline bool Contains(const hstring& message, std::wstring_view text) { return std::wstring_view{ message }.find(text) != std::wstring_view::npos; diff --git a/Telegram.Native/NativeUtils.h b/Telegram.Native/NativeUtils.h index 4f91a41bf7..159d81c513 100644 --- a/Telegram.Native/NativeUtils.h +++ b/Telegram.Native/NativeUtils.h @@ -120,8 +120,12 @@ namespace winrt::Telegram::Native::implementation static ULONGLONG FileTimeToSeconds(FILETIME& ft); static bool IsFileReadableInternal(hstring path, int64_t* fileSize, int64_t* fileTime); + static Application::Suspending_revoker s_suspending; + static Application::Resuming_revoker s_resuming; + static std::mutex s_collectLock; static bool s_collect; + static bool s_suspended; static INT64 RhGetCurrentObjSize() { @@ -130,15 +134,11 @@ namespace winrt::Telegram::Native::implementation static void RhCollect(int generation, int mode) { - if ((generation == 2 && mode == 6)) - { - s_RhCollect(generation, mode); - } - else - { - post_to_threadpool([&]() { s_collectCallback(generation, mode); }); - } + post_to_threadpool([&]() { s_collectCallback(generation, mode); }); } + + static void OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e); + static void OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e); }; } // namespace winrt::Telegram::Native::implementation From c77a3d6e3b60f2c5135bfef77eaf622fc8699c84 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 13:03:33 +0400 Subject: [PATCH 008/169] Fix GlobalMemoryStatusEx --- Telegram/Common/WatchDog.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Telegram/Common/WatchDog.cs b/Telegram/Common/WatchDog.cs index ec0b0e76f4..041ef1e8ff 100644 --- a/Telegram/Common/WatchDog.cs +++ b/Telegram/Common/WatchDog.cs @@ -384,17 +384,13 @@ public static MEMORYSTATUSEX Create() [DllImport("kernelbase.dll", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); + private static extern unsafe bool GlobalMemoryStatusEx(MEMORYSTATUSEX* lpBuffer); #endif public static unsafe void MemoryStatus() { var status = MEMORYSTATUSEX.Create(); -#if NET9_0_OR_GREATER GlobalMemoryStatusEx(&status); -#else - GlobalMemoryStatusEx(status); -#endif var memoryUsage = FileSizeConverter.Convert((long)MemoryManager.AppMemoryUsage); var memoryUsageAvailable = FileSizeConverter.Convert((long)status.ullAvailPhys); @@ -414,11 +410,7 @@ public static unsafe string BuildReport(int hresult) var count = SettingsService.Current.Diagnostics.UpdateCount; var status = MEMORYSTATUSEX.Create(); -#if NET9_0_OR_GREATER GlobalMemoryStatusEx(&status); -#else - GlobalMemoryStatusEx(status); -#endif var memoryUsage = FileSizeConverter.Convert((long)MemoryManager.AppMemoryUsage); var memoryUsageAvailable = FileSizeConverter.Convert((long)status.ullAvailPhys); From 8510b97c6aa7444c6abeae40b2a0b5d44e538dd4 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 14:24:11 +0400 Subject: [PATCH 009/169] Safer string format --- Telegram/Controls/Cells/CryptoAmountCell.xaml.cs | 3 +-- .../Controls/Cells/Revenue/ChatRevenueTransactionCell.xaml.cs | 3 +-- Telegram/Views/Chats/ChatRevenuePage.xaml.cs | 3 +-- Telegram/Views/Monetization/Popups/TransactionPopup.xaml.cs | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Telegram/Controls/Cells/CryptoAmountCell.xaml.cs b/Telegram/Controls/Cells/CryptoAmountCell.xaml.cs index fda4ee50a9..913526b4dd 100644 --- a/Telegram/Controls/Cells/CryptoAmountCell.xaml.cs +++ b/Telegram/Controls/Cells/CryptoAmountCell.xaml.cs @@ -48,13 +48,12 @@ public void UpdateAmount(CryptoAmount value) var doubleAmount = Formatter.Amount(value.CryptocurrencyAmount, value.Cryptocurrency); var stringAmount = doubleAmount.ToString(CultureInfo.InvariantCulture).Split('.'); - var integerAmount = long.Parse(stringAmount[0]); var decimalAmount = stringAmount.Length > 1 ? stringAmount[1] : "0"; var culture = new CultureInfo(NativeUtils.GetCurrentCulture()); var separator = culture.NumberFormat.NumberDecimalSeparator; - CryptocurrencyAmountLabel.Text = integerAmount.ToString("N0"); + CryptocurrencyAmountLabel.Text = stringAmount[0]; CryptocurrencyDecimalLabel.Text = string.Format("{0}{1}", separator, decimalAmount.PadRight(2, '0')); AmountLabel.Text = string.Format("~{0}", Formatter.FormatAmount((long)(value.CryptocurrencyAmount * value.UsdRate), "USD")); diff --git a/Telegram/Controls/Cells/Revenue/ChatRevenueTransactionCell.xaml.cs b/Telegram/Controls/Cells/Revenue/ChatRevenueTransactionCell.xaml.cs index 8b5c75a3a2..1f1ab4a38b 100644 --- a/Telegram/Controls/Cells/Revenue/ChatRevenueTransactionCell.xaml.cs +++ b/Telegram/Controls/Cells/Revenue/ChatRevenueTransactionCell.xaml.cs @@ -63,11 +63,10 @@ public void UpdateInfo(ChatRevenueTransaction info) var doubleAmount = Formatter.Amount(Math.Abs(info.CryptocurrencyAmount), info.Cryptocurrency); var stringAmount = doubleAmount.ToString(CultureInfo.InvariantCulture).Split('.'); - var integerAmount = long.Parse(stringAmount[0]); var decimalAmount = stringAmount.Length > 1 ? stringAmount[1] : "0"; Symbol.Text = info.CryptocurrencyAmount < 0 ? "-" : "+"; - Amount.Text = integerAmount.ToString("N0"); + Amount.Text = stringAmount[0]; Decimal.Text = string.Format(".{0}", decimalAmount.PadRight(2, '0')); Value.Foreground = BootStrapper.Current.Resources[info.CryptocurrencyAmount < 0 ? "SystemFillColorCriticalBrush" : "SystemFillColorSuccessBrush"] as Brush; diff --git a/Telegram/Views/Chats/ChatRevenuePage.xaml.cs b/Telegram/Views/Chats/ChatRevenuePage.xaml.cs index d8c0abb004..aae4aba90a 100644 --- a/Telegram/Views/Chats/ChatRevenuePage.xaml.cs +++ b/Telegram/Views/Chats/ChatRevenuePage.xaml.cs @@ -100,10 +100,9 @@ public void UpdateAmount(CryptoAmount value) var doubleAmount = Formatter.Amount(value.CryptocurrencyAmount, value.Cryptocurrency); var stringAmount = doubleAmount.ToString(CultureInfo.InvariantCulture).Split('.'); - var integerAmount = long.Parse(stringAmount[0]); var decimalAmount = stringAmount.Length > 1 ? stringAmount[1] : "0"; - CryptocurrencyAmountLabel.Text = integerAmount.ToString("N0"); + CryptocurrencyAmountLabel.Text = stringAmount[0]; CryptocurrencyDecimalLabel.Text = string.Format(".{0}", decimalAmount.PadRight(2, '0')); AmountLabel.Text = string.Format("~{0}", Formatter.FormatAmount((long)(value.CryptocurrencyAmount * value.UsdRate), "USD")); diff --git a/Telegram/Views/Monetization/Popups/TransactionPopup.xaml.cs b/Telegram/Views/Monetization/Popups/TransactionPopup.xaml.cs index cab659b1af..7163d14c48 100644 --- a/Telegram/Views/Monetization/Popups/TransactionPopup.xaml.cs +++ b/Telegram/Views/Monetization/Popups/TransactionPopup.xaml.cs @@ -72,11 +72,10 @@ public TransactionPopup(IClientService clientService, Chat chat, ChatRevenueTran var doubleAmount = Formatter.Amount(Math.Abs(info.CryptocurrencyAmount), info.Cryptocurrency); var stringAmount = doubleAmount.ToString(CultureInfo.InvariantCulture).Split('.'); - var integerAmount = long.Parse(stringAmount[0]); var decimalAmount = stringAmount.Length > 1 ? stringAmount[1] : "0"; Symbol.Text = info.CryptocurrencyAmount < 0 ? "-" : "+"; - Amount.Text = integerAmount.ToString("N0"); + Amount.Text = stringAmount[0]; Decimal.Text = string.Format(".{0}", decimalAmount.PadRight(2, '0')); Title.Foreground = BootStrapper.Current.Resources[info.CryptocurrencyAmount < 0 ? "SystemFillColorCriticalBrush" : "SystemFillColorSuccessBrush"] as Brush; From 2d8fb4b23416c014da443f5a28338897508981d2 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 14:25:34 +0400 Subject: [PATCH 010/169] Fix null ref --- Telegram/Controls/Messages/MessageSelector.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Controls/Messages/MessageSelector.xaml.cs b/Telegram/Controls/Messages/MessageSelector.xaml.cs index 3444b30fad..547b5c9bae 100644 --- a/Telegram/Controls/Messages/MessageSelector.xaml.cs +++ b/Telegram/Controls/Messages/MessageSelector.xaml.cs @@ -67,7 +67,7 @@ protected override void OnLoaded() { _hasInitialLoadedEventFired = true; - _compositor = _hitTest.Compositor; + _compositor = BootStrapper.Current.Compositor; _container ??= _compositor.CreateContainerVisual(); if (_requiresArrange) From f02316a1fd80ac451fa90ae080cca34e14b92659 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 14:38:54 +0400 Subject: [PATCH 011/169] Update status duration design --- .../Popups/ChooseStatusDurationPopup.xaml | 143 ++++++++++++++++-- .../Popups/ChooseStatusDurationPopup.xaml.cs | 66 +++++++- 2 files changed, 192 insertions(+), 17 deletions(-) diff --git a/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml b/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml index fc86c6b346..553537c133 100644 --- a/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml +++ b/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml @@ -5,17 +5,134 @@ xmlns:controls="using:Telegram.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d"> - - - - - - - - - - + xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives" + mc:Ignorable="d" + Padding="24,24,24,0"> + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + diff --git a/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml.cs b/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml.cs index 8ef1af5deb..82403f37fe 100644 --- a/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml.cs +++ b/Telegram/Views/Popups/ChooseStatusDurationPopup.xaml.cs @@ -9,6 +9,8 @@ using System.Linq; using Telegram.Common; using Telegram.Controls; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace Telegram.Views.Popups { @@ -53,8 +55,8 @@ public ChooseStatusDurationPopup() } _items = items; - FieldSeconds.ItemsSource = items; - FieldSeconds.SelectedIndex = 2; + ItemsHost.ItemsSource = items; + ItemsHost.SelectedIndex = 2; } public int Value @@ -65,8 +67,64 @@ public int Value public SettingsOptionItem SelectedItem { - get => FieldSeconds.SelectedItem as SettingsOptionItem; - set => FieldSeconds.SelectedItem = value; + get => ItemsHost.SelectedItem as SettingsOptionItem; + set => ItemsHost.SelectedItem = value; + } + + private void ItemsHost_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) + { + if (args.InRecycleQueue || args.Item is not SettingsOptionItem value) + { + return; + } + + args.ItemContainer.Content = value.Text; + args.ItemContainer.HorizontalContentAlignment = HorizontalAlignment.Center; + args.Handled = true; + } + + private void ItemsHost_Loaded(object sender, RoutedEventArgs e) + { + var scrollingHost = ItemsHost.GetScrollViewer(); + if (scrollingHost != null) + { + scrollingHost.ViewChanged += ItemsHost_ViewChanged; + } + + ItemsHost_SelectionChanged(sender, null); + } + + private void ItemsHost_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) + { + if (e.IsIntermediate || sender is not ScrollViewer scrollingHost) + { + return; + } + + var index = (int)(scrollingHost.VerticalOffset / 40); + if (index >= 0 && index < ItemsHost.Items.Count) + { + ItemsHost.SelectionChanged -= ItemsHost_SelectionChanged; + ItemsHost.SelectedIndex = index; + ItemsHost.SelectionChanged += ItemsHost_SelectionChanged; + } + } + + private void ItemsHost_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + var scrollingHost = ItemsHost.GetScrollViewer(); + if (scrollingHost != null && ItemsHost.SelectedIndex != -1) + { + if (e == null) + { + scrollingHost.ViewChanged -= ItemsHost_ViewChanged; + ItemsHost.ScrollIntoView(ItemsHost.SelectedItem); + scrollingHost.UpdateLayout(); + scrollingHost.ViewChanged += ItemsHost_ViewChanged; + } + + scrollingHost?.TryChangeView(null, ItemsHost.SelectedIndex * 40, null, e == null); + } } } } From 45a28766a9713b30485bb84e4ba3335fc5307454 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 14:39:30 +0400 Subject: [PATCH 012/169] Bump version to 12.3.1 --- Telegram.Msix/Package.appxmanifest | 2 +- Telegram/Package.appxmanifest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram.Msix/Package.appxmanifest b/Telegram.Msix/Package.appxmanifest index 5caf6f6c13..5482ff9d75 100644 --- a/Telegram.Msix/Package.appxmanifest +++ b/Telegram.Msix/Package.appxmanifest @@ -1,6 +1,6 @@  - + Unigram—Telegram for Windows diff --git a/Telegram/Package.appxmanifest b/Telegram/Package.appxmanifest index 91f95a14b7..35995e799f 100644 --- a/Telegram/Package.appxmanifest +++ b/Telegram/Package.appxmanifest @@ -11,7 +11,7 @@ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="mp uap uap3 uap4 uap5 uap6 uap11 rescap desktop desktop4"> - + Unigram Experimental From 9fbcb60908bf9ae55e0f1a02e2cd563e0cf583de Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 20:17:13 +0400 Subject: [PATCH 013/169] Move GC monitor to C++ --- Telegram.Native/GarbageCollectionMonitor.cpp | 352 ++++++++++++++++++ Telegram.Native/GarbageCollectionMonitor.h | 152 ++++++++ Telegram.Native/GarbageCollectionMonitor.idl | 14 + Telegram.Native/NativeUtils.cpp | 131 +------ Telegram.Native/NativeUtils.h | 59 +-- Telegram.Native/NativeUtils.idl | 6 +- Telegram.Native/Telegram.Native.vcxproj | 11 + .../Telegram.Native.vcxproj.filters | 1 + Telegram.Native/pch.h | 13 +- Telegram/App.xaml.cs | 2 + .../InactivityGarbageCollectionMonitor.cs | 248 ------------ Telegram/Logger.cs | 11 + Telegram/Navigation/WindowContext.cs | 6 +- Telegram/Telegram.csproj | 1 - Telegram/Views/MainPage.xaml.cs | 5 +- 15 files changed, 573 insertions(+), 439 deletions(-) create mode 100644 Telegram.Native/GarbageCollectionMonitor.cpp create mode 100644 Telegram.Native/GarbageCollectionMonitor.h create mode 100644 Telegram.Native/GarbageCollectionMonitor.idl delete mode 100644 Telegram/Common/InactivityGarbageCollectionMonitor.cs diff --git a/Telegram.Native/GarbageCollectionMonitor.cpp b/Telegram.Native/GarbageCollectionMonitor.cpp new file mode 100644 index 0000000000..d77367e4d4 --- /dev/null +++ b/Telegram.Native/GarbageCollectionMonitor.cpp @@ -0,0 +1,352 @@ +#include "pch.h" +#include "GarbageCollectionMonitor.h" +#if __has_include("GarbageCollectionMonitor.g.cpp") +#include "GarbageCollectionMonitor.g.cpp" +#endif + +#include + +namespace winrt::Telegram::Native::implementation +{ + std::mutex GarbageCollectionMonitor::s_syncLock; + std::unordered_map GarbageCollectionMonitor::s_windowStates; + std::thread GarbageCollectionMonitor::s_monitorThread; + std::atomic GarbageCollectionMonitor::s_xamlCollectionRequested{ false }; + std::atomic GarbageCollectionMonitor::s_lastCollectionTicks{ 0 }; + std::atomic GarbageCollectionMonitor::s_requested{ 0 }; + std::atomic GarbageCollectionMonitor::s_count{ 0 }; + CollectCallback GarbageCollectionMonitor::s_collectCallback; + DispatcherQueue GarbageCollectionMonitor::s_dispatcher{ nullptr }; + + GarbageCollectionMonitor::TimeSpan GarbageCollectionMonitor::InactivityTimeout{ 2000 }; + GarbageCollectionMonitor::TimeSpan GarbageCollectionMonitor::DebounceDelay{ 500 }; + GarbageCollectionMonitor::TimeSpan GarbageCollectionMonitor::CheckIntervalActive{ 250 }; + GarbageCollectionMonitor::TimeSpan GarbageCollectionMonitor::CheckIntervalInactive{ 1000 }; + + void GarbageCollectionMonitor::Initialize(CollectCallback collectCallback, bool disableGcCollect, bool disablePressure) + { + if (s_collectCallback) + { + return; + } + + s_collectCallback = std::move(collectCallback); + s_dispatcher = DispatcherQueue::GetForCurrentThread(); + s_monitorThread = std::thread(MonitorThreadProc); + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100) + { + if (disableGcCollect) + { + s_RhCollect = reinterpret_cast(GetProcAddress(mrt100, "RhCollect")); + } + + if (disablePressure) + { + s_RhGetCurrentObjSize = reinterpret_cast(GetProcAddress(mrt100, "RhGetCurrentObjSize")); + } + + if (s_RhCollect || s_RhGetCurrentObjSize) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (s_RhGetCurrentObjSize) + { + DetourAttach(reinterpret_cast(&s_RhGetCurrentObjSize), GarbageCollectionMonitor::RhGetCurrentObjSize); + } + + if (s_RhCollect) + { + DetourAttach(reinterpret_cast(&s_RhCollect), GarbageCollectionMonitor::RhCollect); + } + + DetourTransactionCommit(); + + if (s_RhCollect) + { + s_suspending = Application::Current().Suspending(winrt::auto_revoke, &GarbageCollectionMonitor::OnSuspending); + s_resuming = Application::Current().Resuming(winrt::auto_revoke, &GarbageCollectionMonitor::OnResuming); + } + } + } + } + + void GarbageCollectionMonitor::MonitorThreadProc() + { + while (true) + { + // Determine check interval based on window activity + bool anyWindowActive = IsAnyWindowActive(); + TimeSpan checkInterval = anyWindowActive ? CheckIntervalActive : CheckIntervalInactive; + + std::this_thread::sleep_for(checkInterval); + + TryTriggerCollection(); + } + } + + void GarbageCollectionMonitor::StartMonitoring(CoreWindow const& window) + { + void* windowKey = winrt::get_abi(window); + WindowState* state = nullptr; + bool isNewWindow = false; + + { + std::lock_guard lock(s_syncLock); + auto it = s_windowStates.find(windowKey); + if (it != s_windowStates.end()) + { + // Already monitoring this window + return; + } + + auto [insertIt, inserted] = s_windowStates.emplace(windowKey, WindowState(window)); + state = &insertIt->second; + isNewWindow = inserted; + } + + if (isNewWindow && state) + { + state->ActivatedToken = window.Activated([state](CoreWindow const&, WindowActivatedEventArgs const& args) + { + state->IsWindowActive.store(args.WindowActivationState() != CoreWindowActivationState::Deactivated, + std::memory_order_relaxed); + }); + + state->ClosedToken = window.Closed([window](CoreWindow const&, CoreWindowEventArgs const&) + { + StopMonitoring(window); + }); + + state->IsWindowActive.store(true, std::memory_order_relaxed); + } + } + + void GarbageCollectionMonitor::StopMonitoring(CoreWindow const& window) + { + void* windowKey = winrt::get_abi(window); + WindowState state; + bool found = false; + + { + std::lock_guard lock(s_syncLock); + auto it = s_windowStates.find(windowKey); + if (it == s_windowStates.end()) + { + return; + } + + state = std::move(it->second); + s_windowStates.erase(it); + found = true; + } + + if (found && state.Window) + { + if (state.ActivatedToken) + { + state.Window.Activated(state.ActivatedToken); + } + if (state.ClosedToken) + { + state.Window.Closed(state.ClosedToken); + } + } + } + + void GarbageCollectionMonitor::DisconnectUnusedReferenceSources() + { + s_requested.fetch_add(1, std::memory_order_relaxed); + + auto usageLevel = MemoryManager::AppMemoryUsageLevel(); + if (usageLevel == AppMemoryUsageLevel::High || usageLevel == AppMemoryUsageLevel::OverLimit) + { + int64_t currentTicks = static_cast(GetTickCount64()); + s_lastCollectionTicks.store(currentTicks, std::memory_order_relaxed); + + int32_t count = s_count.fetch_add(1, std::memory_order_relaxed) + 1; + LOGGER_INFO(L"{}/{}", count, s_requested.load(std::memory_order_relaxed)); + + if (s_dispatcher) + { + s_dispatcher.TryEnqueue(Collect); + } + } + else + { + s_xamlCollectionRequested.store(true, std::memory_order_relaxed); + } + } + + bool GarbageCollectionMonitor::IsAnyWindowActive() + { + std::lock_guard lock(s_syncLock); + for (auto const& [key, state] : s_windowStates) + { + if (state.IsWindowActive.load(std::memory_order_relaxed)) + { + return true; + } + } + return false; + } + + void GarbageCollectionMonitor::TryTriggerCollection() + { + if (!s_xamlCollectionRequested.load(std::memory_order_relaxed)) + { + return; + } + + int64_t currentTicks = static_cast(GetTickCount64()); + int64_t lastCollectionTicks = s_lastCollectionTicks.load(std::memory_order_relaxed); + int64_t timeSinceLastCollection = currentTicks - lastCollectionTicks; + + if (timeSinceLastCollection < static_cast(DebounceDelay.count())) + { + return; + } + + bool anyWindowActive = IsAnyWindowActive(); + if (anyWindowActive) + { + uint32_t lastInputTime = NativeUtils::GetLastInputTime(); + uint32_t timeSinceInput = currentTicks >= lastInputTime + ? static_cast(currentTicks - lastInputTime) + : 0; // Handle wraparound conservatively + + if (timeSinceInput < static_cast(InactivityTimeout.count())) + { + return; // User is still active + } + } + else + { + if (timeSinceLastCollection < static_cast(InactivityTimeout.count())) + { + return; + } + } + + s_lastCollectionTicks.store(currentTicks, std::memory_order_relaxed); + s_xamlCollectionRequested.store(false, std::memory_order_relaxed); + + int32_t count = s_count.fetch_add(1, std::memory_order_relaxed) + 1; + LOGGER_INFO(L"{}/{}", count, s_requested.load(std::memory_order_relaxed)); + + if (s_dispatcher) + { + s_dispatcher.TryEnqueue(Collect); + } + } + + void GarbageCollectionMonitor::Collect() + { + if (s_collectCallback) + { + Detour(true); + try + { + s_collectCallback(); + } + catch (...) + { + // Swallow exceptions to prevent crashes + } + Detour(false); + } + } + + hstring GarbageCollectionMonitor::Debug() + { + bool xamlRequested = s_xamlCollectionRequested.load(std::memory_order_relaxed); + int32_t count = s_count.load(std::memory_order_relaxed); + int32_t requested = s_requested.load(std::memory_order_relaxed); + + return hstring(std::format(L" {}/{}{}", count, requested, xamlRequested ? L"*" : L"")); + } + + PFN_RhGetCurrentObjSize GarbageCollectionMonitor::s_RhGetCurrentObjSize; + PFN_RhCollect GarbageCollectionMonitor::s_RhCollect; + + Application::Suspending_revoker GarbageCollectionMonitor::s_suspending = {}; + Application::Resuming_revoker GarbageCollectionMonitor::s_resuming = {}; + + std::mutex GarbageCollectionMonitor::s_collectLock; + bool GarbageCollectionMonitor::s_collect = false; + bool GarbageCollectionMonitor::s_suspended = false; + + void GarbageCollectionMonitor::Detour(bool value) + { + std::lock_guard const guard(s_collectLock); + + if (value == s_collect || s_suspended || !s_RhCollect) + { + return; + } + + s_collect = value; + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100 && s_RhCollect) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (value) + { + DetourDetach(reinterpret_cast(&s_RhCollect), GarbageCollectionMonitor::RhCollect); + } + else + { + DetourAttach(reinterpret_cast(&s_RhCollect), GarbageCollectionMonitor::RhCollect); + } + + DetourTransactionCommit(); + } + } + + void GarbageCollectionMonitor::OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e) + { + std::lock_guard const guard(s_collectLock); + + if (s_suspended || !s_RhCollect) + { + return; + } + + s_suspended = true; + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100 && s_RhCollect) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach(reinterpret_cast(&s_RhCollect), GarbageCollectionMonitor::RhCollect); + DetourTransactionCommit(); + } + } + + void GarbageCollectionMonitor::OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e) + { + std::lock_guard const guard(s_collectLock); + + if (!s_suspended || !s_RhCollect) + { + return; + } + + s_suspended = false; + + auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); + if (mrt100 && s_RhCollect) + { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(reinterpret_cast(&s_RhCollect), GarbageCollectionMonitor::RhCollect); + DetourTransactionCommit(); + } + } +} diff --git a/Telegram.Native/GarbageCollectionMonitor.h b/Telegram.Native/GarbageCollectionMonitor.h new file mode 100644 index 0000000000..0b4fdc63d4 --- /dev/null +++ b/Telegram.Native/GarbageCollectionMonitor.h @@ -0,0 +1,152 @@ +#pragma once + +#include "GarbageCollectionMonitor.g.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using PFN_RhGetCurrentObjSize = INT64(__fastcall*)(); +using PFN_RhCollect = void(__fastcall*)(int generation, int mode); + +using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::UI::Core; +using namespace winrt::Windows::System; + +template +inline void post_to_threadpool(Func&& func) +{ + auto* heapFunc = new std::decay_t(std::forward(func)); + + PTP_WORK work = CreateThreadpoolWork( + [](PTP_CALLBACK_INSTANCE, PVOID context, PTP_WORK) { + std::unique_ptr> funcPtr( + static_cast*>(context) + ); + (*funcPtr)(); + }, + heapFunc, + nullptr + ); + + SubmitThreadpoolWork(work); + CloseThreadpoolWork(work); +} + +namespace winrt::Telegram::Native::implementation +{ + struct GarbageCollectionMonitor : GarbageCollectionMonitorT + { + using TimeSpan = std::chrono::milliseconds; + static TimeSpan InactivityTimeout; + static TimeSpan DebounceDelay; + static TimeSpan CheckIntervalActive; + static TimeSpan CheckIntervalInactive; + + static void Initialize(CollectCallback collectCallback, bool disableGcCollect, bool disablePressure); + static void StartMonitoring(CoreWindow const& window); + static void StopMonitoring(CoreWindow const& window); + static void DisconnectUnusedReferenceSources(); + static hstring Debug(); + + private: + struct WindowState + { + CoreWindow Window{ nullptr }; + std::atomic IsWindowActive{ false }; + event_token ActivatedToken{}; + event_token ClosedToken{}; + + WindowState() = default; + explicit WindowState(CoreWindow const& window) + : Window(window), IsWindowActive(false) + { + } + + WindowState(WindowState&& other) noexcept + : Window(std::move(other.Window)) + , IsWindowActive(other.IsWindowActive.load(std::memory_order_relaxed)) + , ActivatedToken(other.ActivatedToken) + , ClosedToken(other.ClosedToken) + { + other.Window = nullptr; + other.ActivatedToken = {}; + other.ClosedToken = {}; + } + + WindowState& operator=(WindowState&& other) noexcept + { + if (this != &other) + { + Window = std::move(other.Window); + IsWindowActive.store(other.IsWindowActive.load(std::memory_order_relaxed), std::memory_order_relaxed); + ActivatedToken = other.ActivatedToken; + ClosedToken = other.ClosedToken; + + other.Window = nullptr; + other.ActivatedToken = {}; + other.ClosedToken = {}; + } + return *this; + } + + WindowState(const WindowState&) = delete; + WindowState& operator=(const WindowState&) = delete; + }; + + static void MonitorThreadProc(); + static bool IsAnyWindowActive(); + static void TryTriggerCollection(); + static void Collect(); + static void Detour(bool value); + + static std::mutex s_syncLock; + static std::unordered_map s_windowStates; + static std::thread s_monitorThread; + static std::atomic s_xamlCollectionRequested; + static std::atomic s_lastCollectionTicks; + static std::atomic s_requested; + static std::atomic s_count; + static CollectCallback s_collectCallback; + static DispatcherQueue s_dispatcher; + + static Application::Suspending_revoker s_suspending; + static Application::Resuming_revoker s_resuming; + + static PFN_RhGetCurrentObjSize s_RhGetCurrentObjSize; + static PFN_RhCollect s_RhCollect; + + static std::mutex s_collectLock; + static bool s_collect; + static bool s_suspended; + + static INT64 RhGetCurrentObjSize() + { + return 0x7FFFFFFFFFFFFFFF; + } + + static void RhCollect(int generation, int mode) + { + post_to_threadpool([&]() { DisconnectUnusedReferenceSources(); }); + } + + static void OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e); + static void OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e); + }; +} + +namespace winrt::Telegram::Native::factory_implementation +{ + struct GarbageCollectionMonitor : GarbageCollectionMonitorT + { + }; +} diff --git a/Telegram.Native/GarbageCollectionMonitor.idl b/Telegram.Native/GarbageCollectionMonitor.idl new file mode 100644 index 0000000000..c413d82402 --- /dev/null +++ b/Telegram.Native/GarbageCollectionMonitor.idl @@ -0,0 +1,14 @@ +namespace Telegram.Native +{ + delegate void CollectCallback(); + + [default_interface] + runtimeclass GarbageCollectionMonitor + { + static void Initialize(CollectCallback collectCallback, Boolean disableGcCollect, Boolean disablePressure); + static void StartMonitoring(Windows.UI.Core.CoreWindow window); + static void StopMonitoring(Windows.UI.Core.CoreWindow window); + static void DisconnectUnusedReferenceSources(); + static String Debug(); + } +} diff --git a/Telegram.Native/NativeUtils.cpp b/Telegram.Native/NativeUtils.cpp index 076abba821..ea1c59982f 100644 --- a/Telegram.Native/NativeUtils.cpp +++ b/Telegram.Native/NativeUtils.cpp @@ -29,17 +29,7 @@ using namespace winrt::Windows::Foundation::Collections; namespace winrt::Telegram::Native::implementation { FatalErrorCallback NativeUtils::Callback; - - PFN_RhGetCurrentObjSize NativeUtils::s_RhGetCurrentObjSize; - PFN_RhCollect NativeUtils::s_RhCollect; - - Application::Suspending_revoker NativeUtils::s_suspending = {}; - Application::Resuming_revoker NativeUtils::s_resuming = {}; - - CollectCallback NativeUtils::s_collectCallback; - std::mutex NativeUtils::s_collectLock; - bool NativeUtils::s_collect = false; - bool NativeUtils::s_suspended = false; + LogCallback NativeUtils::s_logCallback; void NativeUtils::SetFatalErrorCallback(FatalErrorCallback callback) { @@ -58,125 +48,16 @@ namespace winrt::Telegram::Native::implementation } } - void NativeUtils::SetCollectCallback(CollectCallback callback, bool disableGcCollect, bool disablePressure) - { - std::lock_guard const guard(s_collectLock); - - if (s_collectCallback) - { - return; - } - - s_collectCallback = callback; - - auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); - if (mrt100) - { - if (disableGcCollect) - { - s_RhCollect = reinterpret_cast(GetProcAddress(mrt100, "RhCollect")); - } - - if (disablePressure) - { - s_RhGetCurrentObjSize = reinterpret_cast(GetProcAddress(mrt100, "RhGetCurrentObjSize")); - } - - if (s_RhCollect || s_RhGetCurrentObjSize) - { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - if (s_RhGetCurrentObjSize) - { - DetourAttach(reinterpret_cast(&s_RhGetCurrentObjSize), NativeUtils::RhGetCurrentObjSize); - } - - if (s_RhCollect) - { - DetourAttach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); - } - - DetourTransactionCommit(); - - if (s_RhCollect) - { - s_suspending = Application::Current().Suspending(winrt::auto_revoke, &NativeUtils::OnSuspending); - s_resuming = Application::Current().Resuming(winrt::auto_revoke, &NativeUtils::OnResuming); - } - } - } - } - - void NativeUtils::Collect(bool value) + void NativeUtils::SetLogCallback(LogCallback callback) { - std::lock_guard const guard(s_collectLock); - - if (value == s_collect || s_suspended || !s_RhCollect) - { - return; - } - - s_collect = value; - - auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); - if (mrt100 && s_RhCollect) - { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - - if (value) - { - DetourDetach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); - } - else - { - DetourAttach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); - } - - DetourTransactionCommit(); - } - } - - void NativeUtils::OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e) - { - std::lock_guard const guard(s_collectLock); - - if (s_suspended || !s_RhCollect) - { - return; - } - - s_suspended = true; - - auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); - if (mrt100 && s_RhCollect) - { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - DetourDetach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); - DetourTransactionCommit(); - } + s_logCallback = callback; } - void NativeUtils::OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e) + void NativeUtils::Log(int32_t level, hstring message, hstring member, hstring filePath, int32_t line) { - std::lock_guard const guard(s_collectLock); - - if (!s_suspended || !s_RhCollect) - { - return; - } - - s_suspended = false; - - auto mrt100 = GetModuleHandle(L"mrt100_app.dll"); - if (mrt100 && s_RhCollect) + if (s_logCallback) { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - DetourAttach(reinterpret_cast(&s_RhCollect), NativeUtils::RhCollect); - DetourTransactionCommit(); + s_logCallback(level, message, member, filePath, line); } } diff --git a/Telegram.Native/NativeUtils.h b/Telegram.Native/NativeUtils.h index 159d81c513..b3c12d1a0f 100644 --- a/Telegram.Native/NativeUtils.h +++ b/Telegram.Native/NativeUtils.h @@ -15,10 +15,7 @@ #include typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char* message); - using PFN_td_set_log_message_callback = WINUSERAPI void(WINAPI*)(int max_verbosity_level, td_log_message_callback_ptr callback); -using PFN_RhGetCurrentObjSize = WINUSERAPI INT64(WINAPI*)(); -using PFN_RhCollect = WINUSERAPI void(WINAPI*)(int generation, int mode); using namespace winrt::Windows::Foundation::Collections; using namespace winrt::Windows::UI::Text; @@ -26,26 +23,6 @@ using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Xaml::Media; using namespace winrt::Windows::UI::Xaml::Core::Direct; -template -inline void post_to_threadpool(Func&& func) -{ - auto* heapFunc = new std::decay_t(std::forward(func)); - - PTP_WORK work = CreateThreadpoolWork( - [](PTP_CALLBACK_INSTANCE, PVOID context, PTP_WORK) { - std::unique_ptr> funcPtr( - static_cast*>(context) - ); - (*funcPtr)(); - }, - heapFunc, - nullptr - ); - - SubmitThreadpoolWork(work); - CloseThreadpoolWork(work); -} - namespace winrt::Telegram::Native::implementation { struct NativeUtils : NativeUtilsT @@ -88,28 +65,18 @@ namespace winrt::Telegram::Native::implementation static int32_t GetScaleForCurrentView(); static void SetFatalErrorCallback(FatalErrorCallback action); - static void SetCollectCallback(CollectCallback action, bool disableGcCollect, bool disablePressure); + static void SetLogCallback(LogCallback action); static void LogMessageCallback(int verbosity_level, const char* message); static winrt::Telegram::Native::FatalError GetStowedException(); static winrt::Telegram::Native::FatalError GetBackTrace(hstring type, hstring message); + static void Log(int32_t level, hstring message, hstring member, hstring filePath, int32_t line); + static hstring GetLogMessage(int64_t format, int64_t args); static void Crash(); - static bool Collect() - { - std::lock_guard const guard(s_collectLock); - return s_collect; - } - - static void Collect(bool value); - static FatalErrorCallback Callback; - static CollectCallback s_collectCallback; - - static PFN_RhGetCurrentObjSize s_RhGetCurrentObjSize; - static PFN_RhCollect s_RhCollect; private: static winrt::Telegram::Native::FatalError GetStowedException2(STOWED_EXCEPTION_INFORMATION_V2* stowed); @@ -120,25 +87,7 @@ namespace winrt::Telegram::Native::implementation static ULONGLONG FileTimeToSeconds(FILETIME& ft); static bool IsFileReadableInternal(hstring path, int64_t* fileSize, int64_t* fileTime); - static Application::Suspending_revoker s_suspending; - static Application::Resuming_revoker s_resuming; - - static std::mutex s_collectLock; - static bool s_collect; - static bool s_suspended; - - static INT64 RhGetCurrentObjSize() - { - return 0x7FFFFFFFFFFFFFFF; - } - - static void RhCollect(int generation, int mode) - { - post_to_threadpool([&]() { s_collectCallback(generation, mode); }); - } - - static void OnSuspending(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::ApplicationModel::SuspendingEventArgs const& e); - static void OnResuming(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::Foundation::IInspectable const& e); + static LogCallback s_logCallback; }; } // namespace winrt::Telegram::Native::implementation diff --git a/Telegram.Native/NativeUtils.idl b/Telegram.Native/NativeUtils.idl index 5b0d7b9f40..ec208e5f2e 100644 --- a/Telegram.Native/NativeUtils.idl +++ b/Telegram.Native/NativeUtils.idl @@ -5,6 +5,8 @@ namespace Telegram.Native delegate void FatalErrorCallback(FatalError error); delegate void CollectCallback(Int32 generation, Int32 mode); + delegate void LogCallback(Int32 level, String message, String member, String filePath, Int32 line); + enum TextDirectionality { Neutral, @@ -72,7 +74,8 @@ namespace Telegram.Native static Int32 GetScaleForCurrentView(); static void SetFatalErrorCallback(FatalErrorCallback action); - static void SetCollectCallback(CollectCallback action, Boolean disableGcCollect, Boolean disablePressure); + static void SetLogCallback(LogCallback callback); + static void Log(Int32 level, String message, String member, String filePath, Int32 line); static FatalError GetStowedException(); static FatalError GetBackTrace(String type, String message); @@ -80,6 +83,5 @@ namespace Telegram.Native static String GetLogMessage(Int64 format, Int64 args); static void Crash(); - static Boolean Collect; } } // namespace Telegram.Native diff --git a/Telegram.Native/Telegram.Native.vcxproj b/Telegram.Native/Telegram.Native.vcxproj index 9b0b755ded..50f48b5569 100644 --- a/Telegram.Native/Telegram.Native.vcxproj +++ b/Telegram.Native/Telegram.Native.vcxproj @@ -355,6 +355,10 @@ FreeformGradientSurface.idl Code + + GarbageCollectionMonitor.idl + Code + @@ -1033,6 +1037,10 @@ FreeformGradientSurface.idl Code + + GarbageCollectionMonitor.idl + Code + @@ -1192,6 +1200,9 @@ Designer + + Designer + diff --git a/Telegram.Native/Telegram.Native.vcxproj.filters b/Telegram.Native/Telegram.Native.vcxproj.filters index 4cb5e41a3f..4a5bbc35c8 100644 --- a/Telegram.Native/Telegram.Native.vcxproj.filters +++ b/Telegram.Native/Telegram.Native.vcxproj.filters @@ -1192,5 +1192,6 @@ Controls + \ No newline at end of file diff --git a/Telegram.Native/pch.h b/Telegram.Native/pch.h index ef936868d1..18eea86fbf 100644 --- a/Telegram.Native/pch.h +++ b/Telegram.Native/pch.h @@ -27,4 +27,15 @@ #define DebugMessage(x) #else #define DebugMessage(x) OutputDebugString(x) -#endif \ No newline at end of file +#endif + +#define LOGGER_ASSERT(...) \ + NativeUtils::Log(0, hstring(std::format(__VA_ARGS__)), winrt::to_hstring(std::string(__FUNCTION__)), winrt::to_hstring(__FILE__), __LINE__) +#define LOGGER_DEBUG(...) \ + NativeUtils::Log(4, hstring(std::format(__VA_ARGS__)), winrt::to_hstring(std::string(__FUNCTION__)), winrt::to_hstring(__FILE__), __LINE__) +#define LOGGER_WARNING(...) \ + NativeUtils::Log(2, hstring(std::format(__VA_ARGS__)), winrt::to_hstring(std::string(__FUNCTION__)), winrt::to_hstring(__FILE__), __LINE__) +#define LOGGER_ERROR(...) \ + NativeUtils::Log(1, hstring(std::format(__VA_ARGS__)), winrt::to_hstring(std::string(__FUNCTION__)), winrt::to_hstring(__FILE__), __LINE__) +#define LOGGER_INFO(...) \ + NativeUtils::Log(3, hstring(std::format(__VA_ARGS__)), winrt::to_hstring(std::string(__FUNCTION__)), winrt::to_hstring(__FILE__), __LINE__) diff --git a/Telegram/App.xaml.cs b/Telegram/App.xaml.cs index 7ef278fdcb..d160576c48 100644 --- a/Telegram/App.xaml.cs +++ b/Telegram/App.xaml.cs @@ -8,6 +8,7 @@ using System; using System.Threading.Tasks; using Telegram.Common; +using Telegram.Native; using Telegram.Navigation; using Telegram.Navigation.Services; using Telegram.Services; @@ -71,6 +72,7 @@ public App() TypeCrosserGenerator.Generate(); SettingsService.Current.Initialize(); + GarbageCollectionMonitor.Initialize(GC.Collect, SettingsService.Current.Diagnostics.DisableXamlGcCollect, SettingsService.Current.Diagnostics.DisableMemoryPressure); WatchDog.Initialize(); LifetimeService.Initialize(); diff --git a/Telegram/Common/InactivityGarbageCollectionMonitor.cs b/Telegram/Common/InactivityGarbageCollectionMonitor.cs deleted file mode 100644 index da67fa85cd..0000000000 --- a/Telegram/Common/InactivityGarbageCollectionMonitor.cs +++ /dev/null @@ -1,248 +0,0 @@ -// -// Copyright (c) Fela Ameghino 2015-2026 -// -// Distributed under the GNU General Public License v3.0. (See accompanying -// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) -// - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading; -using Telegram.Native; -using Telegram.Navigation; -using Telegram.Services; -using Windows.Foundation; -using Windows.System; -using Windows.UI.Core; - -namespace Telegram.Common -{ - public static class InactivityGarbageCollectionMonitor - { - private sealed class WindowState - { - public CoreWindow Window { get; } - public volatile bool IsWindowActive; - - public TypedEventHandler ActivatedHandler; - public TypedEventHandler ClosedHandler; - - public WindowState(CoreWindow window) - { - Window = window ?? throw new ArgumentNullException(nameof(window)); - IsWindowActive = false; - } - } - - private static readonly object _syncLock = new object(); - private static readonly Dictionary _windowStates = new Dictionary(); - private static readonly Thread _monitorThread; - - private static volatile bool _xamlCollectionRequested; - private static long _lastCollectionTicks; - - private static volatile int _requested; - private static volatile int _count; - public static string Debug => $" {_count}/{_requested}{(_xamlCollectionRequested ? "*" : "")}"; - - public static TimeSpan InactivityTimeout { get; set; } = TimeSpan.FromSeconds(2); - public static TimeSpan DebounceDelay { get; set; } = TimeSpan.FromMilliseconds(500); - public static TimeSpan CheckIntervalActive { get; set; } = TimeSpan.FromMilliseconds(250); - public static TimeSpan CheckIntervalInactive { get; set; } = TimeSpan.FromSeconds(1); - - static InactivityGarbageCollectionMonitor() - { - _monitorThread = new Thread(MonitorThreadProc) - { - Name = "InactivityGCMonitor", - IsBackground = true - }; - _monitorThread.Start(); - - NativeUtils.SetCollectCallback(RhCollect, - SettingsService.Current.Diagnostics.DisableXamlGcCollect, - SettingsService.Current.Diagnostics.DisableMemoryPressure); - } - - private static void MonitorThreadProc() - { - while (true) - { - // Determine check interval based on window activity - bool anyWindowActive = IsAnyWindowActive(); - TimeSpan checkInterval = anyWindowActive ? CheckIntervalActive : CheckIntervalInactive; - - Thread.Sleep(checkInterval); - - TryTriggerCollection(); - } - } - - /// - /// Starts monitoring the specified window. - /// Must be called on the window's thread. - /// - /// The window to monitor. - /// Thrown when window is null. - public static void StartMonitoring(CoreWindow window) - { - if (window == null) - throw new ArgumentNullException(nameof(window)); - - WindowState state; - bool isNewWindow; - - lock (_syncLock) - { - if (_windowStates.TryGetValue(window, out state)) - { - // Already monitoring this window - return; - } - - state = new WindowState(window); - _windowStates.Add(window, state); - isNewWindow = true; - } - - if (isNewWindow) - { - state.ActivatedHandler = (sender, args) => - { - state.IsWindowActive = args.WindowActivationState != CoreWindowActivationState.Deactivated; - }; - - state.ClosedHandler = (sender, args) => - { - StopMonitoring(window); - }; - - window.Activated += state.ActivatedHandler; - window.Closed += state.ClosedHandler; - - state.IsWindowActive = true; - } - } - - public static void StopMonitoring(CoreWindow window) - { - if (window == null) - throw new ArgumentNullException(nameof(window)); - - WindowState state; - lock (_syncLock) - { - if (!_windowStates.TryGetValue(window, out state)) - { - return; - } - - _windowStates.Remove(window); - } - - if (state.ActivatedHandler != null) - window.Activated -= state.ActivatedHandler; - - if (state.ClosedHandler != null) - window.Closed -= state.ClosedHandler; - - state.ActivatedHandler = null; - state.ClosedHandler = null; - } - - private static void RhCollect(int generation, int mode) - { - Logger.Info(string.Format("generation: {0}, mode: {1}", generation, mode)); - DisconnectUnusedReferenceSources(); - } - - public static void DisconnectUnusedReferenceSources() - { - _requested++; - - var usageLevel = MemoryManager.AppMemoryUsageLevel; - if (usageLevel is AppMemoryUsageLevel.High or AppMemoryUsageLevel.OverLimit) - { - long currentTicks = (long)Logger.TickCount; - Interlocked.Exchange(ref _lastCollectionTicks, currentTicks); - - _count++; - Logger.Info(); - WindowContext.Main?.Dispatcher.Dispatch(BlockingCollect); - } - else - { - _xamlCollectionRequested = true; - } - - Logger.Info(usageLevel); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsAnyWindowActive() - { - lock (_syncLock) - { - foreach (var state in _windowStates.Values) - { - if (state.IsWindowActive) - return true; - } - return false; - } - } - - private static void TryTriggerCollection() - { - if (!_xamlCollectionRequested) - return; - - long currentTicks = (long)Logger.TickCount; - - long lastCollectionTicks = Interlocked.Read(ref _lastCollectionTicks); - long timeSinceLastCollection = currentTicks - lastCollectionTicks; - - if (timeSinceLastCollection < (long)DebounceDelay.TotalMilliseconds) - return; - - bool anyWindowActive = IsAnyWindowActive(); - if (anyWindowActive) - { - uint lastInputTime = NativeUtils.GetLastInputTime(); - uint timeSinceInput = currentTicks >= lastInputTime - ? (uint)(currentTicks - lastInputTime) - : 0; // Handle wraparound conservatively - - if (timeSinceInput < (uint)InactivityTimeout.TotalMilliseconds) - return; // User is still active - } - else - { - if (timeSinceLastCollection < (long)InactivityTimeout.TotalMilliseconds) - return; - } - - Interlocked.Exchange(ref _lastCollectionTicks, currentTicks); - _xamlCollectionRequested = false; - - _count++; - Logger.Info($"{_count}/{_requested}"); - WindowContext.Main?.Dispatcher.Dispatch(Collect); - } - - private static void Collect() - { - NativeUtils.Collect = true; - GC.Collect(); - NativeUtils.Collect = false; - } - - private static void BlockingCollect() - { - NativeUtils.Collect = true; - GC.Collect(2, GCCollectionMode.Optimized, blocking: true, compacting: false); - NativeUtils.Collect = false; - } - } -} diff --git a/Telegram/Logger.cs b/Telegram/Logger.cs index 370e223e66..5eef95c235 100644 --- a/Telegram/Logger.cs +++ b/Telegram/Logger.cs @@ -11,6 +11,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; +using Telegram.Native; using Telegram.Services; using Telegram.Td; using Telegram.Td.Api; @@ -81,6 +82,16 @@ public static void Info(object message = null, [CallerMemberName] string member [DllImport("kernel32.dll")] private unsafe static extern void GetSystemTimeAsFileTime(long* pSystemTimeAsFileTime); + static Logger() + { + NativeUtils.SetLogCallback(LogCallback); + } + + private static void LogCallback(int level, string message, string member, string filePath, int line) + { + Log((LogLevel)level, message, member, filePath, line); + } + private static unsafe void Log(LogLevel level, object message, string member, string filePath, int line) { // We use UtcNow instead of Now because Now is expensive. diff --git a/Telegram/Navigation/WindowContext.cs b/Telegram/Navigation/WindowContext.cs index 004297c61c..7f001bc88b 100644 --- a/Telegram/Navigation/WindowContext.cs +++ b/Telegram/Navigation/WindowContext.cs @@ -109,11 +109,7 @@ public string PersistedId public WindowContext(Window window) { _window = window; - - if (SettingsService.Current.Diagnostics.DisableXamlGcCollect) - { - InactivityGarbageCollectionMonitor.StartMonitoring(window.CoreWindow); - } + GarbageCollectionMonitor.StartMonitoring(window.CoreWindow); //Current = this; Dispatcher = new DispatcherContext(window.CoreWindow.DispatcherQueue); diff --git a/Telegram/Telegram.csproj b/Telegram/Telegram.csproj index cdd4e1223d..4e5739b151 100644 --- a/Telegram/Telegram.csproj +++ b/Telegram/Telegram.csproj @@ -227,7 +227,6 @@ - diff --git a/Telegram/Views/MainPage.xaml.cs b/Telegram/Views/MainPage.xaml.cs index abdd3f7a1b..3d36021a44 100644 --- a/Telegram/Views/MainPage.xaml.cs +++ b/Telegram/Views/MainPage.xaml.cs @@ -20,6 +20,7 @@ using Telegram.Controls.Media; using Telegram.Controls.Messages; using Telegram.Controls.Views; +using Telegram.Native; using Telegram.Navigation; using Telegram.Navigation.Services; using Telegram.Services; @@ -126,7 +127,7 @@ private void OnGettingFocus(object sender, GettingFocusEventArgs args) private string PollGC() { - var occurred = InactivityGarbageCollectionMonitor.Debug; + var occurred = GarbageCollectionMonitor.Debug(); var first = true; for (int i = 0; i <= 2; i++) @@ -1212,7 +1213,7 @@ public void ProcessKeyboardAccelerators(KeyRoutedEventArgs args) //GC.Collect(); //NativeUtils.Collect = false; - InactivityGarbageCollectionMonitor.DisconnectUnusedReferenceSources(); + GarbageCollectionMonitor.DisconnectUnusedReferenceSources(); return; } From 5693200e0732ac9376b8a57ba050507497b23552 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 6 Jan 2026 20:17:36 +0400 Subject: [PATCH 014/169] Remove unused visual states --- Telegram/Themes/Generic.xaml | 24 ------------------------ Telegram/Views/ChatView.xaml | 12 ------------ 2 files changed, 36 deletions(-) diff --git a/Telegram/Themes/Generic.xaml b/Telegram/Themes/Generic.xaml index fe22a1df5a..145d4b37c8 100644 --- a/Telegram/Themes/Generic.xaml +++ b/Telegram/Themes/Generic.xaml @@ -1838,18 +1838,6 @@ - - - - - - - - - - @@ -5591,18 +5579,6 @@ - - - - - - - - - - - - - - - - - - - - From c7223b5a4db0e3ffd3131556e34d5ac9487f925d Mon Sep 17 00:00:00 2001 From: Fela Date: Wed, 7 Jan 2026 16:00:51 +0400 Subject: [PATCH 015/169] Fix instant view crash on Windows 10 Resolves #3252 --- Telegram/Views/Host/TabbedPage.xaml.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Telegram/Views/Host/TabbedPage.xaml.cs b/Telegram/Views/Host/TabbedPage.xaml.cs index 36b0c29088..ee080743df 100644 --- a/Telegram/Views/Host/TabbedPage.xaml.cs +++ b/Telegram/Views/Host/TabbedPage.xaml.cs @@ -39,9 +39,7 @@ public sealed partial class TabbedPage : UserControl, IPopupHost public TabbedPage(TabViewItem newTab, bool forWebApps) { InitializeComponent(); - Window.Current.SetTitleBar(Footer); - BackdropMaterial.SetApplyToRootOrPageBackground(this, true); var coreTitleBar = CoreApplication.GetCurrentView().TitleBar; coreTitleBar.ExtendViewIntoTitleBar = true; From 8baa8267cdfa7984e4c075073b810304ea686e14 Mon Sep 17 00:00:00 2001 From: Fela Date: Wed, 7 Jan 2026 16:07:21 +0400 Subject: [PATCH 016/169] Don't apply mica at all on Windows 10 --- Telegram/Common/Interop.cs | 12 ++++++++++++ Telegram/Navigation/WindowContext.cs | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Telegram/Common/Interop.cs b/Telegram/Common/Interop.cs index 68c511c812..69c40514e0 100644 --- a/Telegram/Common/Interop.cs +++ b/Telegram/Common/Interop.cs @@ -131,4 +131,16 @@ public partial interface IBufferByteAccess { unsafe void Buffer(out byte* value); } + +#if NET9_0_OR_GREATER + [GeneratedComInterface] +#else + [ComImport] +#endif + [Guid("0D8FB190-F122-5B8D-9FDD-543B0D8EB7F3")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + internal interface ICompositorWithBlurredWallpaperBackdropBrush + { + CompositionBackdropBrush TryCreateBlurredWallpaperBackdropBrush(); + } } diff --git a/Telegram/Navigation/WindowContext.cs b/Telegram/Navigation/WindowContext.cs index 7f001bc88b..b89b584d4a 100644 --- a/Telegram/Navigation/WindowContext.cs +++ b/Telegram/Navigation/WindowContext.cs @@ -319,7 +319,10 @@ private void SetContent(UIElement content) _window.Content = _content; - BackdropMaterial.SetApplyToRootOrPageBackground(_content, true); + if ((object)_window.Compositor is ICompositorWithBlurredWallpaperBackdropBrush) + { + BackdropMaterial.SetApplyToRootOrPageBackground(_content, true); + } } private void OnLoading(FrameworkElement sender, object args) From 8a52d7bfc81613464c612963240e45f6eda4dd5c Mon Sep 17 00:00:00 2001 From: Fela Date: Wed, 7 Jan 2026 16:14:19 +0400 Subject: [PATCH 017/169] Revert "Don't apply mica at all on Windows 10" This reverts commit 8baa8267cdfa7984e4c075073b810304ea686e14. --- Telegram/Common/Interop.cs | 12 ------------ Telegram/Navigation/WindowContext.cs | 5 +---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/Telegram/Common/Interop.cs b/Telegram/Common/Interop.cs index 69c40514e0..68c511c812 100644 --- a/Telegram/Common/Interop.cs +++ b/Telegram/Common/Interop.cs @@ -131,16 +131,4 @@ public partial interface IBufferByteAccess { unsafe void Buffer(out byte* value); } - -#if NET9_0_OR_GREATER - [GeneratedComInterface] -#else - [ComImport] -#endif - [Guid("0D8FB190-F122-5B8D-9FDD-543B0D8EB7F3")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - internal interface ICompositorWithBlurredWallpaperBackdropBrush - { - CompositionBackdropBrush TryCreateBlurredWallpaperBackdropBrush(); - } } diff --git a/Telegram/Navigation/WindowContext.cs b/Telegram/Navigation/WindowContext.cs index b89b584d4a..7f001bc88b 100644 --- a/Telegram/Navigation/WindowContext.cs +++ b/Telegram/Navigation/WindowContext.cs @@ -319,10 +319,7 @@ private void SetContent(UIElement content) _window.Content = _content; - if ((object)_window.Compositor is ICompositorWithBlurredWallpaperBackdropBrush) - { - BackdropMaterial.SetApplyToRootOrPageBackground(_content, true); - } + BackdropMaterial.SetApplyToRootOrPageBackground(_content, true); } private void OnLoading(FrameworkElement sender, object args) From 2d5491d8a04428032571f829b249f57691c1d536 Mon Sep 17 00:00:00 2001 From: Fela Date: Wed, 7 Jan 2026 16:18:01 +0400 Subject: [PATCH 018/169] Hide passkey option on Windows 10 --- Telegram/Common/BridgeApplicationContext.cs | 4 +++- Telegram/ViewModels/Authorization/AuthorizationViewModel.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Telegram/Common/BridgeApplicationContext.cs b/Telegram/Common/BridgeApplicationContext.cs index 11137f6e38..61ebc60857 100644 --- a/Telegram/Common/BridgeApplicationContext.cs +++ b/Telegram/Common/BridgeApplicationContext.cs @@ -130,7 +130,7 @@ public static bool IsPasskeySupported() var method = _webAuthNGetApiVersionNumber.Value; if (method != null) { - return method() != 0; + return method() >= 3; } return false; @@ -138,6 +138,7 @@ public static bool IsPasskeySupported() public static async Task AddLoginPasskeyAsync(IClientService clientService) { + Logger.Info(); await ConnectAsync(); var response = await clientService.SendAsync(new GetPasskeyParameters()); @@ -176,6 +177,7 @@ public static async Task AddLoginPasskeyAsync(IClientService clientServi public static async Task CheckAuthenticationPasskeyAsync(IClientService clientService) { + Logger.Info(); await ConnectAsync(); var response = await clientService.SendAsync(new GetAuthenticationPasskeyParameters()); diff --git a/Telegram/ViewModels/Authorization/AuthorizationViewModel.cs b/Telegram/ViewModels/Authorization/AuthorizationViewModel.cs index 9ba993f071..29e7608e52 100644 --- a/Telegram/ViewModels/Authorization/AuthorizationViewModel.cs +++ b/Telegram/ViewModels/Authorization/AuthorizationViewModel.cs @@ -58,6 +58,7 @@ or AuthorizationStateWaitEmailAddress { LocaleService.Current.Changed += OnLocaleChanged; Handle(new UpdateOption(OptionsService.R.SuggestedLanguagePackId, new OptionValueString(ClientService.Options.SuggestedLanguagePackId))); + Handle(new UpdateOption(OptionsService.R.CanUseLoginPasskey, new OptionValueBoolean(ClientService.Options.CanUseLoginPasskey))); IsLoading = false; @@ -331,7 +332,8 @@ public async void LoginWithPasskey() } } - public bool CanUseLoginPasskey => ClientService.Options.CanUseLoginPasskey; + public bool CanUseLoginPasskey => ClientService.Options.CanUseLoginPasskey + && BridgeApplicationContext.IsPasskeySupported(); #region Strings From 8363d24577df2e12288f464225bb2fb17a5a35e3 Mon Sep 17 00:00:00 2001 From: Fela Date: Thu, 8 Jan 2026 16:19:35 +0400 Subject: [PATCH 019/169] Gift variants --- Telegram/Common/Colors.cs | 6 + Telegram/Controls/Cells/GiftVariantCell.xaml | 52 ++++ .../Controls/Cells/GiftVariantCell.xaml.cs | 61 ++++ Telegram/Controls/PatternBackground.xaml.cs | 21 ++ Telegram/Strings/en/Resources.cs | 45 ++- Telegram/Strings/en/Resources.resw | 42 +++ Telegram/Strings/en/Resources.xml | 15 + Telegram/Telegram.csproj | 14 + .../Views/Gifts/Popups/GiftVariantsPopup.xaml | 270 ++++++++++++++++++ .../Gifts/Popups/GiftVariantsPopup.xaml.cs | 245 ++++++++++++++++ .../Stars/Popups/ReceivedGiftPopup.xaml.cs | 27 +- 11 files changed, 787 insertions(+), 11 deletions(-) create mode 100644 Telegram/Controls/Cells/GiftVariantCell.xaml create mode 100644 Telegram/Controls/Cells/GiftVariantCell.xaml.cs create mode 100644 Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml create mode 100644 Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml.cs diff --git a/Telegram/Common/Colors.cs b/Telegram/Common/Colors.cs index 4c2d314aea..2a8e24536f 100644 --- a/Telegram/Common/Colors.cs +++ b/Telegram/Common/Colors.cs @@ -478,5 +478,11 @@ public static Color Darken(this Color color, float satuation = 0.05f, float valu // OLD: .WithBrightness(-0.2f) return color.WithSatuation(satuation, value); } + + public static Color Lighten(this Color color, float satuation = -0.05f, float value = 0.1f) + { + // OLD: .WithBrightness(0.2f) + return color.WithSatuation(satuation, value); + } } } diff --git a/Telegram/Controls/Cells/GiftVariantCell.xaml b/Telegram/Controls/Cells/GiftVariantCell.xaml new file mode 100644 index 0000000000..48f6faf4e3 --- /dev/null +++ b/Telegram/Controls/Cells/GiftVariantCell.xaml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Telegram/Controls/Cells/GiftVariantCell.xaml.cs b/Telegram/Controls/Cells/GiftVariantCell.xaml.cs new file mode 100644 index 0000000000..30cdec34ef --- /dev/null +++ b/Telegram/Controls/Cells/GiftVariantCell.xaml.cs @@ -0,0 +1,61 @@ +// +// Copyright (c) Fela Ameghino 2015-2026 +// +// Distributed under the GNU General Public License v3.0. (See accompanying +// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) +// + +using Telegram.Services; +using Telegram.Streams; +using Telegram.Td.Api; +using Windows.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +namespace Telegram.Controls.Cells +{ + public sealed partial class GiftVariantCell : UserControl + { + public GiftVariantCell() + { + InitializeComponent(); + } + + public void UpdateModel(IClientService clientService, UpgradedGiftModel model) + { + Animated.Source = DelayedFileSource.FromSticker(clientService, model.Sticker); + Pattern.Clear(); + + Title.Text = model.Name; + Title.RequestedTheme = ElementTheme.Default; + + Rarity.Text = (model.RarityPerMille / 10d).ToString("0.##") + "%"; + Rarity.ClearValue(BackgroundProperty); + } + + public void UpdateBackdrop(IClientService clientService, UpgradedGiftModel model, UpgradedGiftBackdrop backdrop, UpgradedGiftSymbol symbol) + { + Animated.Source = DelayedFileSource.FromSticker(clientService, model.Sticker); + Pattern.Update(clientService, backdrop, symbol); + + Title.Text = backdrop.Name; + Title.RequestedTheme = ElementTheme.Dark; + + Rarity.Text = (backdrop.RarityPerMille / 10d).ToString("0.##") + "%"; + Rarity.Background = new SolidColorBrush(Color.FromArgb(0x54, 0, 0, 0)); + } + + public void UpdateSymbol(IClientService clientService, UpgradedGiftBackdrop backdrop, UpgradedGiftSymbol symbol) + { + Animated.Source = DelayedFileSource.FromSticker(clientService, symbol.Sticker); + Pattern.Update(clientService, backdrop, symbol); + + Title.Text = symbol.Name; + Title.RequestedTheme = ElementTheme.Dark; + + Rarity.Text = (symbol.RarityPerMille / 10d).ToString("0.##") + "%"; + Rarity.Background = new SolidColorBrush(Color.FromArgb(0x54, 0, 0, 0)); + } + } +} diff --git a/Telegram/Controls/PatternBackground.xaml.cs b/Telegram/Controls/PatternBackground.xaml.cs index c0b5ce9c25..ab0c241125 100644 --- a/Telegram/Controls/PatternBackground.xaml.cs +++ b/Telegram/Controls/PatternBackground.xaml.cs @@ -74,6 +74,16 @@ public void Update(IClientService clientService, UpgradedGift gift) Update(source, centerColor, edgeColor, symbolColor); } + public void Update(IClientService clientService, UpgradedGiftBackdrop backdrop, UpgradedGiftSymbol symbol) + { + var source = DelayedFileSource.FromSticker(clientService, symbol.Sticker); + var centerColor = backdrop.Colors.CenterColor.ToColor(); + var edgeColor = backdrop.Colors.EdgeColor.ToColor(); + var symbolColor = backdrop.Colors.SymbolColor.ToColor(); + + Update(source, centerColor, edgeColor, symbolColor); + } + public void Update(AnimatedImageSource pattern, Color centerColor, Color edgeColor, Color symbolColor) { _pattern = pattern; @@ -102,6 +112,17 @@ public void Update(AnimatedImageSource pattern, Color centerColor, Color edgeCol Pattern.Source = pattern; } + public void Clear() + { + if (!_templateApplied) + { + return; + } + + HeaderRoot.Background = null; + Pattern.Source = null; + } + #region Footer public object Footer diff --git a/Telegram/Strings/en/Resources.cs b/Telegram/Strings/en/Resources.cs index 6a08d19ffc..aad5dcef98 100644 --- a/Telegram/Strings/en/Resources.cs +++ b/Telegram/Strings/en/Resources.cs @@ -2,7 +2,7 @@ // // This code was generated by TdParseOptions (http://github.com/UnigramDev/UnigramUtils/) // -// Generated: 01/02/2026 18:26:22 +// Generated: 01/08/2026 14:16:31 // // -------------------------------------------------------------------------------------------------- namespace Telegram @@ -172,6 +172,9 @@ public static class R public const string GiftAddedToCollectionTitle = "GiftAddedToCollectionTitle"; public const string GiftMonths = "GiftMonths"; public const string GiftOfferHours = "GiftOfferHours"; + public const string GiftPreviewCountBackdrops = "GiftPreviewCountBackdrops"; + public const string GiftPreviewCountModels = "GiftPreviewCountModels"; + public const string GiftPreviewCountSymbols = "GiftPreviewCountSymbols"; public const string GiftRemovedFromCollectionTitle = "GiftRemovedFromCollectionTitle"; public const string GiftsPinLimit = "GiftsPinLimit"; public const string GroupCallCreateInfo = "GroupCallCreateInfo"; @@ -10563,6 +10566,16 @@ public static class R /// public static string Gift2PrepayUpgradeTitle => Resource.GetString("Gift2PrepayUpgradeTitle"); + /// + /// Localized resource similar to "Random Traits" + /// + public static string Gift2PreviewRandomTraits => Resource.GetString("Gift2PreviewRandomTraits"); + + /// + /// Localized resource similar to "Selected Traits" + /// + public static string Gift2PreviewSelectedTraits => Resource.GetString("Gift2PreviewSelectedTraits"); + /// /// Localized resource similar to "This gift is hidden. Only you can see it." /// @@ -11374,6 +11387,36 @@ public static class R /// public static string GiftPremiumUseGiftBtn => Resource.GetString("GiftPremiumUseGiftBtn"); + /// + /// Localized resource similar to "backdrop" + /// + public static string GiftPreviewBackdrop => Resource.GetString("GiftPreviewBackdrop"); + + /// + /// Localized resource similar to "Backdrops" + /// + public static string GiftPreviewBackdrops => Resource.GetString("GiftPreviewBackdrops"); + + /// + /// Localized resource similar to "model" + /// + public static string GiftPreviewModel => Resource.GetString("GiftPreviewModel"); + + /// + /// Localized resource similar to "Models" + /// + public static string GiftPreviewModels => Resource.GetString("GiftPreviewModels"); + + /// + /// Localized resource similar to "symbol" + /// + public static string GiftPreviewSymbol => Resource.GetString("GiftPreviewSymbol"); + + /// + /// Localized resource similar to "Symbols" + /// + public static string GiftPreviewSymbols => Resource.GetString("GiftPreviewSymbols"); + /// /// Localized resource similar to "This gift has been removed from **{0}** collection." /// diff --git a/Telegram/Strings/en/Resources.resw b/Telegram/Strings/en/Resources.resw index da797fafaa..0b5fd60122 100644 --- a/Telegram/Strings/en/Resources.resw +++ b/Telegram/Strings/en/Resources.resw @@ -7032,6 +7032,12 @@ This action cannot be undone. This will permanently destroy the gift. Make Unique + + Random Traits + + + Selected Traits + This gift is hidden. Only you can see it. @@ -7605,6 +7611,42 @@ You will receive **{3} TON** after fees. Use Gift + + backdrop + + + Backdrops + + + This collectible features **{0}** unique backdrop + + + This collectible features **{0}** unique backdrops + + + This collectible features **{0}** unique models + + + This collectible features **{0}** unique models + + + This collectible features **{0}** unique symbol + + + This collectible features **{0}** unique symbols + + + model + + + Models + + + symbol + + + Symbols + {0} gift removed from **{1}** diff --git a/Telegram/Strings/en/Resources.xml b/Telegram/Strings/en/Resources.xml index 7960b05235..a6c1ffc6a3 100644 --- a/Telegram/Strings/en/Resources.xml +++ b/Telegram/Strings/en/Resources.xml @@ -13214,4 +13214,19 @@ un1 won 💎 {0} un1 lost 💎 {0} + backdrop + Backdrops + This collectible features **{0}** unique backdrop + This collectible features **{0}** unique backdrops + This collectible features **{0}** unique models + This collectible features **{0}** unique models + This collectible features **{0}** unique symbol + This collectible features **{0}** unique symbols + model + Models + symbol + Symbols + Random Traits + Selected Traits + \ No newline at end of file diff --git a/Telegram/Telegram.csproj b/Telegram/Telegram.csproj index 4e5739b151..d25339af21 100644 --- a/Telegram/Telegram.csproj +++ b/Telegram/Telegram.csproj @@ -276,6 +276,9 @@ ChatInviteLinkCell.xaml + + GiftVariantCell.xaml + ReceivedGiftCell.xaml @@ -1262,6 +1265,9 @@ ShareFolderPopup.xaml + + GiftVariantsPopup.xaml + SharePage.xaml @@ -2609,6 +2615,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -3361,6 +3371,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml b/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml new file mode 100644 index 0000000000..bb01d5d616 --- /dev/null +++ b/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml.cs b/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml.cs new file mode 100644 index 0000000000..460e296902 --- /dev/null +++ b/Telegram/Views/Gifts/Popups/GiftVariantsPopup.xaml.cs @@ -0,0 +1,245 @@ +// +// Copyright (c) Fela Ameghino 2015-2026 +// +// Distributed under the GNU General Public License v3.0. (See accompanying +// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) +// + +using System; +using System.Linq; +using Telegram.Collections; +using Telegram.Common; +using Telegram.Controls; +using Telegram.Controls.Cells; +using Telegram.Navigation.Services; +using Telegram.Services; +using Telegram.Streams; +using Telegram.Td.Api; +using Windows.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Media; + +namespace Telegram.Views.Gifts.Popups +{ + public sealed partial class GiftVariantsPopup : ContentPopup + { + private readonly IClientService _clientService; + private readonly INavigationService _navigationService; + + private readonly DispatcherTimer _timer; + private readonly Random _random = new(); + + private readonly GiftUpgradeVariants _variants; + private readonly MvxObservableCollection _itemsSource; + + private UpgradedGiftModel _selectedModel; + private UpgradedGiftBackdrop _selectedBackdrop; + private UpgradedGiftSymbol _selectedSymbol; + + public GiftVariantsPopup(IClientService clientService, INavigationService navigationService, ReceivedGift gift, GiftUpgradeVariants variants) + { + InitializeComponent(); + + _clientService = clientService; + _navigationService = navigationService; + + _variants = variants; + _itemsSource = new MvxObservableCollection(variants.Models.Cast()); + + OnTick(null, null); + + if (gift.Gift is SentGiftUpgraded upgraded) + { + UpgradedTitle.Text = upgraded.Gift.Title; + } + + ScrollingHost.ItemsSource = _itemsSource; + + _timer = new DispatcherTimer + { + Interval = TimeSpan.FromSeconds(3) + }; + + _timer.Tick += OnTick; + _timer.Start(); + + UpgradedSubtitle.Text = Strings.Gift2PreviewRandomTraits; + + TextBlockHelper.SetMarkdown(Info, Locale.Declension(Strings.R.GiftPreviewCountModels, _variants.Models.Count)); + + Navigation.SelectedIndex = 0; + Navigation.SelectionChanged += Navigation_SelectionChanged; + } + + private void OnTick(object sender, object e) + { + _selectedModel = _variants.Models[_random.Next(0, _variants.Models.Count)]; + _selectedBackdrop = _variants.Backdrops[_random.Next(0, _variants.Backdrops.Count)]; + _selectedSymbol = _variants.Symbols[_random.Next(0, _variants.Symbols.Count)]; + + UpdateComposition(); + } + + private void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) + { + if (args.InRecycleQueue) + { + return; + } + else if (args.ItemContainer.ContentTemplateRoot is GiftVariantCell content) + { + Color color; + + if (args.Item is UpgradedGiftModel model) + { + color = Theme.Accent; + content.UpdateModel(_clientService, model); + } + else if (args.Item is UpgradedGiftBackdrop backdrop) + { + color = backdrop.Colors.EdgeColor.ToColor(); + content.UpdateBackdrop(_clientService, _selectedModel, backdrop, _selectedSymbol); + } + else if (args.Item is UpgradedGiftSymbol symbol) + { + color = _selectedBackdrop.Colors.EdgeColor.ToColor(); + content.UpdateSymbol(_clientService, _selectedBackdrop, symbol); + } + + var presenter = VisualTreeHelper.GetChild(args.ItemContainer, 0) as ListViewItemPresenter; + if (presenter != null) + { + var brush = new SolidColorBrush(color); + + presenter.SelectedBorderBrush = brush; + presenter.SelectedPointerOverBorderBrush = brush; + presenter.SelectedPressedBorderBrush = brush; + } + } + + args.Handled = true; + } + + private void Navigation_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + StopRandomization(false); + + if (Navigation.SelectedIndex == 0) + { + //ScrollingHost.ItemsSource = _variants.Models; + _itemsSource.ReplaceWithT(_variants.Models); + ScrollingHost.SelectedItem = _selectedModel; + + TextBlockHelper.SetMarkdown(Info, Locale.Declension(Strings.R.GiftPreviewCountModels, _variants.Models.Count)); + } + else if (Navigation.SelectedIndex == 1) + { + //ScrollingHost.ItemsSource = _variants.Backdrops; + _itemsSource.ReplaceWithT(_variants.Backdrops); + ScrollingHost.SelectedItem = _selectedBackdrop; + + TextBlockHelper.SetMarkdown(Info, Locale.Declension(Strings.R.GiftPreviewCountBackdrops, _variants.Backdrops.Count)); + } + else if (Navigation.SelectedIndex == 2) + { + //ScrollingHost.ItemsSource = _variants.Symbols; + _itemsSource.ReplaceWithT(_variants.Symbols); + ScrollingHost.SelectedItem = _selectedSymbol; + + TextBlockHelper.SetMarkdown(Info, Locale.Declension(Strings.R.GiftPreviewCountSymbols, _variants.Symbols.Count)); + } + } + + private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (ScrollingHost.SelectedItem != null) + { + StopRandomization(false); + } + + if (ScrollingHost.SelectedItem is UpgradedGiftModel model) + { + _selectedModel = model; + UpdateComposition(); + } + else if (ScrollingHost.SelectedItem is UpgradedGiftBackdrop backdrop) + { + _selectedBackdrop = backdrop; + UpdateComposition(); + } + else if (ScrollingHost.SelectedItem is UpgradedGiftSymbol symbol) + { + _selectedSymbol = symbol; + UpdateComposition(); + } + } + + private void StopRandomization(bool updateSelection) + { + _timer.Stop(); + Randomize.IsChecked = false; + UpgradedSubtitle.Text = Strings.Gift2PreviewSelectedTraits; + + if (updateSelection) + { + if (Navigation.SelectedIndex == 0) + { + ScrollingHost.SelectedItem = _selectedModel; + } + else if (Navigation.SelectedIndex == 1) + { + ScrollingHost.SelectedItem = _selectedBackdrop; + } + else if (Navigation.SelectedIndex == 2) + { + ScrollingHost.SelectedItem = _selectedSymbol; + } + } + } + + private void UpdateComposition() + { + if (_selectedModel == null || _selectedBackdrop == null || _selectedSymbol == null) + { + return; + } + + UpgradedHeader.Update(_clientService, _selectedBackdrop, _selectedSymbol); + UpgradedAnimatedPhoto.Source = DelayedFileSource.FromSticker(_clientService, _selectedModel.Sticker); + + ModelName.Text = _selectedModel.Name; + ModelRarity.Text = (_selectedModel.RarityPerMille / 10d).ToString("0.##") + "%"; + + BackdropName.Text = _selectedBackdrop.Name; + BackdropRarity.Text = (_selectedBackdrop.RarityPerMille / 10d).ToString("0.##") + "%"; + + SymbolName.Text = _selectedSymbol.Name; + SymbolRarity.Text = (_selectedSymbol.RarityPerMille / 10d).ToString("0.##") + "%"; + + var badgeColor = _selectedBackdrop.Colors.CenterColor.ToColor(); + var badgeBrush = new SolidColorBrush(badgeColor.Lighten()); + + ModelRarity.Background = badgeBrush; + BackdropRarity.Background = badgeBrush; + SymbolRarity.Background = badgeBrush; + } + + private void Randomize_Click(object sender, RoutedEventArgs e) + { + if (_timer.IsEnabled) + { + StopRandomization(true); + } + else + { + _timer.Start(); + OnTick(null, null); + + UpgradedSubtitle.Text = Strings.Gift2PreviewRandomTraits; + ScrollingHost.SelectedItem = null; + } + } + } +} diff --git a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs index b11819987f..e24df193ee 100644 --- a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs +++ b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs @@ -19,6 +19,7 @@ using Telegram.Streams; using Telegram.Td; using Telegram.Td.Api; +using Telegram.Views.Gifts.Popups; using Telegram.Views.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -672,27 +673,33 @@ private async void Visibility_Click(object sender, TextUrlClickEventArgs e) } } - private void UpgradedModelRarity_Click(object sender, RoutedEventArgs e) + private async void UpgradedModelRarity_Click(object sender, RoutedEventArgs e) { - if (_gift.Gift is SentGiftUpgraded upgraded) - { - ToastPopup.Show(UpgradedModelRarity, string.Format(Strings.Gift2RarityHint, (upgraded.Gift.Model.RarityPerMille / 10d).ToString("0.##") + "%"), TeachingTipPlacementMode.Top); - } + ShowVariants(); } private void UpgradedBackdropRarity_Click(object sender, RoutedEventArgs e) { - if (_gift.Gift is SentGiftUpgraded upgraded) - { - ToastPopup.Show(UpgradedBackdropRarity, string.Format(Strings.Gift2RarityHint, (upgraded.Gift.Backdrop.RarityPerMille / 10d).ToString("0.##") + "%"), TeachingTipPlacementMode.Top); - } + ShowVariants(); } private void UpgradedSymbolRarity_Click(object sender, RoutedEventArgs e) + { + ShowVariants(); + } + + private async void ShowVariants() { if (_gift.Gift is SentGiftUpgraded upgraded) { - ToastPopup.Show(UpgradedSymbolRarity, string.Format(Strings.Gift2RarityHint, (upgraded.Gift.Symbol.RarityPerMille / 10d).ToString("0.##") + "%"), TeachingTipPlacementMode.Top); + var response = await _clientService.SendAsync(new GetGiftUpgradeVariants(upgraded.Gift.RegularGiftId)); + if (response is GiftUpgradeVariants variants) + { + Hide(); + + await _navigationService.ShowPopupAsync(new GiftVariantsPopup(_clientService, _navigationService, _gift, variants)); + await this.ShowQueuedAsync(XamlRoot); + } } } From 95cc78b288f9b18bc46b7efb71031cd2d44189d9 Mon Sep 17 00:00:00 2001 From: Fela Date: Thu, 8 Jan 2026 18:22:44 +0400 Subject: [PATCH 020/169] Explicitly add zh-Hans, zh-Hant and ja to satisfy font renderer requirements Resolves #3242 --- Telegram/Strings/ja/Resources.resw | 67 +++++++++++++++++++++++++ Telegram/Strings/zh-Hans/Resources.resw | 67 +++++++++++++++++++++++++ Telegram/Strings/zh-Hant/Resources.resw | 67 +++++++++++++++++++++++++ Telegram/Telegram.csproj | 9 ++++ 4 files changed, 210 insertions(+) create mode 100644 Telegram/Strings/ja/Resources.resw create mode 100644 Telegram/Strings/zh-Hans/Resources.resw create mode 100644 Telegram/Strings/zh-Hant/Resources.resw diff --git a/Telegram/Strings/ja/Resources.resw b/Telegram/Strings/ja/Resources.resw new file mode 100644 index 0000000000..e77b240c88 --- /dev/null +++ b/Telegram/Strings/ja/Resources.resw @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Unigram + + + Telegram + + \ No newline at end of file diff --git a/Telegram/Strings/zh-Hans/Resources.resw b/Telegram/Strings/zh-Hans/Resources.resw new file mode 100644 index 0000000000..e77b240c88 --- /dev/null +++ b/Telegram/Strings/zh-Hans/Resources.resw @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Unigram + + + Telegram + + \ No newline at end of file diff --git a/Telegram/Strings/zh-Hant/Resources.resw b/Telegram/Strings/zh-Hant/Resources.resw new file mode 100644 index 0000000000..e77b240c88 --- /dev/null +++ b/Telegram/Strings/zh-Hant/Resources.resw @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Unigram + + + Telegram + + \ No newline at end of file diff --git a/Telegram/Telegram.csproj b/Telegram/Telegram.csproj index d25339af21..dcedc79e21 100644 --- a/Telegram/Telegram.csproj +++ b/Telegram/Telegram.csproj @@ -2494,6 +2494,15 @@ + + Designer + + + Designer + + + Designer + From fe2b7569c6c60faa64a8e8dd5acf18f2093f0f15 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 9 Jan 2026 13:54:45 +0400 Subject: [PATCH 021/169] Fix gift offer buttons --- Telegram/Controls/Messages/MessageService.cs | 2 +- .../Service/MessageUpgradedGiftPurchaseOfferContent.xaml.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Telegram/Controls/Messages/MessageService.cs b/Telegram/Controls/Messages/MessageService.cs index dad5cc2dc2..f2fa33e413 100644 --- a/Telegram/Controls/Messages/MessageService.cs +++ b/Telegram/Controls/Messages/MessageService.cs @@ -2508,7 +2508,7 @@ private static FormattedText UpdateUpgradedGiftPurchaseOffer(MessageWithOwner me if (upgradedGift.State is GiftPurchaseOfferStatePending) { var now = DateTime.Now.ToTimestamp(); - if (now > upgradedGift.ExpirationDate) + if (now >= upgradedGift.ExpirationDate) { content += "\n\n" + Strings.GiftOfferStatusExpired; } diff --git a/Telegram/Controls/Messages/Service/MessageUpgradedGiftPurchaseOfferContent.xaml.cs b/Telegram/Controls/Messages/Service/MessageUpgradedGiftPurchaseOfferContent.xaml.cs index 823cea4e5b..3e882e2fe1 100644 --- a/Telegram/Controls/Messages/Service/MessageUpgradedGiftPurchaseOfferContent.xaml.cs +++ b/Telegram/Controls/Messages/Service/MessageUpgradedGiftPurchaseOfferContent.xaml.cs @@ -5,6 +5,8 @@ // file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) // +using System; +using Telegram.Common; using Telegram.Streams; using Telegram.Td.Api; using Telegram.ViewModels; @@ -30,7 +32,8 @@ protected override void UpdateContent(MessageViewModel message) Pattern.Update(message.ClientService, upgradedGiftPurchaseOffer.Gift); Animation.Source = DelayedFileSource.FromSticker(message.ClientService, upgradedGiftPurchaseOffer.Gift.Model.Sticker); - if (upgradedGiftPurchaseOffer.State is GiftPurchaseOfferStatePending && !message.IsOutgoing) + var now = DateTime.Now.ToTimestamp(); + if (now < upgradedGiftPurchaseOffer.ExpirationDate && upgradedGiftPurchaseOffer.State is GiftPurchaseOfferStatePending && !message.IsOutgoing) { Accept.Visibility = Visibility.Visible; Reject.Visibility = Visibility.Visible; From 43b39e07fcb90b248abe501cdbdeef48e5d8bf35 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 9 Jan 2026 15:31:24 +0400 Subject: [PATCH 022/169] Add tips to settings --- Telegram/Assets/Icons/Tips.cs | 3042 +++++++++++++++++++++++++++ Telegram/Assets/Icons/Tips.json | 1 + Telegram/Telegram.csproj | 1 + Telegram/Views/SettingsPage.xaml | 7 + Telegram/Views/SettingsPage.xaml.cs | 8 + 5 files changed, 3059 insertions(+) create mode 100644 Telegram/Assets/Icons/Tips.cs create mode 100644 Telegram/Assets/Icons/Tips.json diff --git a/Telegram/Assets/Icons/Tips.cs b/Telegram/Assets/Icons/Tips.cs new file mode 100644 index 0000000000..d384961989 --- /dev/null +++ b/Telegram/Assets/Icons/Tips.cs @@ -0,0 +1,3042 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// LottieGen version: +// 8.1.240821-rc.1+f962c65f63 +// +// Command: +// LottieGen -DisableTranslationOptimizer -Language CSharp -Namespace Telegram.Assets.Icons -Public -WinUIVersion 2.8 -InputFile Tips.json +// +// Input file: +// Tips.json (12729 bytes created 15:23+04:00 Jan 9 2026) +// +// LottieGen source: +// http://aka.ms/Lottie +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +// ___________________________________________________________ +// | Object stats | UAP v15 count | UAP v7 count | +// |__________________________|_______________|______________| +// | All CompositionObjects | 634 | 686 | +// |--------------------------+---------------+--------------| +// | Expression animators | 1 | 14 | +// | KeyFrame animators | 14 | 14 | +// | Reference parameters | 1 | 14 | +// | Expression operations | 0 | 0 | +// |--------------------------+---------------+--------------| +// | Animated brushes | 2 | 2 | +// | Animated gradient stops | - | - | +// | ExpressionAnimations | 1 | 14 | +// | PathKeyFrameAnimations | - | - | +// |--------------------------+---------------+--------------| +// | ContainerVisuals | 1 | 1 | +// | ShapeVisuals | 1 | 1 | +// |--------------------------+---------------+--------------| +// | ContainerShapes | 24 | 24 | +// | CompositionSpriteShapes | 5 | 5 | +// |--------------------------+---------------+--------------| +// | Brushes | 5 | 5 | +// | Gradient stops | 4 | 4 | +// | CompositionVisualSurface | - | - | +// ----------------------------------------------------------- +using Microsoft.Graphics.Canvas.Geometry; +using System; +using System.Collections.Generic; +using System.Numerics; +using Windows.Graphics; +using Windows.UI; +using Windows.UI.Composition; + +namespace Telegram.Assets.Icons +{ + // Name: u_username + // Frame rate: 60 fps + // Frame count: 30 + // Duration: 500.0 mS + public sealed partial class Tips + : Microsoft.UI.Xaml.Controls.IAnimatedVisualSource + , Microsoft.UI.Xaml.Controls.IAnimatedVisualSource2 + { + // Animation duration: 0.500 seconds. + internal const long c_durationTicks = 5000000; + + public Microsoft.UI.Xaml.Controls.IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor) + { + object ignored = null; + return TryCreateAnimatedVisual(compositor, out ignored); + } + + public Microsoft.UI.Xaml.Controls.IAnimatedVisual TryCreateAnimatedVisual(Compositor compositor, out object diagnostics) + { + diagnostics = null; + + if (Tips_AnimatedVisual_UAPv15.IsRuntimeCompatible()) + { + var res = + new Tips_AnimatedVisual_UAPv15( + compositor + ); + res.CreateAnimations(); + return res; + } + + if (Tips_AnimatedVisual_UAPv7.IsRuntimeCompatible()) + { + var res = + new Tips_AnimatedVisual_UAPv7( + compositor + ); + res.CreateAnimations(); + return res; + } + + return null; + } + + /// + /// Gets the number of frames in the animation. + /// + public double FrameCount => 30d; + + /// + /// Gets the frame rate of the animation. + /// + public double Framerate => 60d; + + /// + /// Gets the duration of the animation. + /// + public TimeSpan Duration => TimeSpan.FromTicks(5000000); + + /// + /// Converts a zero-based frame number to the corresponding progress value denoting the + /// start of the frame. + /// + public double FrameToProgress(double frameNumber) + { + return frameNumber / 30d; + } + + /// + /// Returns a map from marker names to corresponding progress values. + /// + public IReadOnlyDictionary Markers => + new Dictionary + { + { "NormalToPointerOver_Start", 0.0 }, + { "NormalToPointerOver_End", 1 }, + }; + + /// + /// Sets the color property with the given name, or does nothing if no such property + /// exists. + /// + public void SetColorProperty(string propertyName, Color value) + { + } + + /// + /// Sets the scalar property with the given name, or does nothing if no such property + /// exists. + /// + public void SetScalarProperty(string propertyName, double value) + { + } + + sealed partial class Tips_AnimatedVisual_UAPv15 + : Microsoft.UI.Xaml.Controls.IAnimatedVisual + , Microsoft.UI.Xaml.Controls.IAnimatedVisual2 + { + const long c_durationTicks = 5000000; + readonly Compositor _c; + readonly ExpressionAnimation _reusableExpressionAnimation; + AnimationController _animationController_0; + CompositionColorBrush _animatedColorBrush_TransparentWhite_to_White; + CompositionColorBrush _animatedColorBrush_White_to_TransparentWhite; + CompositionContainerShape _containerShape_00; + CompositionContainerShape _containerShape_05; + CompositionContainerShape _containerShape_10; + CompositionContainerShape _containerShape_14; + CompositionContainerShape _containerShape_19; + CompositionContainerShape _containerShape_20; + ContainerVisual _root; + StepEasingFunction _holdThenStepEasingFunction; + + void BindProperty( + CompositionObject target, + string animatedPropertyName, + string expression, + string referenceParameterName, + CompositionObject referencedObject) + { + _reusableExpressionAnimation.ClearAllParameters(); + _reusableExpressionAnimation.Expression = expression; + _reusableExpressionAnimation.SetReferenceParameter(referenceParameterName, referencedObject); + target.StartAnimation(animatedPropertyName, _reusableExpressionAnimation); + } + + ColorKeyFrameAnimation CreateColorKeyFrameAnimation(float initialProgress, Color initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateColorKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InterpolationColorSpace = CompositionColorSpace.Rgb; + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(float initialProgress, float initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateScalarKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + AnimationController AnimationController_0() + { + if (_animationController_0 != null) { return _animationController_0; } + var result = _animationController_0 = _c.CreateAnimationController(); + result.Pause(); + BindProperty(_animationController_0, "Progress", "_.Progress", "_", _root); + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Shape + // - - - - ShapeGroup: Shape + // - - Path 1 + CanvasGeometry Geometry_0() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(2.68899989F, 0.104999997F)); + builder.AddLine(new Vector2(3.07200003F, -1.5F)); + builder.AddLine(new Vector2(-3.07200003F, -1.5F)); + builder.AddLine(new Vector2(-2.68899989F, 0.104999997F)); + builder.AddLine(new Vector2(-2.65199995F, 0.238999993F)); + builder.AddCubicBezier(new Vector2(-2.41100001F, 0.984000027F), new Vector2(-1.69400001F, 1.5F), new Vector2(-0.875F, 1.5F)); + builder.AddLine(new Vector2(0.874000013F, 1.5F)); + builder.AddLine(new Vector2(1.01800001F, 1.495F)); + builder.AddCubicBezier(new Vector2(1.82299995F, 1.43499994F), new Vector2(2.50500011F, 0.875999987F), new Vector2(2.68899989F, 0.104999997F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Shape + // - - - - ShapeGroup: Shape + // - - Path 1 + CanvasGeometry Geometry_1() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(6F, -0.200000003F)); + builder.AddCubicBezier(new Vector2(6F, -3.40300012F), new Vector2(3.31399989F, -6F), new Vector2(0F, -6F)); + builder.AddCubicBezier(new Vector2(-3.24699998F, -6F), new Vector2(-5.89300013F, -3.50600004F), new Vector2(-5.99700022F, -0.391000003F)); + builder.AddLine(new Vector2(-6F, -0.200000003F)); + builder.AddLine(new Vector2(-5.99499989F, 0.0390000008F)); + builder.AddCubicBezier(new Vector2(-5.92700005F, 1.62399995F), new Vector2(-5.18499994F, 3.08200002F), new Vector2(-3.79500008F, 4.39400005F)); + builder.AddCubicBezier(new Vector2(-3.71000004F, 4.47399998F), new Vector2(-3.65100002F, 4.57700014F), new Vector2(-3.62400007F, 4.68900013F)); + builder.AddLine(new Vector2(-3.31100011F, 6F)); + builder.AddLine(new Vector2(3.31100011F, 6F)); + builder.AddLine(new Vector2(3.625F, 4.6880002F)); + builder.AddLine(new Vector2(3.65100002F, 4.60699987F)); + builder.AddCubicBezier(new Vector2(3.68300009F, 4.52699995F), new Vector2(3.73200011F, 4.454F), new Vector2(3.796F, 4.39400005F)); + builder.AddCubicBezier(new Vector2(5.25500011F, 3.01600003F), new Vector2(6F, 1.477F), new Vector2(6F, -0.200000003F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - Layer aggregator + // - - - - ShapeGroup: Subtract + // - - Path 1 + CanvasGeometry Geometry_2() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.5F, -2.50099993F)); + builder.AddCubicBezier(new Vector2(0.5F, -2.77699995F), new Vector2(0.275999993F, -3.00099993F), new Vector2(0F, -3.00099993F)); + builder.AddCubicBezier(new Vector2(-0.275999993F, -3.00099993F), new Vector2(-0.5F, -2.77699995F), new Vector2(-0.5F, -2.50099993F)); + builder.AddLine(new Vector2(-0.5F, 2.00099993F)); + builder.AddLine(new Vector2(-3.31100011F, 2.00099993F)); + builder.AddLine(new Vector2(-3.07200003F, 3.00099993F)); + builder.AddLine(new Vector2(3.07299995F, 3.00099993F)); + builder.AddLine(new Vector2(3.31100011F, 2.00099993F)); + builder.AddLine(new Vector2(0.5F, 2.00099993F)); + builder.AddLine(new Vector2(0.5F, -2.50099993F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Subtract + // - - - - ShapeGroup: Subtract + CanvasGeometry Geometry_3() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.501999974F, -1.00100005F)); + builder.AddCubicBezier(new Vector2(0.501999974F, -1.27699995F), new Vector2(0.277999997F, -1.50100005F), new Vector2(0.00200000009F, -1.50100005F)); + builder.AddCubicBezier(new Vector2(-0.273999989F, -1.50100005F), new Vector2(-0.497999996F, -1.27699995F), new Vector2(-0.497999996F, -1.00100005F)); + builder.AddLine(new Vector2(-0.497999996F, 0.00100000005F)); + builder.AddCubicBezier(new Vector2(-0.497999996F, 0.27700001F), new Vector2(-0.273999989F, 0.500999987F), new Vector2(0.00200000009F, 0.500999987F)); + builder.AddCubicBezier(new Vector2(0.277999997F, 0.500999987F), new Vector2(0.501999974F, 0.27700001F), new Vector2(0.501999974F, 0.00100000005F)); + builder.AddLine(new Vector2(0.501999974F, -1.00100005F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(2.65799999F, -0.254999995F), new Vector2(2.34100008F, -0.254999995F), new Vector2(2.14599991F, -0.0599999987F)); + builder.AddLine(new Vector2(1.43799996F, 0.648000002F)); + builder.AddCubicBezier(new Vector2(1.24300003F, 0.842999995F), new Vector2(1.24300003F, 1.15999997F), new Vector2(1.43799996F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(1.63300002F, 1.54999995F), new Vector2(1.95000005F, 1.54999995F), new Vector2(2.14499998F, 1.35500002F)); + builder.AddLine(new Vector2(2.85299993F, 0.647000015F)); + builder.AddCubicBezier(new Vector2(3.0480001F, 0.451999992F), new Vector2(3.0480001F, 0.135000005F), new Vector2(2.85299993F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(-2.14499998F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-2.33999991F, -0.254999995F), new Vector2(-2.65799999F, -0.254999995F), new Vector2(-2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-3.0480001F, 0.135000005F), new Vector2(-3.0480001F, 0.451999992F), new Vector2(-2.85299993F, 0.647000015F)); + builder.AddLine(new Vector2(-2.14400005F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.949F, 1.54999995F), new Vector2(-1.63199997F, 1.54999995F), new Vector2(-1.43700004F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.24199998F, 1.15999997F), new Vector2(-1.24199998F, 0.842999995F), new Vector2(-1.43700004F, 0.648000002F)); + builder.AddLine(new Vector2(-2.14499998F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Subtract 2 + // - - - - ShapeGroup: Subtract + CanvasGeometry Geometry_4() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.501999974F, -1.00100005F)); + builder.AddCubicBezier(new Vector2(0.501999974F, -1.27699995F), new Vector2(0.277999997F, -1.50100005F), new Vector2(0.00200000009F, -1.50100005F)); + builder.AddCubicBezier(new Vector2(-0.273999989F, -1.50100005F), new Vector2(-0.497999996F, -1.27699995F), new Vector2(-0.497999996F, -1.00100005F)); + builder.AddLine(new Vector2(-0.497999996F, 0.00100000005F)); + builder.AddCubicBezier(new Vector2(-0.497999996F, 0.27700001F), new Vector2(-0.273999989F, 0.500999987F), new Vector2(0.00200000009F, 0.500999987F)); + builder.AddCubicBezier(new Vector2(0.277999997F, 0.500999987F), new Vector2(0.501999974F, 0.27700001F), new Vector2(0.501999974F, 0.00100000005F)); + builder.AddLine(new Vector2(0.501999974F, -1.00100005F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(2.65799999F, -0.254999995F), new Vector2(2.34100008F, -0.254999995F), new Vector2(2.14599991F, -0.0599999987F)); + builder.AddLine(new Vector2(1.43799996F, 0.648000002F)); + builder.AddCubicBezier(new Vector2(1.24300003F, 0.842999995F), new Vector2(1.24300003F, 1.15999997F), new Vector2(1.43799996F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(1.63300002F, 1.54999995F), new Vector2(1.95000005F, 1.54999995F), new Vector2(2.14499998F, 1.35500002F)); + builder.AddLine(new Vector2(2.85299993F, 0.647000015F)); + builder.AddCubicBezier(new Vector2(3.0480001F, 0.451999992F), new Vector2(3.0480001F, 0.135000005F), new Vector2(2.85299993F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(-2.14499998F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-2.33999991F, -0.254999995F), new Vector2(-2.65799999F, -0.254999995F), new Vector2(-2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-3.0480001F, 0.135000005F), new Vector2(-3.0480001F, 0.451999992F), new Vector2(-2.85299993F, 0.647000015F)); + builder.AddLine(new Vector2(-2.14400005F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.949F, 1.54999995F), new Vector2(-1.63199997F, 1.54999995F), new Vector2(-1.43700004F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.24199998F, 1.15999997F), new Vector2(-1.24199998F, 0.842999995F), new Vector2(-1.43700004F, 0.648000002F)); + builder.AddLine(new Vector2(-2.14499998F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Subtract 2 + // - - - ShapeGroup: Subtract + // Color + ColorKeyFrameAnimation ColorAnimation_TransparentWhite_to_White() + { + // Frame 0. + var result = CreateColorKeyFrameAnimation(0F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), HoldThenStepEasingFunction()); + // Frame 24. + // White + result.InsertKeyFrame(0.800000012F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Subtract + // - - - ShapeGroup: Subtract + // Color + ColorKeyFrameAnimation ColorAnimation_White_to_TransparentWhite() + { + // Frame 0. + var result = CreateColorKeyFrameAnimation(0F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), HoldThenStepEasingFunction()); + // Frame 10. + // TransparentWhite + result.InsertKeyFrame(0.333333343F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + // Frame 24. + // TransparentWhite + result.InsertKeyFrame(0.800000012F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract 2 + // - - ShapeGroup: Subtract + CompositionColorBrush AnimatedColorBrush_TransparentWhite_to_White() + { + if (_animatedColorBrush_TransparentWhite_to_White != null) { return _animatedColorBrush_TransparentWhite_to_White; } + var result = _animatedColorBrush_TransparentWhite_to_White = _c.CreateColorBrush(); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract + // - - ShapeGroup: Subtract + CompositionColorBrush AnimatedColorBrush_White_to_TransparentWhite() + { + if (_animatedColorBrush_White_to_TransparentWhite != null) { return _animatedColorBrush_White_to_TransparentWhite; } + var result = _animatedColorBrush_White_to_TransparentWhite = _c.CreateColorBrush(); + return result; + } + + // - - - - - Layer aggregator + // - - ShapeGroup: Subtract + // Path 1 + CompositionColorBrush ColorBrush_White() + { + return _c.CreateColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 0 + CompositionColorGradientStop GradientStop_0_AlmostKhaki_FFF8DA79_0() + { + return _c.CreateColorGradientStop(0F, Color.FromArgb(0xFF, 0xF8, 0xDA, 0x79)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 0 + CompositionColorGradientStop GradientStop_0_AlmostKhaki_FFF8DA79_1() + { + return _c.CreateColorGradientStop(0F, Color.FromArgb(0xFF, 0xF8, 0xDA, 0x79)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 1 + CompositionColorGradientStop GradientStop_1_AlmostSandyBrown_FFEDBB43_0() + { + return _c.CreateColorGradientStop(1F, Color.FromArgb(0xFF, 0xED, 0xBB, 0x43)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 1 + CompositionColorGradientStop GradientStop_1_AlmostSandyBrown_FFEDBB43_1() + { + return _c.CreateColorGradientStop(1F, Color.FromArgb(0xFF, 0xED, 0xBB, 0x43)); + } + + // Layer aggregator + CompositionContainerShape ContainerShape_00() + { + if (_containerShape_00 != null) { return _containerShape_00; } + var result = _containerShape_00 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Shape + result.Shapes.Add(ContainerShape_01()); + return result; + } + + // - Layer aggregator + // Transforms for Shape + CompositionContainerShape ContainerShape_01() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0.00499999989F, 45.0149994F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_02()); + return result; + } + + // - - Layer aggregator + // Transforms: Shape + CompositionContainerShape ContainerShape_02() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Shape + result.Shapes.Add(ContainerShape_03()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_03() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_04()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_04() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_0()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_05() + { + if (_containerShape_05 != null) { return _containerShape_05; } + var result = _containerShape_05 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Shape + result.Shapes.Add(ContainerShape_06()); + return result; + } + + // - Layer aggregator + // Transforms for Shape + CompositionContainerShape ContainerShape_06() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, -39.9850006F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_07()); + return result; + } + + // - - Layer aggregator + // Transforms: Shape + CompositionContainerShape ContainerShape_07() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Shape + result.Shapes.Add(ContainerShape_08()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_08() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_09()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_09() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_1()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_10() + { + if (_containerShape_10 != null) { return _containerShape_10; } + var result = _containerShape_10 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + result.Shapes.Add(ContainerShape_11()); + return result; + } + + // - Layer aggregator + CompositionContainerShape ContainerShape_11() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_12()); + return result; + } + + // - - Layer aggregator + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_12() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_13()); + return result; + } + + // - - - Layer aggregator + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_13() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_2()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_14() + { + if (_containerShape_14 != null) { return _containerShape_14; } + var result = _containerShape_14 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Subtract + result.Shapes.Add(ContainerShape_15()); + return result; + } + + // - Layer aggregator + // Transforms for Subtract + CompositionContainerShape ContainerShape_15() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 16F); + result.Offset = new Vector2(-0.023F, -44.9510002F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_16()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract + CompositionContainerShape ContainerShape_16() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_17()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Subtract + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_17() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_18()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Subtract + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_18() + { + var result = _c.CreateContainerShape(); + result.Shapes.Add(SpriteShape_3()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_19() + { + if (_containerShape_19 != null) { return _containerShape_19; } + var result = _containerShape_19 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Subtract 2 + result.Shapes.Add(ContainerShape_20()); + return result; + } + + // - Layer aggregator + // Transforms for Subtract 2 + CompositionContainerShape ContainerShape_20() + { + if (_containerShape_20 != null) { return _containerShape_20; } + var result = _containerShape_20 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 16F); + result.Offset = new Vector2(-0.023F, -44.9510002F); + result.RotationAngleInDegrees = 0F; + result.Shapes.Add(ContainerShape_21()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + CompositionContainerShape ContainerShape_21() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_22()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Subtract 2 + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_22() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_23()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Subtract 2 + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_23() + { + var result = _c.CreateContainerShape(); + result.Shapes.Add(SpriteShape_4()); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionLinearGradientBrush LinearGradientBrush_0() + { + var result = _c.CreateLinearGradientBrush(); + var colorStops = result.ColorStops; + colorStops.Add(GradientStop_0_AlmostKhaki_FFF8DA79_0()); + colorStops.Add(GradientStop_1_AlmostSandyBrown_FFEDBB43_0()); + result.MappingMode = CompositionMappingMode.Absolute; + result.StartPoint = new Vector2(0F, -1.5F); + result.EndPoint = new Vector2(0F, 1.5F); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionLinearGradientBrush LinearGradientBrush_1() + { + var result = _c.CreateLinearGradientBrush(); + var colorStops = result.ColorStops; + colorStops.Add(GradientStop_0_AlmostKhaki_FFF8DA79_1()); + colorStops.Add(GradientStop_1_AlmostSandyBrown_FFEDBB43_1()); + result.MappingMode = CompositionMappingMode.Absolute; + result.StartPoint = new Vector2(0F, -6F); + result.EndPoint = new Vector2(0F, 6F); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionPathGeometry PathGeometry_0() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_0())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionPathGeometry PathGeometry_1() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_1())); + } + + // - - - - - Layer aggregator + // - - ShapeGroup: Subtract + // Path 1 + CompositionPathGeometry PathGeometry_2() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_2())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract + // - - ShapeGroup: Subtract + CompositionPathGeometry PathGeometry_3() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_3())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract 2 + // - - ShapeGroup: Subtract + CompositionPathGeometry PathGeometry_4() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_4())); + } + + // - - - - - Layer aggregator + // - - - Transforms: Shape + // - ShapeGroup: Shape + // Path 1 + CompositionSpriteShape SpriteShape_0() + { + var result = _c.CreateSpriteShape(PathGeometry_0()); + result.FillBrush = LinearGradientBrush_0(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Shape + // - ShapeGroup: Shape + // Path 1 + CompositionSpriteShape SpriteShape_1() + { + var result = _c.CreateSpriteShape(PathGeometry_1()); + result.FillBrush = LinearGradientBrush_1(); + return result; + } + + // - - - - Layer aggregator + // - ShapeGroup: Subtract + // Path 1 + CompositionSpriteShape SpriteShape_2() + { + var result = _c.CreateSpriteShape(PathGeometry_2()); + result.FillBrush = ColorBrush_White(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Subtract + // - ShapeGroup: Subtract + CompositionSpriteShape SpriteShape_3() + { + var result = _c.CreateSpriteShape(PathGeometry_3()); + result.FillBrush = AnimatedColorBrush_White_to_TransparentWhite(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Subtract 2 + // - ShapeGroup: Subtract + CompositionSpriteShape SpriteShape_4() + { + var result = _c.CreateSpriteShape(PathGeometry_4()); + result.FillBrush = AnimatedColorBrush_TransparentWhite_to_White(); + return result; + } + + // The root of the composition. + ContainerVisual Root() + { + if (_root != null) { return _root; } + var result = _root = _c.CreateContainerVisual(); + var propertySet = result.Properties; + propertySet.InsertScalar("Progress", 0F); + // Layer aggregator + result.Children.InsertAtTop(ShapeVisual_0()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_0_to_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 0F, HoldThenStepEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_0() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_2() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_3() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_4() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_0_to_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 0F, HoldThenStepEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_0() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_2() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_3() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_4() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // Layer aggregator + ShapeVisual ShapeVisual_0() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(200F, 200F); + var shapes = result.Shapes; + shapes.Add(ContainerShape_00()); + shapes.Add(ContainerShape_05()); + shapes.Add(ContainerShape_10()); + shapes.Add(ContainerShape_14()); + shapes.Add(ContainerShape_19()); + return result; + } + + StepEasingFunction HoldThenStepEasingFunction() + { + if (_holdThenStepEasingFunction != null) { return _holdThenStepEasingFunction; } + var result = _holdThenStepEasingFunction = _c.CreateStepEasingFunction(); + result.FinalStep = 1; + result.IsFinalStepSingleFrame = true; + result.StepCount = 1; + return result; + } + + internal Tips_AnimatedVisual_UAPv15( + Compositor compositor + ) + { + _c = compositor; + _reusableExpressionAnimation = compositor.CreateExpressionAnimation(); + Root(); + } + + public Visual RootVisual => _root; + public TimeSpan Duration => TimeSpan.FromTicks(c_durationTicks); + public Vector2 Size => new Vector2(200F, 200F); + void IDisposable.Dispose() => _root?.Dispose(); + + public void CreateAnimations() + { + _animatedColorBrush_TransparentWhite_to_White.StartAnimation("Color", ColorAnimation_TransparentWhite_to_White(), AnimationController_0()); + _animatedColorBrush_White_to_TransparentWhite.StartAnimation("Color", ColorAnimation_White_to_TransparentWhite(), AnimationController_0()); + _containerShape_00.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_0(), AnimationController_0()); + _containerShape_00.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_0(), AnimationController_0()); + _containerShape_05.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_1(), AnimationController_0()); + _containerShape_05.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_1(), AnimationController_0()); + _containerShape_10.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_2(), AnimationController_0()); + _containerShape_10.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_2(), AnimationController_0()); + _containerShape_14.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_3(), AnimationController_0()); + _containerShape_14.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_3(), AnimationController_0()); + _containerShape_19.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_4(), AnimationController_0()); + _containerShape_19.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_4(), AnimationController_0()); + _containerShape_20.StartAnimation("Scale.X", ScaleXScalarAnimation_0_to_1(), AnimationController_0()); + _containerShape_20.StartAnimation("Scale.Y", ScaleYScalarAnimation_0_to_1(), AnimationController_0()); + } + + public void DestroyAnimations() + { + _animatedColorBrush_TransparentWhite_to_White.StopAnimation("Color"); + _animatedColorBrush_White_to_TransparentWhite.StopAnimation("Color"); + _containerShape_00.StopAnimation("Scale.X"); + _containerShape_00.StopAnimation("Scale.Y"); + _containerShape_05.StopAnimation("Scale.X"); + _containerShape_05.StopAnimation("Scale.Y"); + _containerShape_10.StopAnimation("Scale.X"); + _containerShape_10.StopAnimation("Scale.Y"); + _containerShape_14.StopAnimation("Scale.X"); + _containerShape_14.StopAnimation("Scale.Y"); + _containerShape_19.StopAnimation("Scale.X"); + _containerShape_19.StopAnimation("Scale.Y"); + _containerShape_20.StopAnimation("Scale.X"); + _containerShape_20.StopAnimation("Scale.Y"); + } + + internal static bool IsRuntimeCompatible() + { + return Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 15); + } + } + + sealed partial class Tips_AnimatedVisual_UAPv7 + : Microsoft.UI.Xaml.Controls.IAnimatedVisual + , Microsoft.UI.Xaml.Controls.IAnimatedVisual2 + { + const long c_durationTicks = 5000000; + readonly Compositor _c; + readonly ExpressionAnimation _reusableExpressionAnimation; + CompositionColorBrush _animatedColorBrush_TransparentWhite_to_White; + CompositionColorBrush _animatedColorBrush_White_to_TransparentWhite; + CompositionContainerShape _containerShape_00; + CompositionContainerShape _containerShape_05; + CompositionContainerShape _containerShape_10; + CompositionContainerShape _containerShape_14; + CompositionContainerShape _containerShape_19; + CompositionContainerShape _containerShape_20; + ContainerVisual _root; + StepEasingFunction _holdThenStepEasingFunction; + + void BindProperty( + CompositionObject target, + string animatedPropertyName, + string expression, + string referenceParameterName, + CompositionObject referencedObject) + { + _reusableExpressionAnimation.ClearAllParameters(); + _reusableExpressionAnimation.Expression = expression; + _reusableExpressionAnimation.SetReferenceParameter(referenceParameterName, referencedObject); + target.StartAnimation(animatedPropertyName, _reusableExpressionAnimation); + } + + ColorKeyFrameAnimation CreateColorKeyFrameAnimation(float initialProgress, Color initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateColorKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InterpolationColorSpace = CompositionColorSpace.Rgb; + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + ScalarKeyFrameAnimation CreateScalarKeyFrameAnimation(float initialProgress, float initialValue, CompositionEasingFunction initialEasingFunction) + { + var result = _c.CreateScalarKeyFrameAnimation(); + result.Duration = TimeSpan.FromTicks(c_durationTicks); + result.InsertKeyFrame(initialProgress, initialValue, initialEasingFunction); + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Shape + // - - - - ShapeGroup: Shape + // - - Path 1 + CanvasGeometry Geometry_0() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(2.68899989F, 0.104999997F)); + builder.AddLine(new Vector2(3.07200003F, -1.5F)); + builder.AddLine(new Vector2(-3.07200003F, -1.5F)); + builder.AddLine(new Vector2(-2.68899989F, 0.104999997F)); + builder.AddLine(new Vector2(-2.65199995F, 0.238999993F)); + builder.AddCubicBezier(new Vector2(-2.41100001F, 0.984000027F), new Vector2(-1.69400001F, 1.5F), new Vector2(-0.875F, 1.5F)); + builder.AddLine(new Vector2(0.874000013F, 1.5F)); + builder.AddLine(new Vector2(1.01800001F, 1.495F)); + builder.AddCubicBezier(new Vector2(1.82299995F, 1.43499994F), new Vector2(2.50500011F, 0.875999987F), new Vector2(2.68899989F, 0.104999997F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Shape + // - - - - ShapeGroup: Shape + // - - Path 1 + CanvasGeometry Geometry_1() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(6F, -0.200000003F)); + builder.AddCubicBezier(new Vector2(6F, -3.40300012F), new Vector2(3.31399989F, -6F), new Vector2(0F, -6F)); + builder.AddCubicBezier(new Vector2(-3.24699998F, -6F), new Vector2(-5.89300013F, -3.50600004F), new Vector2(-5.99700022F, -0.391000003F)); + builder.AddLine(new Vector2(-6F, -0.200000003F)); + builder.AddLine(new Vector2(-5.99499989F, 0.0390000008F)); + builder.AddCubicBezier(new Vector2(-5.92700005F, 1.62399995F), new Vector2(-5.18499994F, 3.08200002F), new Vector2(-3.79500008F, 4.39400005F)); + builder.AddCubicBezier(new Vector2(-3.71000004F, 4.47399998F), new Vector2(-3.65100002F, 4.57700014F), new Vector2(-3.62400007F, 4.68900013F)); + builder.AddLine(new Vector2(-3.31100011F, 6F)); + builder.AddLine(new Vector2(3.31100011F, 6F)); + builder.AddLine(new Vector2(3.625F, 4.6880002F)); + builder.AddLine(new Vector2(3.65100002F, 4.60699987F)); + builder.AddCubicBezier(new Vector2(3.68300009F, 4.52699995F), new Vector2(3.73200011F, 4.454F), new Vector2(3.796F, 4.39400005F)); + builder.AddCubicBezier(new Vector2(5.25500011F, 3.01600003F), new Vector2(6F, 1.477F), new Vector2(6F, -0.200000003F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - Layer aggregator + // - - - - ShapeGroup: Subtract + // - - Path 1 + CanvasGeometry Geometry_2() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.5F, -2.50099993F)); + builder.AddCubicBezier(new Vector2(0.5F, -2.77699995F), new Vector2(0.275999993F, -3.00099993F), new Vector2(0F, -3.00099993F)); + builder.AddCubicBezier(new Vector2(-0.275999993F, -3.00099993F), new Vector2(-0.5F, -2.77699995F), new Vector2(-0.5F, -2.50099993F)); + builder.AddLine(new Vector2(-0.5F, 2.00099993F)); + builder.AddLine(new Vector2(-3.31100011F, 2.00099993F)); + builder.AddLine(new Vector2(-3.07200003F, 3.00099993F)); + builder.AddLine(new Vector2(3.07299995F, 3.00099993F)); + builder.AddLine(new Vector2(3.31100011F, 2.00099993F)); + builder.AddLine(new Vector2(0.5F, 2.00099993F)); + builder.AddLine(new Vector2(0.5F, -2.50099993F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Subtract + // - - - - ShapeGroup: Subtract + CanvasGeometry Geometry_3() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.501999974F, -1.00100005F)); + builder.AddCubicBezier(new Vector2(0.501999974F, -1.27699995F), new Vector2(0.277999997F, -1.50100005F), new Vector2(0.00200000009F, -1.50100005F)); + builder.AddCubicBezier(new Vector2(-0.273999989F, -1.50100005F), new Vector2(-0.497999996F, -1.27699995F), new Vector2(-0.497999996F, -1.00100005F)); + builder.AddLine(new Vector2(-0.497999996F, 0.00100000005F)); + builder.AddCubicBezier(new Vector2(-0.497999996F, 0.27700001F), new Vector2(-0.273999989F, 0.500999987F), new Vector2(0.00200000009F, 0.500999987F)); + builder.AddCubicBezier(new Vector2(0.277999997F, 0.500999987F), new Vector2(0.501999974F, 0.27700001F), new Vector2(0.501999974F, 0.00100000005F)); + builder.AddLine(new Vector2(0.501999974F, -1.00100005F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(2.65799999F, -0.254999995F), new Vector2(2.34100008F, -0.254999995F), new Vector2(2.14599991F, -0.0599999987F)); + builder.AddLine(new Vector2(1.43799996F, 0.648000002F)); + builder.AddCubicBezier(new Vector2(1.24300003F, 0.842999995F), new Vector2(1.24300003F, 1.15999997F), new Vector2(1.43799996F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(1.63300002F, 1.54999995F), new Vector2(1.95000005F, 1.54999995F), new Vector2(2.14499998F, 1.35500002F)); + builder.AddLine(new Vector2(2.85299993F, 0.647000015F)); + builder.AddCubicBezier(new Vector2(3.0480001F, 0.451999992F), new Vector2(3.0480001F, 0.135000005F), new Vector2(2.85299993F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(-2.14499998F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-2.33999991F, -0.254999995F), new Vector2(-2.65799999F, -0.254999995F), new Vector2(-2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-3.0480001F, 0.135000005F), new Vector2(-3.0480001F, 0.451999992F), new Vector2(-2.85299993F, 0.647000015F)); + builder.AddLine(new Vector2(-2.14400005F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.949F, 1.54999995F), new Vector2(-1.63199997F, 1.54999995F), new Vector2(-1.43700004F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.24199998F, 1.15999997F), new Vector2(-1.24199998F, 0.842999995F), new Vector2(-1.43700004F, 0.648000002F)); + builder.AddLine(new Vector2(-2.14499998F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - - Layer aggregator + // - - - - - - Transforms: Subtract 2 + // - - - - ShapeGroup: Subtract + CanvasGeometry Geometry_4() + { + CanvasGeometry result; + using (var builder = new CanvasPathBuilder(null)) + { + builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); + builder.BeginFigure(new Vector2(0.501999974F, -1.00100005F)); + builder.AddCubicBezier(new Vector2(0.501999974F, -1.27699995F), new Vector2(0.277999997F, -1.50100005F), new Vector2(0.00200000009F, -1.50100005F)); + builder.AddCubicBezier(new Vector2(-0.273999989F, -1.50100005F), new Vector2(-0.497999996F, -1.27699995F), new Vector2(-0.497999996F, -1.00100005F)); + builder.AddLine(new Vector2(-0.497999996F, 0.00100000005F)); + builder.AddCubicBezier(new Vector2(-0.497999996F, 0.27700001F), new Vector2(-0.273999989F, 0.500999987F), new Vector2(0.00200000009F, 0.500999987F)); + builder.AddCubicBezier(new Vector2(0.277999997F, 0.500999987F), new Vector2(0.501999974F, 0.27700001F), new Vector2(0.501999974F, 0.00100000005F)); + builder.AddLine(new Vector2(0.501999974F, -1.00100005F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(2.65799999F, -0.254999995F), new Vector2(2.34100008F, -0.254999995F), new Vector2(2.14599991F, -0.0599999987F)); + builder.AddLine(new Vector2(1.43799996F, 0.648000002F)); + builder.AddCubicBezier(new Vector2(1.24300003F, 0.842999995F), new Vector2(1.24300003F, 1.15999997F), new Vector2(1.43799996F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(1.63300002F, 1.54999995F), new Vector2(1.95000005F, 1.54999995F), new Vector2(2.14499998F, 1.35500002F)); + builder.AddLine(new Vector2(2.85299993F, 0.647000015F)); + builder.AddCubicBezier(new Vector2(3.0480001F, 0.451999992F), new Vector2(3.0480001F, 0.135000005F), new Vector2(2.85299993F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + builder.BeginFigure(new Vector2(-2.14499998F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-2.33999991F, -0.254999995F), new Vector2(-2.65799999F, -0.254999995F), new Vector2(-2.85299993F, -0.0599999987F)); + builder.AddCubicBezier(new Vector2(-3.0480001F, 0.135000005F), new Vector2(-3.0480001F, 0.451999992F), new Vector2(-2.85299993F, 0.647000015F)); + builder.AddLine(new Vector2(-2.14400005F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.949F, 1.54999995F), new Vector2(-1.63199997F, 1.54999995F), new Vector2(-1.43700004F, 1.35500002F)); + builder.AddCubicBezier(new Vector2(-1.24199998F, 1.15999997F), new Vector2(-1.24199998F, 0.842999995F), new Vector2(-1.43700004F, 0.648000002F)); + builder.AddLine(new Vector2(-2.14499998F, -0.0599999987F)); + builder.EndFigure(CanvasFigureLoop.Closed); + result = CanvasGeometry.CreatePath(builder); + } + return result; + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Subtract 2 + // - - - ShapeGroup: Subtract + // Color + ColorKeyFrameAnimation ColorAnimation_TransparentWhite_to_White() + { + // Frame 0. + var result = CreateColorKeyFrameAnimation(0F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), HoldThenStepEasingFunction()); + // Frame 24. + // White + result.InsertKeyFrame(0.800000012F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Subtract + // - - - ShapeGroup: Subtract + // Color + ColorKeyFrameAnimation ColorAnimation_White_to_TransparentWhite() + { + // Frame 0. + var result = CreateColorKeyFrameAnimation(0F, Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), HoldThenStepEasingFunction()); + // Frame 10. + // TransparentWhite + result.InsertKeyFrame(0.333333343F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + // Frame 24. + // TransparentWhite + result.InsertKeyFrame(0.800000012F, Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF), _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract 2 + // - - ShapeGroup: Subtract + CompositionColorBrush AnimatedColorBrush_TransparentWhite_to_White() + { + if (_animatedColorBrush_TransparentWhite_to_White != null) { return _animatedColorBrush_TransparentWhite_to_White; } + var result = _animatedColorBrush_TransparentWhite_to_White = _c.CreateColorBrush(); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract + // - - ShapeGroup: Subtract + CompositionColorBrush AnimatedColorBrush_White_to_TransparentWhite() + { + if (_animatedColorBrush_White_to_TransparentWhite != null) { return _animatedColorBrush_White_to_TransparentWhite; } + var result = _animatedColorBrush_White_to_TransparentWhite = _c.CreateColorBrush(); + return result; + } + + // - - - - - Layer aggregator + // - - ShapeGroup: Subtract + // Path 1 + CompositionColorBrush ColorBrush_White() + { + return _c.CreateColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 0 + CompositionColorGradientStop GradientStop_0_AlmostKhaki_FFF8DA79_0() + { + return _c.CreateColorGradientStop(0F, Color.FromArgb(0xFF, 0xF8, 0xDA, 0x79)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 0 + CompositionColorGradientStop GradientStop_0_AlmostKhaki_FFF8DA79_1() + { + return _c.CreateColorGradientStop(0F, Color.FromArgb(0xFF, 0xF8, 0xDA, 0x79)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 1 + CompositionColorGradientStop GradientStop_1_AlmostSandyBrown_FFEDBB43_0() + { + return _c.CreateColorGradientStop(1F, Color.FromArgb(0xFF, 0xED, 0xBB, 0x43)); + } + + // - - - - - - - Layer aggregator + // - - - - - Transforms: Shape + // - - - ShapeGroup: Shape + // - Path 1 + // Stop 1 + CompositionColorGradientStop GradientStop_1_AlmostSandyBrown_FFEDBB43_1() + { + return _c.CreateColorGradientStop(1F, Color.FromArgb(0xFF, 0xED, 0xBB, 0x43)); + } + + // Layer aggregator + CompositionContainerShape ContainerShape_00() + { + if (_containerShape_00 != null) { return _containerShape_00; } + var result = _containerShape_00 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Shape + result.Shapes.Add(ContainerShape_01()); + return result; + } + + // - Layer aggregator + // Transforms for Shape + CompositionContainerShape ContainerShape_01() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0.00499999989F, 45.0149994F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_02()); + return result; + } + + // - - Layer aggregator + // Transforms: Shape + CompositionContainerShape ContainerShape_02() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Shape + result.Shapes.Add(ContainerShape_03()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_03() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_04()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_04() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_0()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_05() + { + if (_containerShape_05 != null) { return _containerShape_05; } + var result = _containerShape_05 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Shape + result.Shapes.Add(ContainerShape_06()); + return result; + } + + // - Layer aggregator + // Transforms for Shape + CompositionContainerShape ContainerShape_06() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, -39.9850006F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_07()); + return result; + } + + // - - Layer aggregator + // Transforms: Shape + CompositionContainerShape ContainerShape_07() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Shape + result.Shapes.Add(ContainerShape_08()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_08() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_09()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Shape + // ShapeGroup: Shape + CompositionContainerShape ContainerShape_09() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_1()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_10() + { + if (_containerShape_10 != null) { return _containerShape_10; } + var result = _containerShape_10 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + result.Shapes.Add(ContainerShape_11()); + return result; + } + + // - Layer aggregator + CompositionContainerShape ContainerShape_11() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_12()); + return result; + } + + // - - Layer aggregator + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_12() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_13()); + return result; + } + + // - - - Layer aggregator + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_13() + { + var result = _c.CreateContainerShape(); + // Path 1 + result.Shapes.Add(SpriteShape_2()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_14() + { + if (_containerShape_14 != null) { return _containerShape_14; } + var result = _containerShape_14 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Subtract + result.Shapes.Add(ContainerShape_15()); + return result; + } + + // - Layer aggregator + // Transforms for Subtract + CompositionContainerShape ContainerShape_15() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 16F); + result.Offset = new Vector2(-0.023F, -44.9510002F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(1F, 1F); + result.Shapes.Add(ContainerShape_16()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract + CompositionContainerShape ContainerShape_16() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_17()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Subtract + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_17() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_18()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Subtract + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_18() + { + var result = _c.CreateContainerShape(); + result.Shapes.Add(SpriteShape_3()); + return result; + } + + // Layer aggregator + CompositionContainerShape ContainerShape_19() + { + if (_containerShape_19 != null) { return _containerShape_19; } + var result = _containerShape_19 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(100F, 119.985001F); + result.RotationAngleInDegrees = 0F; + // Transforms: Subtract 2 + result.Shapes.Add(ContainerShape_20()); + return result; + } + + // - Layer aggregator + // Transforms for Subtract 2 + CompositionContainerShape ContainerShape_20() + { + if (_containerShape_20 != null) { return _containerShape_20; } + var result = _containerShape_20 = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 16F); + result.Offset = new Vector2(-0.023F, -44.9510002F); + result.RotationAngleInDegrees = 0F; + result.Shapes.Add(ContainerShape_21()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + CompositionContainerShape ContainerShape_21() + { + var result = _c.CreateContainerShape(); + // ShapeGroup: Subtract + result.Shapes.Add(ContainerShape_22()); + return result; + } + + // - - - Layer aggregator + // - Transforms: Subtract 2 + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_22() + { + var result = _c.CreateContainerShape(); + result.CenterPoint = new Vector2(0F, 0F); + result.Offset = new Vector2(0F, 0F); + result.RotationAngleInDegrees = 0F; + result.Scale = new Vector2(10F, 10F); + result.Shapes.Add(ContainerShape_23()); + return result; + } + + // - - - - Layer aggregator + // - - Transforms: Subtract 2 + // ShapeGroup: Subtract + CompositionContainerShape ContainerShape_23() + { + var result = _c.CreateContainerShape(); + result.Shapes.Add(SpriteShape_4()); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionLinearGradientBrush LinearGradientBrush_0() + { + var result = _c.CreateLinearGradientBrush(); + var colorStops = result.ColorStops; + colorStops.Add(GradientStop_0_AlmostKhaki_FFF8DA79_0()); + colorStops.Add(GradientStop_1_AlmostSandyBrown_FFEDBB43_0()); + result.MappingMode = CompositionMappingMode.Absolute; + result.StartPoint = new Vector2(0F, -1.5F); + result.EndPoint = new Vector2(0F, 1.5F); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionLinearGradientBrush LinearGradientBrush_1() + { + var result = _c.CreateLinearGradientBrush(); + var colorStops = result.ColorStops; + colorStops.Add(GradientStop_0_AlmostKhaki_FFF8DA79_1()); + colorStops.Add(GradientStop_1_AlmostSandyBrown_FFEDBB43_1()); + result.MappingMode = CompositionMappingMode.Absolute; + result.StartPoint = new Vector2(0F, -6F); + result.EndPoint = new Vector2(0F, 6F); + return result; + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionPathGeometry PathGeometry_0() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_0())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Shape + // - - ShapeGroup: Shape + // Path 1 + CompositionPathGeometry PathGeometry_1() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_1())); + } + + // - - - - - Layer aggregator + // - - ShapeGroup: Subtract + // Path 1 + CompositionPathGeometry PathGeometry_2() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_2())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract + // - - ShapeGroup: Subtract + CompositionPathGeometry PathGeometry_3() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_3())); + } + + // - - - - - - Layer aggregator + // - - - - Transforms: Subtract 2 + // - - ShapeGroup: Subtract + CompositionPathGeometry PathGeometry_4() + { + return _c.CreatePathGeometry(new CompositionPath(Geometry_4())); + } + + // - - - - - Layer aggregator + // - - - Transforms: Shape + // - ShapeGroup: Shape + // Path 1 + CompositionSpriteShape SpriteShape_0() + { + var result = _c.CreateSpriteShape(PathGeometry_0()); + result.FillBrush = LinearGradientBrush_0(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Shape + // - ShapeGroup: Shape + // Path 1 + CompositionSpriteShape SpriteShape_1() + { + var result = _c.CreateSpriteShape(PathGeometry_1()); + result.FillBrush = LinearGradientBrush_1(); + return result; + } + + // - - - - Layer aggregator + // - ShapeGroup: Subtract + // Path 1 + CompositionSpriteShape SpriteShape_2() + { + var result = _c.CreateSpriteShape(PathGeometry_2()); + result.FillBrush = ColorBrush_White(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Subtract + // - ShapeGroup: Subtract + CompositionSpriteShape SpriteShape_3() + { + var result = _c.CreateSpriteShape(PathGeometry_3()); + result.FillBrush = AnimatedColorBrush_White_to_TransparentWhite(); + return result; + } + + // - - - - - Layer aggregator + // - - - Transforms: Subtract 2 + // - ShapeGroup: Subtract + CompositionSpriteShape SpriteShape_4() + { + var result = _c.CreateSpriteShape(PathGeometry_4()); + result.FillBrush = AnimatedColorBrush_TransparentWhite_to_White(); + return result; + } + + // The root of the composition. + ContainerVisual Root() + { + if (_root != null) { return _root; } + var result = _root = _c.CreateContainerVisual(); + var propertySet = result.Properties; + propertySet.InsertScalar("Progress", 0F); + // Layer aggregator + result.Children.InsertAtTop(ShapeVisual_0()); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_0_to_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 0F, HoldThenStepEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_0() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_2() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_3() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleXScalarAnimation_1_to_1_4() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - - Layer aggregator + // Transforms: Subtract 2 + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_0_to_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 0F, HoldThenStepEasingFunction()); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.200000003F, 1F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_0() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_1() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_2() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_3() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // - Layer aggregator + // Scale + ScalarKeyFrameAnimation ScaleYScalarAnimation_1_to_1_4() + { + // Frame 0. + var result = CreateScalarKeyFrameAnimation(0F, 1F, HoldThenStepEasingFunction()); + // Frame 1. + result.InsertKeyFrame(0.0333333351F, 1.00792003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.166999996F), new Vector2(0.833000004F, 0.714999974F))); + // Frame 2. + result.InsertKeyFrame(0.0666666701F, 1.02708995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.118000001F), new Vector2(0.833000004F, 0.86500001F))); + // Frame 3. + result.InsertKeyFrame(0.100000001F, 1.03894997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.217999995F), new Vector2(0.833000004F, 0.74000001F))); + // Frame 4. + result.InsertKeyFrame(0.13333334F, 1.06402004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123000003F), new Vector2(0.833000004F, 0.838F))); + // Frame 5. + result.InsertKeyFrame(0.166666672F, 1.08773994F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.171000004F), new Vector2(0.833000004F, 0.847000003F))); + // Frame 6. + result.InsertKeyFrame(0.200000003F, 1.10764003F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.182999998F), new Vector2(0.833000004F, 0.883000016F))); + // Frame 7. + result.InsertKeyFrame(0.233333334F, 1.11573005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.287999988F), new Vector2(0.833000004F, 0.822000027F))); + // Frame 8. + result.InsertKeyFrame(0.266666681F, 1.12495005F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.157000005F), new Vector2(0.833000004F, 0.953000009F))); + // Frame 9. + result.InsertKeyFrame(0.300000012F, 1.12093997F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0.455000013F))); + // Frame 10. + result.InsertKeyFrame(0.333333343F, 1.09875F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0979999974F), new Vector2(0.833000004F, 0.791999996F))); + // Frame 11. + result.InsertKeyFrame(0.366666675F, 1.06546998F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.870999992F))); + // Frame 12. + result.InsertKeyFrame(0.400000006F, 1.04718995F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.234999999F), new Vector2(0.833000004F, 0.753000021F))); + // Frame 13. + result.InsertKeyFrame(0.433333337F, 1.01118004F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.126000002F), new Vector2(0.833000004F, 0.842999995F))); + // Frame 14. + result.InsertKeyFrame(0.466666669F, 0.979480028F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.178000003F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 15. + result.InsertKeyFrame(0.5F, 0.966099977F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.280999988F), new Vector2(0.833000004F, 0.791000009F))); + // Frame 16. + result.InsertKeyFrame(0.533333361F, 0.945890009F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.138999999F), new Vector2(0.833000004F, 0.885999978F))); + // Frame 17. + result.InsertKeyFrame(0.566666663F, 0.938359976F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.307000011F), new Vector2(0.833000004F, 0.920000017F))); + // Frame 18. + result.InsertKeyFrame(0.600000024F, 0.938619971F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0F), new Vector2(0.833000004F, 0F))); + // Frame 19. + result.InsertKeyFrame(0.633333325F, 0.944859982F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.0869999975F), new Vector2(0.833000004F, 0.769999981F))); + // Frame 20. + result.InsertKeyFrame(0.666666687F, 0.955869973F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.130999997F), new Vector2(0.833000004F, 0.869000018F))); + // Frame 21. + result.InsertKeyFrame(0.699999988F, 0.96221F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.228F), new Vector2(0.833000004F, 0.746999979F))); + // Frame 22. + result.InsertKeyFrame(0.733333349F, 0.975099981F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.123999998F), new Vector2(0.833000004F, 0.841000021F))); + // Frame 23. + result.InsertKeyFrame(0.766666651F, 0.986810029F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.174999997F), new Vector2(0.833000004F, 0.880999982F))); + // Frame 24. + result.InsertKeyFrame(0.800000012F, 0.991869986F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.275999993F), new Vector2(0.833000004F, 0.782999992F))); + // Frame 25. + result.InsertKeyFrame(0.833333313F, 1F, _c.CreateCubicBezierEasingFunction(new Vector2(0.166999996F, 0.135000005F), new Vector2(0.833000004F, 0.833000004F))); + return result; + } + + // Layer aggregator + ShapeVisual ShapeVisual_0() + { + var result = _c.CreateShapeVisual(); + result.Size = new Vector2(200F, 200F); + var shapes = result.Shapes; + shapes.Add(ContainerShape_00()); + shapes.Add(ContainerShape_05()); + shapes.Add(ContainerShape_10()); + shapes.Add(ContainerShape_14()); + shapes.Add(ContainerShape_19()); + return result; + } + + StepEasingFunction HoldThenStepEasingFunction() + { + if (_holdThenStepEasingFunction != null) { return _holdThenStepEasingFunction; } + var result = _holdThenStepEasingFunction = _c.CreateStepEasingFunction(); + result.FinalStep = 1; + result.IsFinalStepSingleFrame = true; + result.StepCount = 1; + return result; + } + + internal Tips_AnimatedVisual_UAPv7( + Compositor compositor + ) + { + _c = compositor; + _reusableExpressionAnimation = compositor.CreateExpressionAnimation(); + Root(); + } + + public Visual RootVisual => _root; + public TimeSpan Duration => TimeSpan.FromTicks(c_durationTicks); + public Vector2 Size => new Vector2(200F, 200F); + void IDisposable.Dispose() => _root?.Dispose(); + + public void CreateAnimations() + { + _animatedColorBrush_TransparentWhite_to_White.StartAnimation("Color", ColorAnimation_TransparentWhite_to_White()); + var controller = _animatedColorBrush_TransparentWhite_to_White.TryGetAnimationController("Color"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _animatedColorBrush_White_to_TransparentWhite.StartAnimation("Color", ColorAnimation_White_to_TransparentWhite()); + controller = _animatedColorBrush_White_to_TransparentWhite.TryGetAnimationController("Color"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_00.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_0()); + controller = _containerShape_00.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_00.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_0()); + controller = _containerShape_00.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_05.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_1()); + controller = _containerShape_05.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_05.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_1()); + controller = _containerShape_05.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_10.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_2()); + controller = _containerShape_10.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_10.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_2()); + controller = _containerShape_10.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_14.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_3()); + controller = _containerShape_14.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_14.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_3()); + controller = _containerShape_14.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_19.StartAnimation("Scale.X", ScaleXScalarAnimation_1_to_1_4()); + controller = _containerShape_19.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_19.StartAnimation("Scale.Y", ScaleYScalarAnimation_1_to_1_4()); + controller = _containerShape_19.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_20.StartAnimation("Scale.X", ScaleXScalarAnimation_0_to_1()); + controller = _containerShape_20.TryGetAnimationController("Scale.X"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + _containerShape_20.StartAnimation("Scale.Y", ScaleYScalarAnimation_0_to_1()); + controller = _containerShape_20.TryGetAnimationController("Scale.Y"); + controller.Pause(); + BindProperty(controller, "Progress", "_.Progress", "_", _root); + } + + public void DestroyAnimations() + { + _animatedColorBrush_TransparentWhite_to_White.StopAnimation("Color"); + _animatedColorBrush_White_to_TransparentWhite.StopAnimation("Color"); + _containerShape_00.StopAnimation("Scale.X"); + _containerShape_00.StopAnimation("Scale.Y"); + _containerShape_05.StopAnimation("Scale.X"); + _containerShape_05.StopAnimation("Scale.Y"); + _containerShape_10.StopAnimation("Scale.X"); + _containerShape_10.StopAnimation("Scale.Y"); + _containerShape_14.StopAnimation("Scale.X"); + _containerShape_14.StopAnimation("Scale.Y"); + _containerShape_19.StopAnimation("Scale.X"); + _containerShape_19.StopAnimation("Scale.Y"); + _containerShape_20.StopAnimation("Scale.X"); + _containerShape_20.StopAnimation("Scale.Y"); + } + + internal static bool IsRuntimeCompatible() + { + return Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 7); + } + } + } +} diff --git a/Telegram/Assets/Icons/Tips.json b/Telegram/Assets/Icons/Tips.json new file mode 100644 index 0000000000..43458f8dd1 --- /dev/null +++ b/Telegram/Assets/Icons/Tips.json @@ -0,0 +1 @@ +{"v":"5.12.1","fr":60,"ip":0,"op":30,"w":200,"h":200,"nm":"u_username","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Subtract 2","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.023,-28.951,0],"ix":2,"l":2},"a":{"a":0,"k":[0,16,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":0,"s":[0,0,100]},{"t":24,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.195,-0.195],[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195]],"o":[[-0.195,-0.195],[-0.195,0.195],[0,0],[0.195,0.195],[0.195,-0.195],[0,0]],"v":[[-2.145,-0.06],[-2.853,-0.06],[-2.853,0.647],[-2.144,1.355],[-1.437,1.355],[-1.437,0.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.195,0.195],[0.195,-0.195],[0,0],[-0.195,-0.195],[-0.195,0.195],[0,0]],"o":[[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195],[0,0],[0.195,-0.195]],"v":[[2.853,-0.06],[2.146,-0.06],[1.438,0.648],[1.438,1.355],[2.145,1.355],[2.853,0.647]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0.276,0],[0,-0.276],[0,0],[-0.276,0],[0,0.276]],"o":[[0,-0.276],[-0.276,0],[0,0],[0,0.276],[0.276,0],[0,0]],"v":[[0.502,-1.001],[0.002,-1.501],[-0.498,-1.001],[-0.498,0.001],[0.002,0.501],[0.502,0.001]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Subtract","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Subtract","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":10,"s":[0]},{"t":24,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.023,-28.951,0],"ix":2,"l":2},"a":{"a":0,"k":[0,16,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0.195,-0.195],[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195]],"o":[[-0.195,-0.195],[-0.195,0.195],[0,0],[0.195,0.195],[0.195,-0.195],[0,0]],"v":[[-2.145,-0.06],[-2.853,-0.06],[-2.853,0.647],[-2.144,1.355],[-1.437,1.355],[-1.437,0.648]],"c":true}]},{"t":24,"s":[{"i":[[0,0],[0.195,-0.195],[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195]],"o":[[-0.195,-0.195],[-0.195,0.195],[0,0],[0.195,0.195],[0.195,-0.195],[0,0]],"v":[[-3.461,-1.376],[-4.169,-1.376],[-4.169,-0.669],[-3.46,0.039],[-2.753,0.039],[-2.753,-0.668]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0.195,0.195],[0.195,-0.195],[0,0],[-0.195,-0.195],[-0.195,0.195],[0,0]],"o":[[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195],[0,0],[0.195,-0.195]],"v":[[2.853,-0.06],[2.146,-0.06],[1.438,0.648],[1.438,1.355],[2.145,1.355],[2.853,0.647]],"c":true}]},{"t":24,"s":[{"i":[[0.195,0.195],[0.195,-0.195],[0,0],[-0.195,-0.195],[-0.195,0.195],[0,0]],"o":[[-0.195,-0.195],[0,0],[-0.195,0.195],[0.195,0.195],[0,0],[0.195,-0.195]],"v":[[4.169,-1.376],[3.462,-1.376],[2.754,-0.668],[2.754,0.039],[3.461,0.039],[4.169,-0.669]],"c":true}]}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0.276,0],[0,-0.276],[0,0],[-0.276,0],[0,0.276]],"o":[[0,-0.276],[-0.276,0],[0,0],[0,0.276],[0.276,0],[0,0]],"v":[[0.502,-1.001],[0.002,-1.501],[-0.498,-1.001],[-0.498,0.001],[0.002,0.501],[0.502,0.001]],"c":true}]},{"t":24,"s":[{"i":[[0,0],[0.276,0],[0,-0.276],[0,0],[-0.276,0],[0,0.276]],"o":[[0,-0.276],[-0.276,0],[0,0],[0,0.276],[0.276,0],[0,0]],"v":[[0.502,-3.633],[0.002,-4.133],[-0.498,-3.633],[-0.498,-2.631],[0.002,-2.131],[0.502,-2.631]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Subtract","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Subtract","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,119.985,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.715,0.715,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.865,0.865,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.118,0.118,0]},"t":1,"s":[100.792,100.792,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.74,0.74,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.218,0.218,0]},"t":2,"s":[102.709,102.709,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.838,0.838,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.123,0.123,0]},"t":3,"s":[103.895,103.895,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.847,0.847,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.171,0.171,0]},"t":4,"s":[106.402,106.402,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.883,0.883,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.183,0.183,0]},"t":5,"s":[108.774,108.774,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.822,0.822,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.288,0.288,0]},"t":6,"s":[110.764,110.764,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.953,0.953,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.157,0.157,0]},"t":7,"s":[111.573,111.573,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.455,0.455,1]},"o":{"x":[0.167,0.167,0.167],"y":[-0.108,-0.108,0]},"t":8,"s":[112.495,112.495,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.792,0.792,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.098,0.098,0]},"t":9,"s":[112.094,112.094,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.871,0.871,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.139,0.139,0]},"t":10,"s":[109.875,109.875,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.753,0.753,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.235,0.235,0]},"t":11,"s":[106.547,106.547,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.843,0.843,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.126,0.126,0]},"t":12,"s":[104.719,104.719,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.881,0.881,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.178,0.178,0]},"t":13,"s":[101.118,101.118,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.791,0.791,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.281,0.281,0]},"t":14,"s":[97.948,97.948,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.886,0.886,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.139,0.139,0]},"t":15,"s":[96.61,96.61,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.92,0.92,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.307,0.307,0]},"t":16,"s":[94.589,94.589,100]},{"i":{"x":[0.833,0.833,0.833],"y":[-1.099,-1.099,1]},"o":{"x":[0.167,0.167,0.167],"y":[-2.347,-2.347,0]},"t":17,"s":[93.836,93.836,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.77,0.77,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.087,0.087,0]},"t":18,"s":[93.862,93.862,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.869,0.869,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.131,0.131,0]},"t":19,"s":[94.486,94.486,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.747,0.747,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.228,0.228,0]},"t":20,"s":[95.587,95.587,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.841,0.841,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.124,0.124,0]},"t":21,"s":[96.221,96.221,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.881,0.881,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.175,0.175,0]},"t":22,"s":[97.51,97.51,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.783,0.783,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.276,0.276,0]},"t":23,"s":[98.681,98.681,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1.001]},"o":{"x":[0.167,0.167,0.167],"y":[0.135,0.135,0]},"t":24,"s":[99.187,99.187,100]},{"t":25,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.276,0],[0,-0.276],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,-0.276],[-0.276,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.5,-2.501],[0,-3.001],[-0.5,-2.501],[-0.5,2.001],[-3.311,2.001],[-3.072,3.001],[3.073,3.001],[3.311,2.001],[0.5,2.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Subtract","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-39.985,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,1.677],[3.314,0],[0.104,-3.115],[0,0],[0,0],[-1.39,-1.312],[-0.027,-0.112],[0,0],[0,0],[0,0],[0,0],[-0.064,0.06]],"o":[[0,-3.203],[-3.247,0],[0,0],[0,0],[0.068,1.585],[0.085,0.08],[0,0],[0,0],[0,0],[0,0],[0.032,-0.08],[1.459,-1.378]],"v":[[6,-0.2],[0,-6],[-5.997,-0.391],[-6,-0.2],[-5.995,0.039],[-3.795,4.394],[-3.624,4.689],[-3.311,6],[3.311,6],[3.625,4.688],[3.651,4.607],[3.796,4.394]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.976,0.855,0.478,0.5,0.955,0.796,0.371,1,0.933,0.737,0.263],"ix":9}},"s":{"a":0,"k":[0,-6],"ix":5},"e":{"a":0,"k":[0,6],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.005,45.015,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.184,0.771],[0,0],[0,0],[0,0],[0,0],[-0.819,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0.241,0.745],[0,0],[0,0],[0.805,-0.06]],"v":[[2.689,0.105],[3.072,-1.5],[-3.072,-1.5],[-2.689,0.105],[-2.652,0.239],[-0.875,1.5],[0.874,1.5],[1.018,1.495]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":50,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.976,0.855,0.478,0.5,0.955,0.796,0.371,1,0.933,0.737,0.263],"ix":9}},"s":{"a":0,"k":[0,-1.5],"ix":5},"e":{"a":0,"k":[0,1.5],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[0.129411771894,0.129411771894,0.129411771894,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[1000,1000],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}} \ No newline at end of file diff --git a/Telegram/Telegram.csproj b/Telegram/Telegram.csproj index dcedc79e21..5ae5ec05c3 100644 --- a/Telegram/Telegram.csproj +++ b/Telegram/Telegram.csproj @@ -163,6 +163,7 @@ + diff --git a/Telegram/Views/SettingsPage.xaml b/Telegram/Views/SettingsPage.xaml index 58fafce616..8a7312a1e0 100644 --- a/Telegram/Views/SettingsPage.xaml +++ b/Telegram/Views/SettingsPage.xaml @@ -300,6 +300,13 @@ + + + + + diff --git a/Telegram/Views/SettingsPage.xaml.cs b/Telegram/Views/SettingsPage.xaml.cs index debccc03e9..48e6cbd630 100644 --- a/Telegram/Views/SettingsPage.xaml.cs +++ b/Telegram/Views/SettingsPage.xaml.cs @@ -148,6 +148,14 @@ private void PrivacyPolicy_Click(object sender, RoutedEventArgs e) ViewModel.NavigationService.NavigateToInstant(Strings.PrivacyPolicyUrl); } + private void Features_Click(object sender, RoutedEventArgs e) + { + if (Uri.TryCreate(Strings.TelegramFeaturesUrl, UriKind.Absolute, out Uri tipsUri)) + { + MessageHelper.OpenTelegramUrl(ViewModel.ClientService, ViewModel.NavigationService, tipsUri); + } + } + private void Premium_Click(object sender, RoutedEventArgs e) { ViewModel.NavigationService.ShowPromo(new PremiumSourceSettings()); From 0a814a491b924147cae85e9134f042a1548b91ff Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 12 Jan 2026 14:34:58 +0400 Subject: [PATCH 023/169] Prioritize link preview over reply --- Telegram/Views/ChatView.xaml.cs | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Telegram/Views/ChatView.xaml.cs b/Telegram/Views/ChatView.xaml.cs index 3b7e688839..19facc21fb 100644 --- a/Telegram/Views/ChatView.xaml.cs +++ b/Telegram/Views/ChatView.xaml.cs @@ -2710,29 +2710,7 @@ private void Reply_ContextRequested(UIElement sender, ContextRequestedEventArgs var flyout = new MenuFlyout(); var header = ViewModel.ComposerHeader; - if (header?.ReplyTo != null && header.ReplyTo.CanBeRepliedInAnotherChat && !ViewModel.IsDirectMessagesGroup) - { - if (header.ReplyTo.Quote != null) - { - var quote = new MessageQuote(header.ReplyTo); - - flyout.CreateFlyoutItem(ViewModel.QuoteToMessageInAnotherChat, quote, Strings.ReplyToAnotherChat, Icons.Replace); - } - else if (header.ReplyTo.ChecklistTaskId != 0) - { - var checklist = new MessageChecklistTask(header.ReplyTo); - - flyout.CreateFlyoutItem(ViewModel.ReplyToChecklistTaskInAnotherChat, checklist, Strings.ReplyToAnotherChat, Icons.Replace); - } - else - { - flyout.CreateFlyoutItem(ViewModel.ReplyToMessageInAnotherChat, header.ReplyTo.Message, Strings.ReplyToAnotherChat, Icons.Replace); - } - - flyout.CreateFlyoutSeparator(); - flyout.CreateFlyoutItem(ViewModel.ClearReply, Strings.DoNotReply, Icons.DismissCircle, destructive: true); - } - else if (header?.LinkPreview != null) + if (header?.LinkPreview != null) { static void ChangeShowAbove(MessageComposerHeader header) { @@ -2825,6 +2803,28 @@ void handler(object sender, RoutedEventArgs e) flyout.CreateFlyoutSeparator(); flyout.CreateFlyoutItem(ViewModel.ClearReply, Strings.DoNotLinkPreview, Icons.DismissCircle, destructive: true); } + else if (header?.ReplyTo != null && header.ReplyTo.CanBeRepliedInAnotherChat && !ViewModel.IsDirectMessagesGroup) + { + if (header.ReplyTo.Quote != null) + { + var quote = new MessageQuote(header.ReplyTo); + + flyout.CreateFlyoutItem(ViewModel.QuoteToMessageInAnotherChat, quote, Strings.ReplyToAnotherChat, Icons.Replace); + } + else if (header.ReplyTo.ChecklistTaskId != 0) + { + var checklist = new MessageChecklistTask(header.ReplyTo); + + flyout.CreateFlyoutItem(ViewModel.ReplyToChecklistTaskInAnotherChat, checklist, Strings.ReplyToAnotherChat, Icons.Replace); + } + else + { + flyout.CreateFlyoutItem(ViewModel.ReplyToMessageInAnotherChat, header.ReplyTo.Message, Strings.ReplyToAnotherChat, Icons.Replace); + } + + flyout.CreateFlyoutSeparator(); + flyout.CreateFlyoutItem(ViewModel.ClearReply, Strings.DoNotReply, Icons.DismissCircle, destructive: true); + } flyout.ShowAt(sender, args); } From a70aa9ee886fbbcaf3922911bb6b4ae70ba31df6 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 12 Jan 2026 14:38:36 +0400 Subject: [PATCH 024/169] Fix CanInviteUsers --- Telegram/Controls/ProfileHeader.xaml.cs | 2 +- Telegram/Services/ClientService.cs | 4 ++-- Telegram/Td/Api/TdExtensions.cs | 22 +++++++++---------- .../ViewModels/Folders/FolderViewModel.cs | 4 ++-- .../Folders/ShareFolderViewModel.cs | 4 ++-- .../Views/Popups/ChooseChatsPopup.xaml.cs | 2 +- .../Profile/ProfileMembersTabPage.xaml.cs | 4 ++-- .../Supergroups/SupergroupEditPage.xaml.cs | 4 ++-- .../Supergroups/SupergroupMembersPage.xaml.cs | 4 ++-- 9 files changed, 24 insertions(+), 26 deletions(-) diff --git a/Telegram/Controls/ProfileHeader.xaml.cs b/Telegram/Controls/ProfileHeader.xaml.cs index 6f40e6c5dd..b9a289ab81 100644 --- a/Telegram/Controls/ProfileHeader.xaml.cs +++ b/Telegram/Controls/ProfileHeader.xaml.cs @@ -1612,7 +1612,7 @@ void AddToggle(int value, int? parameter, string text, string icon) { //flyout.CreateFlyoutItem(ViewModel.EditCommand, Strings.ManageChannelMenu, Icons.Edit); } - else if (chat.Permissions.CanInviteUsers || supergroup.CanInviteUsers()) + else if (supergroup.CanInviteUsers(chat)) { flyout.CreateFlyoutItem(ViewModel.Invite, Strings.AddMember, Icons.PersonAdd); } diff --git a/Telegram/Services/ClientService.cs b/Telegram/Services/ClientService.cs index dd56c67c9c..34bf64a919 100644 --- a/Telegram/Services/ClientService.cs +++ b/Telegram/Services/ClientService.cs @@ -2048,11 +2048,11 @@ public bool CanInviteUsers(Chat chat) { if (TryGetSupergroup(chat, out Supergroup supergroup)) { - return supergroup.CanInviteUsers(); + return supergroup.CanInviteUsers(chat); } else if (TryGetBasicGroup(chat, out BasicGroup basicGroup)) { - return basicGroup.CanInviteUsers(); + return basicGroup.CanInviteUsers(chat); } // TODO: secret chats maybe? diff --git a/Telegram/Td/Api/TdExtensions.cs b/Telegram/Td/Api/TdExtensions.cs index a3a2a19a75..83f12771bd 100644 --- a/Telegram/Td/Api/TdExtensions.cs +++ b/Telegram/Td/Api/TdExtensions.cs @@ -3928,7 +3928,7 @@ public static bool CanPromoteMembers(this BasicGroup basicGroup) return basicGroup.Status is ChatMemberStatusCreator; } - public static bool CanInviteUsers(this Supergroup supergroup) + public static bool CanInviteUsers(this Supergroup supergroup, Chat chat) { if (supergroup.Status == null) { @@ -3939,26 +3939,24 @@ public static bool CanInviteUsers(this Supergroup supergroup) { return false; } - - //if (supergroup.AnyoneCanInvite && supergroup.Status is ChatMemberStatusMember) - //{ - // return true; - //} + else if (supergroup.Status is ChatMemberStatusMember) + { + return chat.Permissions.CanInviteUsers; + } return supergroup.Status is ChatMemberStatusCreator or ChatMemberStatusAdministrator { Rights.CanInviteUsers: true }; } - public static bool CanInviteUsers(this BasicGroup basicGroup) + public static bool CanInviteUsers(this BasicGroup basicGroup, Chat chat) { if (basicGroup.Status == null) { return false; } - - //if (basicGroup.EveryoneIsAdministrator) - //{ - // return true; - //} + else if (basicGroup.Status is ChatMemberStatusMember) + { + return chat.Permissions.CanInviteUsers; + } return basicGroup.Status is ChatMemberStatusCreator or ChatMemberStatusAdministrator { Rights.CanInviteUsers: true }; } diff --git a/Telegram/ViewModels/Folders/FolderViewModel.cs b/Telegram/ViewModels/Folders/FolderViewModel.cs index 7350b23db4..f40b62b6d7 100644 --- a/Telegram/ViewModels/Folders/FolderViewModel.cs +++ b/Telegram/ViewModels/Folders/FolderViewModel.cs @@ -571,7 +571,7 @@ public async void CreateLink() } else if (ClientService.TryGetSupergroup(chat, out Supergroup supergroup)) { - if (supergroup.CanInviteUsers()) + if (supergroup.CanInviteUsers(chat)) { continue; } @@ -582,7 +582,7 @@ public async void CreateLink() } else if (ClientService.TryGetBasicGroup(chat, out BasicGroup basicGroup)) { - if (basicGroup.CanInviteUsers()) + if (basicGroup.CanInviteUsers(chat)) { continue; } diff --git a/Telegram/ViewModels/Folders/ShareFolderViewModel.cs b/Telegram/ViewModels/Folders/ShareFolderViewModel.cs index 514e081ff9..6e9e6f98df 100644 --- a/Telegram/ViewModels/Folders/ShareFolderViewModel.cs +++ b/Telegram/ViewModels/Folders/ShareFolderViewModel.cs @@ -66,7 +66,7 @@ protected override async Task OnNavigatedToAsync(object parameter, NavigationMod { if (ClientService.TryGetSupergroup(chat, out Supergroup supergroup)) { - if (supergroup.CanInviteUsers()) + if (supergroup.CanInviteUsers(chat)) { continue; } @@ -77,7 +77,7 @@ protected override async Task OnNavigatedToAsync(object parameter, NavigationMod } else if (ClientService.TryGetBasicGroup(chat, out BasicGroup basicGroup)) { - if (basicGroup.CanInviteUsers()) + if (basicGroup.CanInviteUsers(chat)) { continue; } diff --git a/Telegram/Views/Popups/ChooseChatsPopup.xaml.cs b/Telegram/Views/Popups/ChooseChatsPopup.xaml.cs index 03510b07d2..ba5d7a066a 100644 --- a/Telegram/Views/Popups/ChooseChatsPopup.xaml.cs +++ b/Telegram/Views/Popups/ChooseChatsPopup.xaml.cs @@ -291,7 +291,7 @@ public virtual bool Allow(IClientService clientService, Chat chat) } else if (CanInviteUsers) { - return super.CanInviteUsers(); + return super.CanInviteUsers(chat); } else if (CanPromoteMembers) { diff --git a/Telegram/Views/Profile/ProfileMembersTabPage.xaml.cs b/Telegram/Views/Profile/ProfileMembersTabPage.xaml.cs index e086e79cca..f0f9263591 100644 --- a/Telegram/Views/Profile/ProfileMembersTabPage.xaml.cs +++ b/Telegram/Views/Profile/ProfileMembersTabPage.xaml.cs @@ -33,12 +33,12 @@ protected override void OnNavigatedTo(NavigationEventArgs e) if (ViewModel.ClientService.TryGetSupergroup(ViewModel.Chat, out Supergroup supergroup)) { AddNew.Content = supergroup.IsChannel ? Strings.AddSubscriber : Strings.AddMember; - AddNewPanel.Visibility = supergroup.CanInviteUsers() ? Visibility.Visible : Visibility.Collapsed; + AddNewPanel.Visibility = supergroup.CanInviteUsers(ViewModel.Chat) ? Visibility.Visible : Visibility.Collapsed; } else if (ViewModel.ClientService.TryGetBasicGroup(ViewModel.Chat, out BasicGroup basicGroup)) { AddNew.Content = Strings.AddMember; - AddNewPanel.Visibility = basicGroup.CanInviteUsers() ? Visibility.Visible : Visibility.Collapsed; + AddNewPanel.Visibility = basicGroup.CanInviteUsers(ViewModel.Chat) ? Visibility.Visible : Visibility.Collapsed; } } diff --git a/Telegram/Views/Supergroups/SupergroupEditPage.xaml.cs b/Telegram/Views/Supergroups/SupergroupEditPage.xaml.cs index 7b4aab62a2..17abc3e8da 100644 --- a/Telegram/Views/Supergroups/SupergroupEditPage.xaml.cs +++ b/Telegram/Views/Supergroups/SupergroupEditPage.xaml.cs @@ -173,7 +173,7 @@ public void UpdateSupergroup(Chat chat, Supergroup group, SupergroupFullInfo ful ViewModel.HasAutomaticTranslation = group.HasAutomaticTranslation; var canChangeInfo = group.CanChangeInfo(chat); - var canInviteUsers = group.CanInviteUsers(); + var canInviteUsers = group.CanInviteUsers(chat); var canRestrictMembers = group.CanRestrictMembers(); var canPostMessages = group.CanPostMessages(); var hasActiveUsername = group.HasActiveUsername(); @@ -286,7 +286,7 @@ public void UpdateBasicGroup(Chat chat, BasicGroup group, BasicGroupFullInfo ful ViewModel.IsAllHistoryAvailable = 1; var canChangeInfo = group.CanChangeInfo(chat); - var canInviteUsers = group.CanInviteUsers(); + var canInviteUsers = group.CanInviteUsers(chat); TitleLabel.IsReadOnly = !canChangeInfo; About.IsReadOnly = !canChangeInfo; diff --git a/Telegram/Views/Supergroups/SupergroupMembersPage.xaml.cs b/Telegram/Views/Supergroups/SupergroupMembersPage.xaml.cs index c944ac7c70..69c66bca00 100644 --- a/Telegram/Views/Supergroups/SupergroupMembersPage.xaml.cs +++ b/Telegram/Views/Supergroups/SupergroupMembersPage.xaml.cs @@ -186,7 +186,7 @@ public void UpdateSupergroup(Chat chat, Supergroup group, SupergroupFullInfo ful Title = group.IsChannel ? Strings.ChannelSubscribers : Strings.ChannelMembers; AddNew.Content = group.IsChannel ? Strings.AddSubscriber : Strings.AddMember; - AddNewPanel.Visibility = group.CanInviteUsers() ? Visibility.Visible : Visibility.Collapsed; + AddNewPanel.Visibility = group.CanInviteUsers(chat) ? Visibility.Visible : Visibility.Collapsed; Footer.Visibility = group.IsChannel ? Visibility.Visible : Visibility.Collapsed; } @@ -204,7 +204,7 @@ public void UpdateBasicGroup(Chat chat, BasicGroup group, BasicGroupFullInfo ful } AddNew.Content = Strings.AddMember; - AddNewPanel.Visibility = group.CanInviteUsers() ? Visibility.Visible : Visibility.Collapsed; + AddNewPanel.Visibility = group.CanInviteUsers(chat) ? Visibility.Visible : Visibility.Collapsed; Footer.Visibility = Visibility.Collapsed; } From 25955acca3ff913fddfaff76656c4dc163029375 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 12 Jan 2026 16:42:25 +0400 Subject: [PATCH 025/169] Directly open google maps when clicking on locations --- Telegram/Controls/ProfileHeader.xaml.cs | 5 +---- Telegram/Controls/Stories/StoryContent.xaml.cs | 5 +---- Telegram/ViewModels/MessageDelegate.cs | 9 +++------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Telegram/Controls/ProfileHeader.xaml.cs b/Telegram/Controls/ProfileHeader.xaml.cs index b9a289ab81..4e0aa4bdd7 100644 --- a/Telegram/Controls/ProfileHeader.xaml.cs +++ b/Telegram/Controls/ProfileHeader.xaml.cs @@ -2145,10 +2145,7 @@ private void Location_Click(object sender, RoutedEventArgs e) { try { - var options = new Windows.System.LauncherOptions(); - options.FallbackUri = new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude)); - - _ = Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "bingmaps:?collection=point.{0}_{1}", location.Latitude, location.Longitude)), options); + _ = Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude))); } catch { diff --git a/Telegram/Controls/Stories/StoryContent.xaml.cs b/Telegram/Controls/Stories/StoryContent.xaml.cs index 486a816e56..b0fb729c2f 100644 --- a/Telegram/Controls/Stories/StoryContent.xaml.cs +++ b/Telegram/Controls/Stories/StoryContent.xaml.cs @@ -660,10 +660,7 @@ private async void Area_Click(object sender, RoutedEventArgs e) _ => null }; - var options = new Windows.System.LauncherOptions(); - options.FallbackUri = new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude)); - - await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "bingmaps:?collection=point.{0}_{1}", location.Latitude, location.Longitude)), options); + await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude))); } catch { diff --git a/Telegram/ViewModels/MessageDelegate.cs b/Telegram/ViewModels/MessageDelegate.cs index a79f3b670e..56e1755247 100644 --- a/Telegram/ViewModels/MessageDelegate.cs +++ b/Telegram/ViewModels/MessageDelegate.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Net; using Telegram.Common; using Telegram.Controls; using Telegram.Navigation; @@ -340,16 +339,14 @@ public async void OpenLocation(Location location, string title) { try { - var options = new Windows.System.LauncherOptions(); - options.FallbackUri = new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude)); - if (title != null) { - await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "bingmaps:?collection=point.{0}_{1}_{2}", location.Latitude, location.Longitude, WebUtility.UrlEncode(title))), options); + // TODO: is title supported? + await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude))); } else { - await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "bingmaps:?collection=point.{0}_{1}", location.Latitude, location.Longitude)), options); + await Windows.System.Launcher.LaunchUriAsync(new Uri(string.Format(CultureInfo.InvariantCulture, "https://www.google.com/maps/search/?api=1&query={0},{1}", location.Latitude, location.Longitude))); } } catch From af58693e4662b4e8837ccd3fdd5ae6ef77962a65 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 12 Jan 2026 17:37:09 +0400 Subject: [PATCH 026/169] Fix tinted night modals --- Telegram/Services/ThemeService.Defaults.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/Services/ThemeService.Defaults.cs b/Telegram/Services/ThemeService.Defaults.cs index 5e15b1adf0..725a3208e9 100644 --- a/Telegram/Services/ThemeService.Defaults.cs +++ b/Telegram/Services/ThemeService.Defaults.cs @@ -68,8 +68,8 @@ public partial class ThemeInfoBase { "ApplicationPageBackgroundThemeBrush", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, { "PageHeaderBackgroundBrush", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, { "PageSubHeaderBackgroundBrush", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, - { "ContentDialogBackground", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, - { "ContentDialogTopOverlaySolid", Color.FromArgb(0xFF, 0x2B, 0x2B, 0x2B) }, + { "ContentDialogBackground", Color.FromArgb(0xFF, 0x17, 0x1B, 0x21) }, + { "ContentDialogTopOverlaySolid", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, { "SolidBackgroundFillColorBaseBrush", Color.FromArgb(0xFF, 0x1C, 0x27, 0x33) }, { "TelegramSeparatorMediumBrush", Color.FromArgb(0xFF, 0x10, 0x17, 0x1E) }, { "SystemControlDisabledChromeDisabledLowBrush", Color.FromArgb(0xFF, 0x7D, 0x8E, 0x98) }, From 42c8002f8068e50676e379e1550264555f1c5928 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:19:23 +0400 Subject: [PATCH 027/169] Fix edit profile photo --- Telegram/Services/ProfilePhotoService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Services/ProfilePhotoService.cs b/Telegram/Services/ProfilePhotoService.cs index 0cfbb0810c..7cc1f9e230 100644 --- a/Telegram/Services/ProfilePhotoService.cs +++ b/Telegram/Services/ProfilePhotoService.cs @@ -143,7 +143,7 @@ private async Task EditPhotoAsync(INavigationService navigation, } else if (file is StoragePhoto photo) { - var serialized = JsonSerializer.Serialize(photo.EditState, GenerationJsonContext.Default.VideoGeneration); + var serialized = JsonSerializer.Serialize(photo.EditState, GenerationJsonContext.Default.ImageGeneration); var generated = await photo.File.ToGeneratedAsync(ConversionType.Compress, serialized); inputPhoto = new InputChatPhotoStatic(generated); } From b938cf0f1957b512bf83b1768e6f12b4f015763a Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:19:33 +0400 Subject: [PATCH 028/169] Update tgcalls --- Libraries/tgcalls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/tgcalls b/Libraries/tgcalls index c89f009c29..24876ebca7 160000 --- a/Libraries/tgcalls +++ b/Libraries/tgcalls @@ -1 +1 @@ -Subproject commit c89f009c29e7142f1935383a978f2ad7c46da4d1 +Subproject commit 24876ebca7da10f92dc972225734337f9e793054 From d74042e8a9fbd63d46358eee5a41f299e87a2b5f Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:19:47 +0400 Subject: [PATCH 029/169] Update exception serialization --- Telegram/Common/ExceptionSerializer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Telegram/Common/ExceptionSerializer.cs b/Telegram/Common/ExceptionSerializer.cs index bfe0d5ecf6..09be90e951 100644 --- a/Telegram/Common/ExceptionSerializer.cs +++ b/Telegram/Common/ExceptionSerializer.cs @@ -460,10 +460,10 @@ private static int GetImageSize(IntPtr imageBase) "RLottie", "swresample-5", "swscale-8", + "tdjson", "Telegram", "Telegram.Native.Calls", "Telegram.Native", - "Telegram.Td", "WebView2Loader", "zlib1", }; @@ -556,6 +556,7 @@ private static string TranslateText(string text) case "L’instance de périphérique GPU a été suspendue. Utilisez GetDeviceRemovedReason pour déterminer l’action appropriée.": case "La instancia de dispositivo de GPU se ha suspendido. Use GetDeviceRemovedReason para averiguar cuál es la acción adecuada.": + case "Istanza del dispositivo GPU sospesa. Utilizzare GetDeviceRemovedReason per determinare l'azione appropriata.": case "Die GPU-Geräteinstanz wurde angehalten. Verwenden Sie GetDeviceRemovedReason, um die erforderliche Aktion zu bestimmen.": case "GPU aygıt örneği askıya alınmış. Uygun eylemi belirlemek için GetDeviceRemovedReason komutunu kullanın.": case "Wystąpienie urządzenia GPU zostało zawieszone. Użyj obiektu GetDeviceRemovedReason, aby określić odpowiednią akcję.": @@ -708,6 +709,7 @@ private static string TranslateText(string text) case "O filtro de mensagens indicou que o aplicativo está ocupado.": case "El filtro de mensaje indicó que la aplicación está ocupada.": case "Het berichtenfilter heeft aangegeven dat de toepassing bezet is.": + case "Filtr wiadomości wykazał, że aplikacja jest zajęta.": case "Il filtro messaggi ha indicato che l'applicazione è impegnata.": case "İleti filtresi uygulamanın kullanımda olduğunu belirledi.": case "Фильтр сообщений выдал диагностику о занятости приложения.": @@ -733,9 +735,11 @@ private static string TranslateText(string text) return "An event was unable to invoke any of the subscribers"; case "Le package n'a pas de répertoire mutable.": + case "Das Paket hat kein variables Verzeichnis.": case "Пакет не имеет изменяемого каталога.": return "The package does not have a mutable directory."; + case "Risorsa realizzata sulla destinazione di rendering errata.": case "Die Ressource wurde auf dem falschen Renderziel erkannt.": case "Kaynak yanlış işleme hedefinde gerçekleştirildi.": return "The resource was realized on the wrong render target."; From 19531ae9b730dd489dda525275dd2ce491421f8c Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:20:18 +0400 Subject: [PATCH 030/169] Improve UpdateLayoutAsync --- Telegram/Common/Extensions.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Telegram/Common/Extensions.cs b/Telegram/Common/Extensions.cs index 2dd49145bb..e8d14e5672 100644 --- a/Telegram/Common/Extensions.cs +++ b/Telegram/Common/Extensions.cs @@ -1768,17 +1768,19 @@ public static Task UpdateLayoutAsync(this FrameworkElement element, Cancellation } var tcs = new TaskCompletionSource(); - void layoutUpdated(object s1, object e1) + var registration = token.Register(() => { element.LayoutUpdated -= layoutUpdated; - tcs.TrySetResult(true); - } + tcs.TrySetResult(false); + }); - token.Register(() => + void layoutUpdated(object s1, object e1) { element.LayoutUpdated -= layoutUpdated; - tcs.TrySetCanceled(); - }); + tcs.TrySetResult(true); + + registration.Dispose(); + } element.LayoutUpdated += layoutUpdated; return tcs.Task; From 0947041d501f42b3baa70f16afeeb91ce37ec911 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:20:34 +0400 Subject: [PATCH 031/169] Improve custom font replacement chain --- Telegram/Common/Theme.cs | 49 ++++++++++------------------------------ 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/Telegram/Common/Theme.cs b/Telegram/Common/Theme.cs index 1f9db14c0c..7f917f58b9 100644 --- a/Telegram/Common/Theme.cs +++ b/Telegram/Common/Theme.cs @@ -70,55 +70,30 @@ public void UpdateEmojiSet() xamlAutoFontFamilyValue = "Segoe UI"; } - //if (false) - //{ - // foreach (var language in Formatter.Languages) - // { - // // We copy XAML behavior, only resolve for Japanese and Korean - // if (language == "ja" || language == "ko" || language == "ja-JP" || language == "ko-KR") - // { - // try - // { - // var recommendedFonts = new LanguageFontGroup(language); - // var family = recommendedFonts.UITextFont.FontFamily; - - // xamlAutoFontFamily.Prepend(family, comma); - // } - // catch - // { - // // All the remote procedure calls must be wrapped in a try-catch block - // } - // } - // } - - // xamlAutoFontFamily.Prepend("Segoe UI", comma); - //} - - switch (SettingsService.Current.Appearance.EmojiSet) - { - case "microsoft": - XamlAutoFontFamily = "ms-appx:///Assets/Emoji/microsoft.ttf#Segoe UI Emoji"; - break; - default: - XamlAutoFontFamily = "ms-appx:///Assets/Emoji/apple.ttf#Segoe UI Emoji"; - break; - } + var emojiFontFamily = SettingsService.Current.Appearance.EmojiSet switch + { + "microsoft" => "ms-appx:///Assets/Emoji/microsoft.ttf#Segoe UI Emoji", + _ => "ms-appx:///Assets/Emoji/apple.ttf#Segoe UI Emoji", + }; + + // When using custom fonts we prioritize the user choice over emojis. + // This will break all keycaps emojis, but preserves if (xamlAutoFontFamilyDefault) { - this["EmojiTextThemeFontFamily"] = new FontFamily(XamlAutoFontFamily + comma + xamlAutoFontFamilyValue); + XamlAutoFontFamily = emojiFontFamily; + this["EmojiTextThemeFontFamily"] = new FontFamily(emojiFontFamily + comma + xamlAutoFontFamilyValue); } else { - XamlAutoFontFamily += comma + xamlAutoFontFamilyValue; - this["EmojiTextThemeFontFamily"] = new FontFamily(XamlAutoFontFamily + comma + xamlAutoFontFamilyValue); + XamlAutoFontFamily = xamlAutoFontFamilyValue + comma + emojiFontFamily; + this["EmojiTextThemeFontFamily"] = new FontFamily(xamlAutoFontFamilyValue + comma + emojiFontFamily); } this["ContentControlThemeFontFamily"] = new FontFamily(XamlAutoFontFamily); this["EmojiThemeFontFamily"] = new FontFamily(XamlAutoFontFamily); this["EmojiThemeFontFamilyWithSymbols"] = new FontFamily(XamlAutoFontFamily + comma + "ms-appx:///Assets/Fonts/Telegram.ttf#Telegram"); this["EmojiThemeFontFamilyWithRounded"] = new FontFamily(XamlAutoFontFamily + comma + "ms-appx:///Assets/Fonts/Nunito.ttf#Nunito" + comma + "ms-appx:///Assets/Fonts/Telegram.ttf#Telegram"); - this["EmojiTextThemeFontFamily"] = new FontFamily(XamlAutoFontFamily + comma + xamlAutoFontFamilyValue); } public string XamlAutoFontFamily { get; private set; } From 7c8131efb21842b4f64465554ebcde14f87e85c7 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:21:04 +0400 Subject: [PATCH 032/169] Fix gallery hot keys when forward is open --- .../Controls/Gallery/GalleryWindow.xaml.cs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/Telegram/Controls/Gallery/GalleryWindow.xaml.cs b/Telegram/Controls/Gallery/GalleryWindow.xaml.cs index a00164549e..f754b4a2ad 100644 --- a/Telegram/Controls/Gallery/GalleryWindow.xaml.cs +++ b/Telegram/Controls/Gallery/GalleryWindow.xaml.cs @@ -826,6 +826,12 @@ private void Unload() private void OnPreviewKeyDown(object sender, KeyRoutedEventArgs args) { + var focused = FocusManagerEx.TryGetFocusedElement(); + if (focused is Slider or TextBox or RichEditBox) + { + return; + } + var modifiers = WindowContext.KeyModifiers(); var keyCode = (int)args.Key; @@ -836,29 +842,11 @@ private void OnPreviewKeyDown(object sender, KeyRoutedEventArgs args) } else if (args.Key is VirtualKey.Left or VirtualKey.GamepadLeftShoulder && modifiers == VirtualKeyModifiers.None) { - if (args.Key == VirtualKey.Left) - { - var focused = FocusManagerEx.TryGetFocusedElement(); - if (focused is Slider) - { - return; - } - } - ChangeView(CarouselDirection.Previous); args.Handled = true; } else if (args.Key is VirtualKey.Right or VirtualKey.GamepadRightShoulder && modifiers == VirtualKeyModifiers.None) { - if (args.Key == VirtualKey.Right) - { - var focused = FocusManagerEx.TryGetFocusedElement(); - if (focused is Slider) - { - return; - } - } - ChangeView(CarouselDirection.Next); args.Handled = true; } From 1fadc4fdd64a5b9456cd48e3adf2adf95afbdcf1 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:22:34 +0400 Subject: [PATCH 033/169] Stake dice improvements --- Telegram/Controls/Cells/ChatCell.xaml.cs | 2 + Telegram/Controls/DiceView.cs | 4 ++ .../Messages/Content/StakeDiceContent.xaml.cs | 66 ++++++++++++++++++- Telegram/Controls/ToastPopup.cs | 55 ++++++++++++++++ Telegram/Views/Popups/StakeDicePopup.xaml | 55 ++++++++++++++-- Telegram/Views/Popups/StakeDicePopup.xaml.cs | 7 ++ 6 files changed, 183 insertions(+), 6 deletions(-) diff --git a/Telegram/Controls/Cells/ChatCell.xaml.cs b/Telegram/Controls/Cells/ChatCell.xaml.cs index 03a84a6314..81962f0bbf 100644 --- a/Telegram/Controls/Cells/ChatCell.xaml.cs +++ b/Telegram/Controls/Cells/ChatCell.xaml.cs @@ -1745,6 +1745,8 @@ static FormattedText Text1(string text, FormattedText formatted, string fallback return text.Text; case MessageDice dice: return dice.Emoji.AsFormattedText(); + case MessageStakeDice dice: + return Constants.StakeDice.AsFormattedText(); default: return string.Empty.AsFormattedText(); } diff --git a/Telegram/Controls/DiceView.cs b/Telegram/Controls/DiceView.cs index 101ead5e61..1df60008f6 100644 --- a/Telegram/Controls/DiceView.cs +++ b/Telegram/Controls/DiceView.cs @@ -313,6 +313,8 @@ public void Invalidate() } else if (i == 1) { + Completed?.Invoke(this, null); + lock (_subscribeLock) { _subscribed = false; @@ -626,6 +628,8 @@ public bool IsContentUnread public event EventHandler IndexChanged; + public event EventHandler Completed; + public event EventHandler FirstFrameRendered; public int LoopCount => IsLoopingEnabled ? 0 : 1; diff --git a/Telegram/Controls/Messages/Content/StakeDiceContent.xaml.cs b/Telegram/Controls/Messages/Content/StakeDiceContent.xaml.cs index 13a06789c6..0861bde4a6 100644 --- a/Telegram/Controls/Messages/Content/StakeDiceContent.xaml.cs +++ b/Telegram/Controls/Messages/Content/StakeDiceContent.xaml.cs @@ -6,7 +6,9 @@ // using System; +using System.Threading; using Telegram.Common; +using Telegram.Navigation; using Telegram.Td.Api; using Telegram.ViewModels; using Telegram.Views.Popups; @@ -14,6 +16,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Media; namespace Telegram.Controls.Messages.Content { @@ -48,6 +51,7 @@ protected override void OnApplyTemplate() Player = GetTemplateChild(nameof(Player)) as DiceView; Player.FirstFrameRendered += Player_FirstFrameRendered; + Player.Completed += Player_Completed; _templateApplied = true; @@ -162,6 +166,20 @@ private void Player_FirstFrameRendered(object sender, EventArgs e) ElementCompositionPreview.SetElementChildVisual(Player, null); } + private void Player_Completed(object sender, EventArgs e) + { + if (_message?.Content is MessageStakeDice) + { + _message.GeneratedContentUnread = false; + + this.BeginOnUIThread(() => + { + var selector = this.GetParent(); + selector?.UpdateMessageStakeDice(_message); + }); + } + } + private void DownloadFile(MessageViewModel message, DiceStickers stickers) { if (stickers is DiceStickersRegular regular) @@ -233,7 +251,53 @@ private async void Button_Click(object sender, RoutedEventArgs e) await _message.ClientService.SendAsync(new GetStakeDiceState()); - _message.Delegate.NavigationService.ShowPopup(new StakeDicePopup(_message)); + using var cancellationToken = new CancellationTokenSource(); + var label = new TextBlock + { + TextWrapping = TextWrapping.Wrap, + FontFamily = BootStrapper.Current.Resources["EmojiThemeFontFamilyWithSymbols"] as FontFamily + }; + + TextBlockHelper.SetMarkdown(label, Strings.StakeDiceToast + (_message.ClientService.StakeDiceState.StakeToncoinAmount / Constants.ToncoinMin).ToString("0.#")); + + var button = new SettingsButton + { + Style = BootStrapper.Current.Resources["SmallButtonStyle"] as Style, + Glyph = Strings.Change.ToLower(), + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Bottom, + FontSize = 11, + Padding = new Thickness(8, 0, 8, 0), + Margin = new Thickness(8, 0, 0, 2), + CornerRadius = new CornerRadius(8), + BorderThickness = new Thickness(0), + Height = 16 + }; + + void handler(object _, RoutedEventArgs args) + { + _message.Delegate.NavigationService.ShowPopup(new StakeDicePopup(_message)); + button.Click -= handler; + cancellationToken.Cancel(); + } + + button.Click += handler; + + var grid = new Grid(); + grid.Children.Add(label); + grid.Children.Add(button); + grid.ColumnDefinitions.Add(new ColumnDefinition()); + grid.ColumnDefinitions.Add(new ColumnDefinition()); + grid.VerticalAlignment = VerticalAlignment.Center; + + Grid.SetColumn(button, 1); + + var confirm = await ToastPopup.ShowActionAsync(XamlRoot, grid, Strings.StakeDiceButton, null, Microsoft.UI.Xaml.Controls.TeachingTipPlacementMode.Center, cancellationToken: cancellationToken.Token); + if (confirm == ContentDialogResult.Primary) + { + _message.Delegate.SendMessage(new InputMessageStakeDice(_message.ClientService.StakeDiceState.StateHash, _message.ClientService.StakeDiceState.StakeToncoinAmount, false)); + } + return; //string text; diff --git a/Telegram/Controls/ToastPopup.cs b/Telegram/Controls/ToastPopup.cs index fc47872344..3fe5235e3e 100644 --- a/Telegram/Controls/ToastPopup.cs +++ b/Telegram/Controls/ToastPopup.cs @@ -7,6 +7,7 @@ using Microsoft.UI.Xaml.Controls; using System; +using System.Threading; using System.Threading.Tasks; using Telegram.Common; using Telegram.Controls.Messages; @@ -511,6 +512,60 @@ void closed(TeachingTip sender, TeachingTipClosedEventArgs e) return Task.FromResult(ContentDialogResult.None); } + public static Task ShowActionAsync(XamlRoot xamlRoot, FrameworkElement text, string action, FrameworkElement icon, TeachingTipPlacementMode placement, ElementTheme requestedTheme = ElementTheme.Dark, TimeSpan? dismissAfter = null, CancellationToken cancellationToken = default) + { + var toast = ShowImpl(xamlRoot, text, icon, placement, requestedTheme, dismissAfter); + if (toast?.Content is Grid content) + { + toast.MaxWidth = 500; + + if (cancellationToken != default) + { + cancellationToken.Register(() => + { + toast.IsOpen = false; + }); + } + + var tsc = new TaskCompletionSource(); + var undo = new Button() + { + Content = action, + FontWeight = FontWeights.SemiBold, + VerticalAlignment = VerticalAlignment.Center, + Style = BootStrapper.Current.Resources["AccentTextButtonStyle"] as Style, + Margin = new Thickness(8, -4, -4, -4), + Padding = new Thickness(4, 5, 4, 6) + }; + + void handler(object sender, RoutedEventArgs e) + { + Logger.Info("closed"); + + tsc.TrySetResult(ContentDialogResult.Primary); + undo.Click -= handler; + + toast.IsOpen = false; + } + + void closed(TeachingTip sender, TeachingTipClosedEventArgs e) + { + tsc.TrySetResult(ContentDialogResult.None); + sender.Closed -= closed; + } + + undo.Click += handler; + toast.Closed += closed; + + Grid.SetColumn(undo, 2); + content.Children.Add(undo); + + return tsc.Task; + } + + return Task.FromResult(ContentDialogResult.None); + } + public static Task ShowCountdownAsync(XamlRoot xamlRoot, string text, string action, TimeSpan dismissAfter, ElementTheme requestedTheme = ElementTheme.Dark) { return ShowCountdownAsync(xamlRoot, ClientEx.ParseMarkdown(text), action, dismissAfter, TeachingTipPlacementMode.Center, requestedTheme); diff --git a/Telegram/Views/Popups/StakeDicePopup.xaml b/Telegram/Views/Popups/StakeDicePopup.xaml index d6035f487c..f291dc16cf 100644 --- a/Telegram/Views/Popups/StakeDicePopup.xaml +++ b/Telegram/Views/Popups/StakeDicePopup.xaml @@ -534,11 +534,56 @@ - + + + + + + + + + + + + + + + + + + + + + Date: Fri, 16 Jan 2026 17:22:43 +0400 Subject: [PATCH 034/169] Unreference removed files --- Telegram.Native.Calls/Telegram.Native.Calls.vcxproj | 8 -------- .../Telegram.Native.Calls.vcxproj.filters | 12 ------------ 2 files changed, 20 deletions(-) diff --git a/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj b/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj index ef89b9ca0f..0991453b13 100644 --- a/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj +++ b/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj @@ -169,7 +169,6 @@ - @@ -180,7 +179,6 @@ - BroadcastTimeRequestedEventArgs.idl @@ -328,9 +326,6 @@ NotUsing - - NotUsing - NotUsing @@ -358,9 +353,6 @@ NotUsing - - NotUsing - NotUsing diff --git a/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj.filters b/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj.filters index fa0b1e9f08..a21542d4db 100644 --- a/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj.filters +++ b/Telegram.Native.Calls/Telegram.Native.Calls.vcxproj.filters @@ -177,15 +177,9 @@ - - tgcalls\v2 - tgcalls\v2 - - tgcalls\v2 - @@ -407,15 +401,9 @@ - - tgcalls\v2 - tgcalls\v2 - - tgcalls\v2 - From 68dd69b47b6fcb31f9f36ae9c8095f89680d7dc9 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:22:59 +0400 Subject: [PATCH 035/169] Fix generated documentation --- Telegram.Generators/SchemaGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram.Generators/SchemaGenerator.cs b/Telegram.Generators/SchemaGenerator.cs index 58e14fcbf9..0b18e064e3 100644 --- a/Telegram.Generators/SchemaGenerator.cs +++ b/Telegram.Generators/SchemaGenerator.cs @@ -957,7 +957,7 @@ public bool Read() var temp = _index + 1; while (temp < _lines.Length && _lines[temp].StartsWith("//")) { - Value += " " + _lines[temp].Substring(2); + Value += " " + _lines[temp].Substring(2).TrimStart('-'); temp++; } From 18125f7f75fa59054fc43cfc577b74e0ad57eb5b Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:53:14 +0400 Subject: [PATCH 036/169] Improve stories expand/collapse animation --- Telegram/Controls/Stories/StoriesStrip.xaml | 9 ++ .../Controls/Stories/StoriesStrip.xaml.cs | 52 ++++++- Telegram/Views/MainPage.xaml | 142 +++++++++--------- Telegram/Views/MainPage.xaml.cs | 9 +- 4 files changed, 136 insertions(+), 76 deletions(-) diff --git a/Telegram/Controls/Stories/StoriesStrip.xaml b/Telegram/Controls/Stories/StoriesStrip.xaml index 8ff64b559f..4f324e7b03 100644 --- a/Telegram/Controls/Stories/StoriesStrip.xaml +++ b/Telegram/Controls/Stories/StoriesStrip.xaml @@ -54,5 +54,14 @@ CornerRadius="16" VerticalAlignment="Top" HorizontalAlignment="Left" /> + + diff --git a/Telegram/Controls/Stories/StoriesStrip.xaml.cs b/Telegram/Controls/Stories/StoriesStrip.xaml.cs index a5b1b66395..4e2f0d5a29 100644 --- a/Telegram/Controls/Stories/StoriesStrip.xaml.cs +++ b/Telegram/Controls/Stories/StoriesStrip.xaml.cs @@ -9,9 +9,12 @@ using System.Collections.Specialized; using System.Numerics; using Telegram.Common; +using Telegram.Composition; using Telegram.Controls.Cells; using Telegram.Controls.Media; +using Telegram.Controls.Messages; using Telegram.Td.Api; +using Telegram.ViewModels.Drawers; using Telegram.ViewModels.Stories; using Telegram.Views.Stories.Popups; using Windows.Foundation; @@ -111,10 +114,20 @@ private void UpdateIndexes() Show.Width = count * 12 + 12 + 8; Show.Margin = new Thickness(_first > 0 ? 26 : 14, 20, 0, 0); Show.Visibility = Visibility.Visible; + + Icon.Margin = new Thickness(Show.Width + Show.Margin.Left + 8, 20, 0, 0); + Icon.Visibility = Visibility.Visible; + + TitleBarrr?.Margin = new Thickness(TitleBarrr.Margin.Left, 40, TitleBarrr.Margin.Right, -40); + TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset + (count * 12 + 12 + 8) : 80 + (count * 12 + 12 + 8), 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 80, 0); } else { Show.Visibility = Visibility.Collapsed; + Icon.Visibility = Visibility.Collapsed; + + TitleBarrr?.Margin = new Thickness(TitleBarrr.Margin.Left, 0, TitleBarrr.Margin.Right, 0); + TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset : 80, 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 80, 0); } ScrollingHost.IsHitTestVisible = !_collapsed; @@ -347,6 +360,7 @@ public FrameworkElement ChatTabs } public FrameworkElement TitleBarrr { get; set; } + public Border TitleBarHandle { get; set; } public FrameworkElement Header { get; set; } private bool _tabsLeftCollapsed = true; @@ -371,6 +385,17 @@ public float SystemOverlayLeftInset } } + private float _systemOverlayRightInset; + public float SystemOverlayRightInset + { + get => _systemOverlayRightInset; + set + { + _systemOverlayRightInset = value; + UpdateIndexes(); + } + } + private void UpdatePadding() { _progress?.InsertBoolean("RightToLeft", _systemOverlayLeftInset > 0); @@ -487,8 +512,10 @@ private void SetControlledList(FrameworkElement value) ForEach(_progress, _progressAnimation); - var titleVisualOffsetAnimation = compositor.CreateExpressionAnimation( - "_.RightToLeft ? 0 : _.Visible && _.Count > 0 ? (24 + (12 * _.Count)) * (1 - _.Progress) : 0"); + var titleVisualOffsetAnimation = compositor.CreateExpressionAnimation("Vector3(_.RightToLeft ? 0 : _.Visible && _.Count > 0 ? 40 + (12 * _.Count) + (((72 * _.Count) - (40 + (12 * _.Count))) * _.Progress) : 0, 16, 0)"); + var titleVisualScaleAnimation = compositor.CreateExpressionAnimation("_.Visible && _.Count > 0 ? Vector3(Clamp(_.Progress < 0.5 ? 0.5 : 0.5 + (_.Progress - 0.5), 0.5, 1), Clamp(_.Progress < 0.5 ? 0.5 : 0.5 + (_.Progress - 0.5), 0.5, 1), 1) : Vector3(1, 1, 1)"); + var titleVisualOpacityAnimation = compositor.CreateExpressionAnimation("_.Visible && _.Count > 0 ? _.Progress < 0.5 ? 0 : (_.Progress - 0.5) * 2 : 1"); + var titleVisualOpacityInverseAnimation = compositor.CreateExpressionAnimation("Clamp(1 - _.Progress * 2, 0, 1)"); var storiesVisualOffsetAnimationX = compositor.CreateExpressionAnimation( "(_.Padding - _.First * 12) * (1 - _.Progress)"); @@ -500,6 +527,9 @@ private void SetControlledList(FrameworkElement value) "84 * _.Progress"); titleVisualOffsetAnimation.SetReferenceParameter("_", _progress); + titleVisualScaleAnimation.SetReferenceParameter("_", _progress); + titleVisualOpacityAnimation.SetReferenceParameter("_", _progress); + titleVisualOpacityInverseAnimation.SetReferenceParameter("_", _progress); storiesVisualOffsetAnimationX.SetReferenceParameter("_", _progress); storiesVisualOffsetAnimation.SetReferenceParameter("_", _progress); headerVisualOffsetAnimation.SetReferenceParameter("_", _progress); @@ -508,6 +538,11 @@ private void SetControlledList(FrameworkElement value) var storiesVisual = ElementComposition.GetElementVisual(this); var headerVisual = ElementComposition.GetElementVisual(Header); + var titleRedirect = compositor.CreateRedirectVisual(TitleBarrr, Vector2.Zero, new Vector2(200, 40)); + titleRedirect.CenterPoint = new Vector3(0, 20, 0); + ElementCompositionPreview.SetElementChildVisual(this, titleRedirect); + + titleVisual.CenterPoint = new Vector3(0, 10, 0); storiesVisual.Clip = clip; titleVisual.Properties.InsertVector3("Translation", Vector3.Zero); @@ -518,7 +553,10 @@ private void SetControlledList(FrameworkElement value) ElementCompositionPreview.SetIsTranslationEnabled(this, true); ElementCompositionPreview.SetIsTranslationEnabled(Header, true); - titleVisual.StartAnimation("Translation.X", titleVisualOffsetAnimation); + titleRedirect.StartAnimation("Offset", titleVisualOffsetAnimation); + titleRedirect.StartAnimation("Opacity", titleVisualOpacityInverseAnimation); + titleVisual.StartAnimation("Scale", titleVisualScaleAnimation); + titleVisual.StartAnimation("Opacity", titleVisualOpacityAnimation); storiesVisual.StartAnimation("Translation.X", storiesVisualOffsetAnimationX); clip.StartAnimation("RightInset", storiesVisualOffsetAnimationX); storiesVisual.StartAnimation("Translation.Y", storiesVisualOffsetAnimation); @@ -797,5 +835,13 @@ public void Expand(bool animated = true, float offset = 0) #endregion + + private void Icon_Click(object sender, RoutedEventArgs e) + { + if (ViewModel.IsPremium) + { + EmojiMenuFlyout.ShowAt(ViewModel.ClientService, EmojiDrawerMode.EmojiStatus, Icon, EmojiFlyoutAlignment.TopLeft); + } + } } } diff --git a/Telegram/Views/MainPage.xaml b/Telegram/Views/MainPage.xaml index 73d52dbf4d..f903160a3c 100644 --- a/Telegram/Views/MainPage.xaml +++ b/Telegram/Views/MainPage.xaml @@ -40,82 +40,85 @@ IsHitTestVisible="False" Grid.Column="1" /> - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + + - + - + + + + 0 ? 138 : 0; - UpdateTitleBarMargins(); + + Stories.SystemOverlayLeftInset = metrics.LeftInset > 0 ? 138 : 0; + Stories.SystemOverlayRightInset = metrics.RightInset > 0 ? 138 : 0; } private void UpdateTitleBarMargins() @@ -250,11 +251,11 @@ private void UpdateTitleBarMargins() if (TitleText.FlowDirection == FlowDirection.LeftToRight) { - TitleBarrr.Margin = new Thickness(left, 0, right, 0); + TitleBarrr.Margin = new Thickness(left, TitleBarrr.Margin.Top, right, TitleBarrr.Margin.Bottom); } else { - TitleBarrr.Margin = new Thickness(right, 0, left, 0); + TitleBarrr.Margin = new Thickness(right, TitleBarrr.Margin.Top, left, TitleBarrr.Margin.Bottom); } } From 03b0ce7d55f527ee73220bc47b5e27053b045294 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:54:39 +0400 Subject: [PATCH 037/169] Improve tab style for forward and web preview --- Telegram/Controls/Messages/Content/WebPageContent.xaml | 4 ++++ Telegram/Controls/Messages/MessageForwardHeader.xaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Telegram/Controls/Messages/Content/WebPageContent.xaml b/Telegram/Controls/Messages/Content/WebPageContent.xaml index 122d06b394..d28ea177d0 100644 --- a/Telegram/Controls/Messages/Content/WebPageContent.xaml +++ b/Telegram/Controls/Messages/Content/WebPageContent.xaml @@ -44,6 +44,10 @@ Value="0,8,0,6" /> + + diff --git a/Telegram/Controls/Messages/MessageForwardHeader.xaml b/Telegram/Controls/Messages/MessageForwardHeader.xaml index a3a828c340..201207a1ae 100644 --- a/Telegram/Controls/Messages/MessageForwardHeader.xaml +++ b/Telegram/Controls/Messages/MessageForwardHeader.xaml @@ -11,6 +11,10 @@ Value="{ThemeResource MessageHeaderForegroundBrush}" /> + + From 6ef88b813cfd1eddad64229dad544336353f3b8d Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:54:54 +0400 Subject: [PATCH 038/169] Fix stake dice final state --- Telegram/Controls/Messages/MessageSelector.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Controls/Messages/MessageSelector.xaml.cs b/Telegram/Controls/Messages/MessageSelector.xaml.cs index 547b5c9bae..583858437b 100644 --- a/Telegram/Controls/Messages/MessageSelector.xaml.cs +++ b/Telegram/Controls/Messages/MessageSelector.xaml.cs @@ -337,7 +337,7 @@ public void UpdateMessageStakeDice(MessageViewModel message) return; } - if (message.Content is MessageStakeDice { Value: not 0 }) + if (message.Content is MessageStakeDice { Value: not 0 } && !message.GeneratedContentUnread) { _hasStakeDice = true; Footer ??= GetTemplateChild(nameof(Footer)) as Border; From 257d9f9648287bce73c357ae612bf36e16d2e0c9 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:55:08 +0400 Subject: [PATCH 039/169] Try-catch --- Telegram/Services/ThemeService.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Telegram/Services/ThemeService.cs b/Telegram/Services/ThemeService.cs index 0f4d509393..e38e9b9d87 100644 --- a/Telegram/Services/ThemeService.cs +++ b/Telegram/Services/ThemeService.cs @@ -75,16 +75,23 @@ public async Task> GetCustomThemesAsync() { var result = new List(); - var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("themes", CreationCollisionOption.OpenIfExists); - var files = await folder.GetFilesAsync(); - - foreach (var file in files) + try { - try + var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("themes", CreationCollisionOption.OpenIfExists); + var files = await folder.GetFilesAsync(); + + foreach (var file in files) { - result.Add(await DeserializeAsync(file)); + try + { + result.Add(await DeserializeAsync(file)); + } + catch { } } - catch { } + } + catch + { + // GetFilesAsync seems to throw at times } return result; From 7b4a2afd5afee41c71845dde1b2f447cbde4d4dc Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:55:16 +0400 Subject: [PATCH 040/169] Extra log --- Telegram/Services/NotificationsService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Telegram/Services/NotificationsService.cs b/Telegram/Services/NotificationsService.cs index 2db8436b95..52737b3fb8 100644 --- a/Telegram/Services/NotificationsService.cs +++ b/Telegram/Services/NotificationsService.cs @@ -710,6 +710,11 @@ private void UpdateToast(string caption, string message, string account, bool su notification.SuppressPopup = suppressPopup || ticks - _lastShownToast <= 7000; notifier.Show(notification); + if (ticks - _lastShownToast <= 7000) + { + Logger.Info("Suppress popup"); + } + if (soundFile != null && notifier.Setting == NotificationSetting.Enabled) { SoundEffects.Play(soundFile); From a049665f45b21a065687cff5a90d6722c4722ca4 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:55:27 +0400 Subject: [PATCH 041/169] Fix null ref --- Telegram/Td/Api/TdExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/Td/Api/TdExtensions.cs b/Telegram/Td/Api/TdExtensions.cs index 83f12771bd..93ae499991 100644 --- a/Telegram/Td/Api/TdExtensions.cs +++ b/Telegram/Td/Api/TdExtensions.cs @@ -1658,12 +1658,12 @@ public static File GetFile(this MessageWithOwner message) return GetFile(viewModel.GeneratedContent ?? message.Content); } - return GetFile(message.Content); + return GetFile(message?.Content); } public static File GetFile(this Message message) { - return GetFile(message.Content); + return GetFile(message?.Content); } public static File GetFile(this MessageContent content) From 32e878b07c99bc44f31a642192b5438067e5fe31 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:56:06 +0400 Subject: [PATCH 042/169] Refactoring --- Telegram/ViewModels/CallsViewModel.cs | 42 +++++++++++++++++++++--- Telegram/Views/MainPage.xaml.cs | 8 ++--- Telegram/Views/Popups/CallsPopup.xaml.cs | 23 +------------ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/Telegram/ViewModels/CallsViewModel.cs b/Telegram/ViewModels/CallsViewModel.cs index 6d7c255da2..32a10153b2 100644 --- a/Telegram/ViewModels/CallsViewModel.cs +++ b/Telegram/ViewModels/CallsViewModel.cs @@ -13,11 +13,15 @@ using Telegram.Collections; using Telegram.Common; using Telegram.Controls; +using Telegram.Controls.Media; using Telegram.Converters; using Telegram.Navigation; +using Telegram.Navigation.Services; using Telegram.Services; using Telegram.Td.Api; using Telegram.Views.Calls.Popups; +using Telegram.Views.Popups; +using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; @@ -146,14 +150,44 @@ public async void DeleteCall(TLCallGroup group) #endregion - public async void CreateLink() + private static async void CreateLink(IClientService clientService, INavigationService navigation) { - var response = await ClientService.SendAsync(new CreateGroupCall(null)); - if (response is GroupCallInfo info && ClientService.TryGetGroupCall(info.GroupCallId, out GroupCall groupCall)) + var response = await clientService.SendAsync(new CreateGroupCall(null)); + if (response is GroupCallInfo info && clientService.TryGetGroupCall(info.GroupCallId, out GroupCall groupCall)) { - NavigationService.ShowPopup(new ShareGroupCallPopup(ClientService, NavigationService, groupCall)); + navigation.ShowPopup(new ShareGroupCallPopup(clientService, navigation, groupCall)); } } + + public static void NewCall(IClientService clientService, INavigationService navigation) + { + var popup = new ChooseChatsPopup(); + var button = new SettingsButton + { + Content = Strings.GroupCallCreateLink, + Glyph = Icons.LinkAdd, + Style = BootStrapper.Current.Resources["GlyphBadgeButtonPopupStyle"] as Style, + Margin = new Thickness(12, 0, 12, 0), + }; + + void handler(object sender, RoutedEventArgs e) + { + button.Click -= handler; + popup.Hide(); + + CreateLink(clientService, navigation); + } + + button.Click += handler; + popup.Header = button; + + navigation.ShowPopup(popup, new ChooseChatsConfigurationCreateGroupCall()); + } + + public void NewCall() + { + NewCall(ClientService, NavigationService); + } } public partial class TLCallGroup diff --git a/Telegram/Views/MainPage.xaml.cs b/Telegram/Views/MainPage.xaml.cs index 882960c130..eefa89b2db 100644 --- a/Telegram/Views/MainPage.xaml.cs +++ b/Telegram/Views/MainPage.xaml.cs @@ -2336,11 +2336,11 @@ public void NavigationView_ItemClick(RootDestination destination) } else if (destination == RootDestination.Contacts) { - _ = ViewModel.NavigationService.ShowPopupAsync(new ContactsPopup()); + ViewModel.NavigationService.ShowPopup(new ContactsPopup()); } else if (destination == RootDestination.Calls) { - _ = ViewModel.NavigationService.ShowPopupAsync(new CallsPopup()); + ViewModel.NavigationService.ShowPopup(new CallsPopup()); } else if (destination == RootDestination.Settings) { @@ -2356,11 +2356,11 @@ public void NavigationView_ItemClick(RootDestination destination) } else if (destination == RootDestination.NewGroup) { - _ = ViewModel.NavigationService.ShowPopupAsync(new NewGroupPopup()); + ViewModel.NavigationService.ShowPopup(new NewGroupPopup()); } else if (destination == RootDestination.NewChannel) { - _ = ViewModel.NavigationService.ShowPopupAsync(new NewChannelPopup()); + ViewModel.NavigationService.ShowPopup(new NewChannelPopup()); } else if (destination == RootDestination.MyProfile) { diff --git a/Telegram/Views/Popups/CallsPopup.xaml.cs b/Telegram/Views/Popups/CallsPopup.xaml.cs index 2541dc5776..cfd2596cc2 100644 --- a/Telegram/Views/Popups/CallsPopup.xaml.cs +++ b/Telegram/Views/Popups/CallsPopup.xaml.cs @@ -9,7 +9,6 @@ using Telegram.Controls; using Telegram.Controls.Cells; using Telegram.Controls.Media; -using Telegram.Navigation; using Telegram.ViewModels; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -73,28 +72,8 @@ private void OnItemClick(object sender, ItemClickEventArgs e) private void NewCall_Click(object sender, RoutedEventArgs e) { - var popup = new ChooseChatsPopup(); - var button = new SettingsButton - { - Content = Strings.GroupCallCreateLink, - Glyph = Icons.LinkAdd, - Style = BootStrapper.Current.Resources["GlyphBadgeButtonPopupStyle"] as Style, - Margin = new Thickness(12, 0, 12, 0), - }; - - void handler(object sender, RoutedEventArgs e) - { - button.Click -= handler; - popup.Hide(); - - ViewModel.CreateLink(); - } - - button.Click += handler; - popup.Header = button; - Hide(); - ViewModel.NavigationService.ShowPopup(popup, new ChooseChatsConfigurationCreateGroupCall()); + ViewModel.NewCall(); } private void ScrollingHeader_SizeChanged(object sender, SizeChangedEventArgs e) From 1f96b86f7ab934b67d74bbee4d14bd76b98e1f37 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:57:30 +0400 Subject: [PATCH 043/169] Forum tabs in profile --- Telegram/Services/Session.g.cs | 5 + Telegram/Telegram.csproj | 9 + Telegram/TypeContainerGenerator.cs | 1 + .../Profile/ProfileTabsViewModel.cs | 18 +- .../Profile/ProfileTopicsTabViewModel.cs | 38 ++++ Telegram/ViewModels/ProfileViewModel.cs | 31 ++- Telegram/ViewModels/TopicListViewModel.cs | 31 ++- .../Profile/ProfileSavedChatsTabPage.xaml.cs | 7 +- .../Views/Profile/ProfileTopicsTabPage.xaml | 51 +++++ .../Profile/ProfileTopicsTabPage.xaml.cs | 183 ++++++++++++++++++ 10 files changed, 363 insertions(+), 11 deletions(-) create mode 100644 Telegram/ViewModels/Profile/ProfileTopicsTabViewModel.cs create mode 100644 Telegram/Views/Profile/ProfileTopicsTabPage.xaml create mode 100644 Telegram/Views/Profile/ProfileTopicsTabPage.xaml.cs diff --git a/Telegram/Services/Session.g.cs b/Telegram/Services/Session.g.cs index c28e2fd009..beacf1ac7a 100644 --- a/Telegram/Services/Session.g.cs +++ b/Telegram/Services/Session.g.cs @@ -304,6 +304,11 @@ public T Resolve() _clientService, _settingsService, _eventAggregator); + case "Telegram.ViewModels.Profile.ProfileTopicsTabViewModel": + return (T)(object)new Telegram.ViewModels.Profile.ProfileTopicsTabViewModel( + _clientService, + _settingsService, + _eventAggregator); case "Telegram.ViewModels.Users.UserEditViewModel": return (T)(object)new Telegram.ViewModels.Users.UserEditViewModel( _clientService, diff --git a/Telegram/Telegram.csproj b/Telegram/Telegram.csproj index 5ae5ec05c3..59411daee2 100644 --- a/Telegram/Telegram.csproj +++ b/Telegram/Telegram.csproj @@ -694,6 +694,7 @@ + @@ -1416,6 +1417,9 @@ ProfileRatingPopup.xaml + + ProfileTopicsTabPage.xaml + ProfileSavedMessagesTabPage.xaml @@ -3577,6 +3581,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -4402,6 +4410,7 @@ Windows Desktop Extensions for the UWP + 14.0 diff --git a/Telegram/TypeContainerGenerator.cs b/Telegram/TypeContainerGenerator.cs index e4ee17a834..e695627ee2 100644 --- a/Telegram/TypeContainerGenerator.cs +++ b/Telegram/TypeContainerGenerator.cs @@ -103,6 +103,7 @@ public static void Generate() typeof(ProfileBotsTabViewModel), typeof(ProfileGiftsTabViewModel), typeof(ProfileSavedChatsTabViewModel), + typeof(ProfileTopicsTabViewModel), typeof(UserEditViewModel), typeof(UserAffiliateViewModel), typeof(SupergroupEditViewModel), diff --git a/Telegram/ViewModels/Profile/ProfileTabsViewModel.cs b/Telegram/ViewModels/Profile/ProfileTabsViewModel.cs index 954bc68f4e..6e68e4dd9f 100644 --- a/Telegram/ViewModels/Profile/ProfileTabsViewModel.cs +++ b/Telegram/ViewModels/Profile/ProfileTabsViewModel.cs @@ -37,6 +37,14 @@ public override string ToString() } } + public class ProfileTabTopics : ProfileTab + { + public override string ToString() + { + return nameof(ProfileTabTopics); + } + } + public class ProfileTabPreviews : ProfileTab { public override string ToString() @@ -131,6 +139,7 @@ public ProfileTabItem(ProfileTab type, object parameter, ICollectionWithTotalCou ProfileTabGifts => (Strings.ProfileGifts, typeof(ProfileGiftsTabPage)), ProfileTabArchivedPosts => (Strings.ArchivedStories, typeof(ProfileStoriesTabPage)), ProfileTabSavedChats => (Strings.SavedDialogsTab, typeof(ProfileSavedChatsTabPage)), + ProfileTabTopics => (Strings.Topics, typeof(ProfileTopicsTabPage)), ProfileTabPreviews => (Strings.ProfileBotPreviewTab, typeof(ProfileStoriesTabPage)), ProfileTabGroups => (Strings.SharedGroupsTab2, typeof(ProfileGroupsTabPage)), ProfileTabSimilarBots => (Strings.SimilarBotsTab, typeof(ProfileBotsTabPage)), @@ -175,7 +184,8 @@ public override string ToString() public abstract partial class ProfileTabsViewModel : MediaTabsViewModelBase, IHandle { - protected readonly ProfileSavedChatsTabViewModel _savedChatsViewModel; + protected readonly ProfileSavedChatsTabViewModel _savedChatsTabViewModel; + protected readonly ProfileTopicsTabViewModel _topicsTabViewModel; protected readonly ProfileStoriesTabViewModel _pinnedStoriesTabViewModel; protected readonly ProfileStoriesTabViewModel _archivedStoriesTabViewModel; protected readonly ProfileGroupsTabViewModel _groupsTabViewModel; @@ -187,7 +197,8 @@ public abstract partial class ProfileTabsViewModel : MediaTabsViewModelBase, IHa public ProfileTabsViewModel(IClientService clientService, ISettingsService settingsService, IStorageService storageService, IEventAggregator aggregator) : base(clientService, settingsService, storageService, aggregator) { - _savedChatsViewModel = Session.Resolve(); + _savedChatsTabViewModel = Session.Resolve(); + _topicsTabViewModel = Session.Resolve(); _pinnedStoriesTabViewModel = Session.Resolve(); _archivedStoriesTabViewModel = Session.Resolve(); _groupsTabViewModel = Session.Resolve(); @@ -200,7 +211,8 @@ public ProfileTabsViewModel(IClientService clientService, ISettingsService setti _pinnedStoriesTabViewModel.SetType(ChatStoriesType.Pinned); _archivedStoriesTabViewModel.SetType(ChatStoriesType.Archive); - Children.Add(_savedChatsViewModel); + Children.Add(_savedChatsTabViewModel); + Children.Add(_topicsTabViewModel); Children.Add(_pinnedStoriesTabViewModel); Children.Add(_archivedStoriesTabViewModel); Children.Add(_groupsTabViewModel); diff --git a/Telegram/ViewModels/Profile/ProfileTopicsTabViewModel.cs b/Telegram/ViewModels/Profile/ProfileTopicsTabViewModel.cs new file mode 100644 index 0000000000..59c5ef2222 --- /dev/null +++ b/Telegram/ViewModels/Profile/ProfileTopicsTabViewModel.cs @@ -0,0 +1,38 @@ +// +// Copyright (c) Fela Ameghino 2015-2026 +// +// Distributed under the GNU General Public License v3.0. (See accompanying +// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) +// + +using System.Threading.Tasks; +using Telegram.Navigation.Services; +using Telegram.Services; +using Windows.UI.Xaml.Navigation; + +namespace Telegram.ViewModels.Profile +{ + public partial class ProfileTopicsTabViewModel : TopicListViewModel + { + public ProfileTopicsTabViewModel(IClientService clientService, ISettingsService settingsService, IEventAggregator aggregator) + : base(clientService, settingsService, aggregator, null, true, true) + { + } + + protected override Task OnNavigatedToAsync(object parameter, NavigationMode mode, NavigationState state) + { + if (parameter is long chatId) + { + var chat = ClientService.GetChat(chatId); + if (chat == null) + { + return Task.CompletedTask; + } + + SetChat(chat); + } + + return Task.CompletedTask; + } + } +} diff --git a/Telegram/ViewModels/ProfileViewModel.cs b/Telegram/ViewModels/ProfileViewModel.cs index b5b30f22ed..ba91a25a80 100644 --- a/Telegram/ViewModels/ProfileViewModel.cs +++ b/Telegram/ViewModels/ProfileViewModel.cs @@ -63,7 +63,8 @@ private void Gifts_ItemsReady(object sender, EventArgs e) public ITranslateService TranslateService => _translateService; - public ProfileSavedChatsTabViewModel SavedChatsTab => _savedChatsViewModel; + public ProfileSavedChatsTabViewModel SavedChatsTab => _savedChatsTabViewModel; + public ProfileTopicsTabViewModel TopicsTab => _topicsTabViewModel; public ProfileStoriesTabViewModel PinnedStoriesTab => _pinnedStoriesTabViewModel; public ProfileStoriesTabViewModel ArchivedStoriesTab => _archivedStoriesTabViewModel; public ProfileGroupsTabViewModel GroupsTab => _groupsTabViewModel; @@ -235,6 +236,11 @@ protected override async Task UpdateTabsAsync(Chat chat) } else { + if (user.Type is UserTypeBot { HasTopics: true }) + { + tabs.Add(new ProfileTabItem(new ProfileTabTopics(), null, TopicsTab.Items, Strings.R.Chats)); + } + if (user.Id == ClientService.Options.MyId) { tabs.Add(new ProfileTabItem(new ProfileTabSavedChats(), null, SavedChatsTab.Items, Strings.R.Chats)); @@ -307,6 +313,11 @@ protected override async Task UpdateTabsAsync(Chat chat) { if (ForumTopic == null) { + if (supergroup.HasForumTabs) + { + tabs.Add(new ProfileTabItem(new ProfileTabTopics(), null, TopicsTab.Items, Strings.R.Chats)); + } + tabs.Add(new ProfileTabItem(new ProfileTabMembers(), null, ClientService.GetMembersCount(chat), Strings.R.Members)); } @@ -1481,6 +1492,24 @@ public void OpenSavedMessagesTopic(SavedMessagesTopic topic) NavigationService.NavigateToChat(_chat.Id, topic: new MessageTopicSavedMessages(topic.Id)); } + public void OpenForumTopic(ForumTopic topic) + { + if (_chat is not Chat chat) + { + return; + } + + if (NavigationService.IsChatOpen(chat.Id)) + { + NavigationService.ReplaceChatInBackStack(chat.Id, new ChatMessageTopic(chat.Id, new MessageTopicForum(topic.Info.ForumTopicId))); + NavigationService.GoBack(); + } + else + { + NavigationService.NavigateToChat(chat, topic: new MessageTopicForum(topic.Info.ForumTopicId)); + } + } + private StarAmount _starCount; public StarAmount StarCount { diff --git a/Telegram/ViewModels/TopicListViewModel.cs b/Telegram/ViewModels/TopicListViewModel.cs index ae19a4eac1..3669c493e6 100644 --- a/Telegram/ViewModels/TopicListViewModel.cs +++ b/Telegram/ViewModels/TopicListViewModel.cs @@ -582,7 +582,7 @@ public async void CreateTopic() } } - public interface ITopicListCollection : IList + public interface ITopicListCollection : IList, ICollectionWithTotalCount { Chat Chat { get; } @@ -941,6 +941,20 @@ public bool IsEmpty } } + private int _totalCount; + public int TotalCount + { + get => _totalCount; + set + { + if (_totalCount != value) + { + _totalCount = value; + OnPropertyChanged(new PropertyChangedEventArgs(nameof(TotalCount))); + } + } + } + private void NotifyChanged() { OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEmpty))); @@ -1285,11 +1299,24 @@ public bool IsEmpty } } + private int _totalCount; + public int TotalCount + { + get => _totalCount; + set + { + if (_totalCount != value) + { + _totalCount = value; + OnPropertyChanged(new PropertyChangedEventArgs(nameof(TotalCount))); + } + } + } + private void NotifyChanged() { OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEmpty))); } } - } } diff --git a/Telegram/Views/Profile/ProfileSavedChatsTabPage.xaml.cs b/Telegram/Views/Profile/ProfileSavedChatsTabPage.xaml.cs index 75b27f0912..3007120c4c 100644 --- a/Telegram/Views/Profile/ProfileSavedChatsTabPage.xaml.cs +++ b/Telegram/Views/Profile/ProfileSavedChatsTabPage.xaml.cs @@ -104,12 +104,9 @@ public void UpdateSavedMessagesTopicLastMessage(SavedMessagesTopic topic) } var container = ScrollingHost.ContainerFromItem(topic) as SelectorItem; - if (container?.ContentTemplateRoot is Grid content) + if (container?.ContentTemplateRoot is ChatCell cell) { - if (content.Children[0] is ChatCell cell) - { - cell.UpdateSavedMessagesTopic(clientService, topic); - } + cell.UpdateSavedMessagesTopic(clientService, topic); } }); } diff --git a/Telegram/Views/Profile/ProfileTopicsTabPage.xaml b/Telegram/Views/Profile/ProfileTopicsTabPage.xaml new file mode 100644 index 0000000000..378289529c --- /dev/null +++ b/Telegram/Views/Profile/ProfileTopicsTabPage.xaml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Telegram/Views/Profile/ProfileTopicsTabPage.xaml.cs b/Telegram/Views/Profile/ProfileTopicsTabPage.xaml.cs new file mode 100644 index 0000000000..fde261303a --- /dev/null +++ b/Telegram/Views/Profile/ProfileTopicsTabPage.xaml.cs @@ -0,0 +1,183 @@ +// +// Copyright (c) Fela Ameghino 2015-2026 +// +// Distributed under the GNU General Public License v3.0. (See accompanying +// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) +// + +using System; +using System.Collections.Generic; +using Telegram.Common; +using Telegram.Controls; +using Telegram.Controls.Cells; +using Telegram.Controls.Media; +using Telegram.Td.Api; +using Telegram.ViewModels; +using Telegram.ViewModels.Delegates; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Input; + +namespace Telegram.Views.Profile +{ + public sealed partial class ProfileTopicsTabPage : ProfileTabPage, ITopicListDelegate + { + public new ProfileViewModel ViewModel => DataContext as ProfileViewModel; + + public ProfileTopicsTabPage() + { + InitializeComponent(); + + Connected += OnConnected; + Disconnected += OnDisconnected; + } + + private void OnConnected(object sender, RoutedEventArgs e) + { + ViewModel?.TopicsTab.Delegate = this; + } + + private void OnDisconnected(object sender, RoutedEventArgs e) + { + ViewModel?.TopicsTab.Delegate = null; + } + + private void ListView_ItemClick(object sender, ItemClickEventArgs e) + { + if (e.ClickedItem is ForumTopic topic) + { + ViewModel.OpenForumTopic(topic); + } + } + + private readonly Dictionary _itemToSelector = new(); + + protected override void OnChoosingItemContainer(ListViewBase sender, ChoosingItemContainerEventArgs args) + { + if (args.ItemContainer == null) + { + args.ItemContainer = new TableListViewItem(); + args.ItemContainer.Style = ScrollingHost.ItemContainerStyle; + args.ItemContainer.ContentTemplate = ScrollingHost.ItemTemplate; + args.ItemContainer.ContextRequested += OnContextRequested; + } + + args.IsContainerPrepared = true; + } + + private void OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) + { + if (args.Item is not ForumTopic forumTopic) + { + return; + } + + if (args.InRecycleQueue) + { + _itemToSelector.Remove(forumTopic.Info.ForumTopicId); + return; + } + else if (args.ItemContainer.ContentTemplateRoot is ForumTopicCell content) + { + _itemToSelector[forumTopic.Info.ForumTopicId] = args.ItemContainer; + content.UpdateForumTopic(ViewModel.TopicsTab, forumTopic); + } + } + + private void OnContextRequested(UIElement sender, ContextRequestedEventArgs args) + { + var topic = ScrollingHost.ItemFromContainer(sender) as SavedMessagesTopic; + var flyout = new MenuFlyout(); + + if (topic.IsPinned) + { + flyout.CreateFlyoutItem(ViewModel.SavedChatsTab.UnpinTopic, topic, Strings.UnpinFromTop, Icons.PinOff); + } + else + { + flyout.CreateFlyoutItem(ViewModel.SavedChatsTab.PinTopic, topic, Strings.PinToTop, Icons.Pin); + } + + flyout.CreateFlyoutItem(ViewModel.SavedChatsTab.DeleteTopic, topic, Strings.Delete, Icons.Delete, destructive: true); + + flyout.ShowAt(sender, args); + } + + public void SetSelectedItem(object topic) + { + // Do nothing + } + + public void SetSelectedItems(IList topics) + { + // Do nothing + } + + public void UpdateForumTopicLastMessage(ForumTopic topic) + { + HandleForumTopic(topic, (chatView, chat) => + { + chatView.UpdateForumTopicReadInbox(chat); + chatView.UpdateForumTopicLastMessage(chat); + }); + } + + public void HandleForumTopic(int forumTopicId, Action action) + { + if (TryGetTopicAndCell(forumTopicId, out ForumTopic chat, out IForumTopicDelegate cell)) + { + action(cell, chat); + } + } + + public void HandleForumTopic(ForumTopic topic, Action action) + { + if (TryGetCell(topic, out IForumTopicDelegate cell)) + { + action(cell, topic); + } + } + + public void UpdateDirectMessagesChatTopicLastMessage(DirectMessagesChatTopic topic) + { + // Do nothing + } + + public void HandleDirectMessagesChatTopic(long topicId, Action action) + { + // Do nothing + } + + public void HandleDirectMessagesChatTopic(DirectMessagesChatTopic topic, Action action) + { + // Do nothing + } + + private bool TryGetTopicAndCell(int topicId, out ForumTopic topic, out IForumTopicDelegate cell) + { + if (_itemToSelector.TryGetValue(topicId, out SelectorItem container)) + { + topic = ScrollingHost.ItemFromContainer(container) as ForumTopic; + cell = container.ContentTemplateRoot as IForumTopicDelegate; + return topic != null && cell != null; + } + + topic = null; + cell = null; + return false; + } + + private bool TryGetCell(ForumTopic topic, out IForumTopicDelegate cell) + { + if (_itemToSelector.TryGetValue(topic.Info.ForumTopicId, out SelectorItem container)) + { + cell = container.ContentTemplateRoot as IForumTopicDelegate; + return cell != null; + } + + cell = null; + return false; + } + } +} From 652116c0a6527deac8fb0b350201eb227db4bb5d Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:57:46 +0400 Subject: [PATCH 044/169] Always enable summary in debug --- Telegram/ViewModels/MessageViewModel.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Telegram/ViewModels/MessageViewModel.cs b/Telegram/ViewModels/MessageViewModel.cs index f6cb0f1117..474b013724 100644 --- a/Telegram/ViewModels/MessageViewModel.cs +++ b/Telegram/ViewModels/MessageViewModel.cs @@ -310,7 +310,11 @@ private bool GetCanBeShared() private bool? _hasSenderPhoto; public bool HasSenderPhoto => _hasSenderPhoto ??= GetHasSenderPhoto(); +#if DEBUG + public bool CanSummarizeText => Text?.Text.Length > 1000 && !IsVisuallyOutgoing; +#else public bool CanSummarizeText => SummaryLanguageCode?.Length > 0 && !IsVisuallyOutgoing; +#endif private bool GetHasSenderPhoto() { From 5e776c8169fe04f88c45071485725b8d5d7b4dd0 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:58:13 +0400 Subject: [PATCH 045/169] Update default tab style --- Telegram/Controls/TopNavView.cs | 12 ++++++++++++ Telegram/Themes/Generic.xaml | 25 ++++++++++++++----------- Telegram/Views/ProfilePage.xaml | 2 +- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Telegram/Controls/TopNavView.cs b/Telegram/Controls/TopNavView.cs index 1951c5fc0d..9ef4243f59 100644 --- a/Telegram/Controls/TopNavView.cs +++ b/Telegram/Controls/TopNavView.cs @@ -183,6 +183,9 @@ private void AnimateSelectionChanged(object nextItem, bool retry = true) var scopedBatch = BootStrapper.Current.Compositor.CreateScopedBatch(CompositionBatchTypes.Animation); scopedBatch.Completed += OnAnimationCompleted; + SetZIndex(prevIndicator, -1); + SetZIndex(nextIndicator, -2); + // Play the animation on both the previous and next indicators PlayIndicatorAnimations(prevIndicator, 0, @@ -213,6 +216,15 @@ private void AnimateSelectionChanged(object nextItem, bool retry = true) } } + private void SetZIndex(UIElement indicator, int index) + { + var selector = indicator.GetParent(); + if (selector != null) + { + Canvas.SetZIndex(selector, index); + } + } + private UIElement FindSelectionIndicator(object item, bool retry) { var container = (item is TopNavViewItem ? item : ContainerFromItem(item)) as TopNavViewItem; diff --git a/Telegram/Themes/Generic.xaml b/Telegram/Themes/Generic.xaml index 145d4b37c8..ce1bfac2cc 100644 --- a/Telegram/Themes/Generic.xaml +++ b/Telegram/Themes/Generic.xaml @@ -3091,19 +3091,19 @@ + Value="{ThemeResource AccentButtonBackground}" /> + Value="{ThemeResource AccentButtonBackground}" /> + Value="{ThemeResource AccentButtonBackground}" /> @@ -3200,8 +3200,9 @@ + AutomationProperties.AccessibilityView="Raw" + Canvas.ZIndex="1" /> + VerticalAlignment="Center" + Height="24" + Opacity="0.15"> + RadiusX="12" + RadiusY="12" /> diff --git a/Telegram/Views/ProfilePage.xaml b/Telegram/Views/ProfilePage.xaml index 86eb1e3dab..50f0a7bcf3 100644 --- a/Telegram/Views/ProfilePage.xaml +++ b/Telegram/Views/ProfilePage.xaml @@ -59,7 +59,7 @@ ItemsSource="{x:Bind ViewModel.Items}" SelectedItem="{x:Bind ViewModel.SelectedItem, Mode=TwoWay}" Height="48" - Padding="8,4"> + Padding="8,0,8,4"> Date: Fri, 16 Jan 2026 17:58:23 +0400 Subject: [PATCH 046/169] Navigation helper method --- Telegram/Common/NavigationService.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Telegram/Common/NavigationService.cs b/Telegram/Common/NavigationService.cs index 5ba63c55f8..d54686e8e6 100644 --- a/Telegram/Common/NavigationService.cs +++ b/Telegram/Common/NavigationService.cs @@ -366,6 +366,29 @@ public static void ReplaceChatInBackStack(this INavigationService service, long } } + public static void ReplaceChatInBackStack(this INavigationService service, long oldChatId, ChatMessageTopic newChatId) + { + for (int i = service.Frame.BackStackDepth - 1; i >= 0; i--) + { + var item = service.Frame.BackStack[i]; + + if (service.TryGetChatFromParameter(item.Parameter, out ChatMessageTopic chatId)) + { + if (chatId.ChatId == oldChatId) + { + if (item.Parameter is string cacheKey && service.CacheKeyToParameter.ContainsKey(cacheKey)) + { + service.CacheKeyToParameter[cacheKey] = newChatId; + } + else + { + service.Frame.BackStack[i] = new PageStackEntry(item.SourcePageType, newChatId, item.NavigationTransitionInfo); + } + } + } + } + } + public static Task NavigateWithResult(this INavigationService service, Type type, object parameter = null) { var tsc = new TaskCompletionSource(); From d0339a9a5acbded70c8443c3933a12d62b06321d Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:58:37 +0400 Subject: [PATCH 047/169] Fix summary button offset --- Telegram/Views/ChatView.Bubbles.xaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/Views/ChatView.Bubbles.xaml.cs b/Telegram/Views/ChatView.Bubbles.xaml.cs index 1cfae45f7e..1f34bd6260 100644 --- a/Telegram/Views/ChatView.Bubbles.xaml.cs +++ b/Telegram/Views/ChatView.Bubbles.xaml.cs @@ -412,7 +412,7 @@ bool AnimateStickySummary(Visual visual, GlyphButton stickySummary, ref Selector const string topExp = "(reference.Offset.Y + scroll.Translation.Y) - props.TopPadding"; const string bottomExp = $"(reference.Offset.Y + child.Size.Y + scroll.Translation.Y) - props.TopPadding"; - const string trueTrueExp = $"{bottomExp} >= 73 ? Max(props.TopPadding, {topExp}) : {bottomExp} - 26"; + const string trueTrueExp = $"{bottomExp} >= 73 ? Max(props.TopPadding, {topExp}) : {bottomExp} - (30 + 4 + 30)"; const string trueFalseExp = $"{bottomExp} - 26"; //$"{bottomExp} > 0 ? props.TopPadding : {bottomExp} + 8"; const string falseTrueExp = $"Max(0, {topExp})"; @@ -564,7 +564,7 @@ bool AnimateStickyPhoto(Visual visual, ProfilePicture stickyPhoto, ref SelectorI bottom += container.ActualHeight; // Read and play messages logic: - if (message.Id == 0) + if (message.Id is 0 or long.MaxValue) { continue; } From ae7fb936be4856189a14938fe819054a658dc593 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 16 Jan 2026 17:59:43 +0400 Subject: [PATCH 048/169] Bump version to 12.3.2 --- Telegram.Msix/Package.appxmanifest | 2 +- Telegram/Package.appxmanifest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram.Msix/Package.appxmanifest b/Telegram.Msix/Package.appxmanifest index 5482ff9d75..6f0ef52f53 100644 --- a/Telegram.Msix/Package.appxmanifest +++ b/Telegram.Msix/Package.appxmanifest @@ -1,6 +1,6 @@  - + Unigram—Telegram for Windows diff --git a/Telegram/Package.appxmanifest b/Telegram/Package.appxmanifest index 35995e799f..b18bc5d862 100644 --- a/Telegram/Package.appxmanifest +++ b/Telegram/Package.appxmanifest @@ -11,7 +11,7 @@ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="mp uap uap3 uap4 uap5 uap6 uap11 rescap desktop desktop4"> - + Unigram Experimental From 5c333ca27355404635398a6b1071635bf035d4b0 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 19 Jan 2026 17:38:19 +0400 Subject: [PATCH 049/169] Fix title bar --- .../Controls/Stories/StoriesStrip.xaml.cs | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/Telegram/Controls/Stories/StoriesStrip.xaml.cs b/Telegram/Controls/Stories/StoriesStrip.xaml.cs index 4e2f0d5a29..27f9c4582e 100644 --- a/Telegram/Controls/Stories/StoriesStrip.xaml.cs +++ b/Telegram/Controls/Stories/StoriesStrip.xaml.cs @@ -9,7 +9,6 @@ using System.Collections.Specialized; using System.Numerics; using Telegram.Common; -using Telegram.Composition; using Telegram.Controls.Cells; using Telegram.Controls.Media; using Telegram.Controls.Messages; @@ -109,7 +108,7 @@ private void UpdateIndexes() } var count = _last - _first + 1; - if (count > 0 && _collapsed) + if (count > 0 && _collapsed && _isVisible) { Show.Width = count * 12 + 12 + 8; Show.Margin = new Thickness(_first > 0 ? 26 : 14, 20, 0, 0); @@ -118,16 +117,16 @@ private void UpdateIndexes() Icon.Margin = new Thickness(Show.Width + Show.Margin.Left + 8, 20, 0, 0); Icon.Visibility = Visibility.Visible; - TitleBarrr?.Margin = new Thickness(TitleBarrr.Margin.Left, 40, TitleBarrr.Margin.Right, -40); - TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset + (count * 12 + 12 + 8) : 80 + (count * 12 + 12 + 8), 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 80, 0); + TitleBarrr?.IsHitTestVisible = false; + TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset + (count * 12 + 12 + 8) : TitleBarrr.Margin.Left + 40 + (count * 12 + 12 + 8), 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 88, 0); } else { Show.Visibility = Visibility.Collapsed; Icon.Visibility = Visibility.Collapsed; - TitleBarrr?.Margin = new Thickness(TitleBarrr.Margin.Left, 0, TitleBarrr.Margin.Right, 0); - TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset : 80, 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 80, 0); + TitleBarrr?.IsHitTestVisible = true; + TitleBarHandle?.Margin = new Thickness(SystemOverlayLeftInset > 0 ? SystemOverlayLeftInset : TitleBarrr.Margin.Left + 40, 0, SystemOverlayRightInset > 0 ? SystemOverlayRightInset : 88, 0); } ScrollingHost.IsHitTestVisible = !_collapsed; @@ -410,6 +409,8 @@ public bool IsVisible { _isVisible = value; _progress?.InsertBoolean("Visible", value); + + UpdateIndexes(); } } @@ -504,6 +505,7 @@ private void SetControlledList(FrameworkElement value) _progress.InsertScalar("First", _first); _progress.InsertScalar("Last", _last); _progress.InsertScalar("Count", _last - _first + 1); + _progress.InsertScalar("Total", _last + 1); _progress.InsertScalar("Progress", 0); _progress.StartAnimation("Progress", _progressAnimation); @@ -512,9 +514,20 @@ private void SetControlledList(FrameworkElement value) ForEach(_progress, _progressAnimation); - var titleVisualOffsetAnimation = compositor.CreateExpressionAnimation("Vector3(_.RightToLeft ? 0 : _.Visible && _.Count > 0 ? 40 + (12 * _.Count) + (((72 * _.Count) - (40 + (12 * _.Count))) * _.Progress) : 0, 16, 0)"); - var titleVisualScaleAnimation = compositor.CreateExpressionAnimation("_.Visible && _.Count > 0 ? Vector3(Clamp(_.Progress < 0.5 ? 0.5 : 0.5 + (_.Progress - 0.5), 0.5, 1), Clamp(_.Progress < 0.5 ? 0.5 : 0.5 + (_.Progress - 0.5), 0.5, 1), 1) : Vector3(1, 1, 1)"); - var titleVisualOpacityAnimation = compositor.CreateExpressionAnimation("_.Visible && _.Count > 0 ? _.Progress < 0.5 ? 0 : (_.Progress - 0.5) * 2 : 1"); + // >= 0.5 : above + // < 0.5 : below + var offsetExpandedX = "-(_.Padding - _.First * 12) * (_.Progress)"; + var offsetExpandedX2 = "24 + (12 * _.Count) + (((72 * _.Total) - (40 + (12 * _.Total))) * _.Progress)"; + var offsetExpandedY = "48 * _.Progress"; + + var offsetExpressionX = $"_.Progress < 0.5 ? ({offsetExpandedX}) + ({offsetExpandedX2}) : 0"; + var offsetExpressionY = $"_.Progress < 0.5 ? {offsetExpandedY} : 0"; + var scaleExpression = "_.Progress < 0.5 ? 1 : 0.5 + (_.Progress - 0.5)"; + var opacityExpression = "_.Progress < 0.5 ? 1 - _.Progress * 2 : (_.Progress - 0.5) * 2"; + + var titleVisualOffsetAnimation = compositor.CreateExpressionAnimation($"_.Visible && _.Count > 0 ? Vector3({offsetExpressionX}, {offsetExpressionY}, 0) : Vector3(0, 0, 0)"); + var titleVisualScaleAnimation = compositor.CreateExpressionAnimation($"_.Visible && _.Count > 0 ? Vector3(Clamp({scaleExpression}, 0.5, 1), Clamp({scaleExpression}, 0.5, 1), 1) : Vector3(1, 1, 1)"); + var titleVisualOpacityAnimation = compositor.CreateExpressionAnimation($"_.Visible && _.Count > 0 ? Clamp({opacityExpression}, 0, 1) : 1"); var titleVisualOpacityInverseAnimation = compositor.CreateExpressionAnimation("Clamp(1 - _.Progress * 2, 0, 1)"); var storiesVisualOffsetAnimationX = compositor.CreateExpressionAnimation( @@ -538,10 +551,6 @@ private void SetControlledList(FrameworkElement value) var storiesVisual = ElementComposition.GetElementVisual(this); var headerVisual = ElementComposition.GetElementVisual(Header); - var titleRedirect = compositor.CreateRedirectVisual(TitleBarrr, Vector2.Zero, new Vector2(200, 40)); - titleRedirect.CenterPoint = new Vector3(0, 20, 0); - ElementCompositionPreview.SetElementChildVisual(this, titleRedirect); - titleVisual.CenterPoint = new Vector3(0, 10, 0); storiesVisual.Clip = clip; @@ -553,8 +562,7 @@ private void SetControlledList(FrameworkElement value) ElementCompositionPreview.SetIsTranslationEnabled(this, true); ElementCompositionPreview.SetIsTranslationEnabled(Header, true); - titleRedirect.StartAnimation("Offset", titleVisualOffsetAnimation); - titleRedirect.StartAnimation("Opacity", titleVisualOpacityInverseAnimation); + titleVisual.StartAnimation("Translation", titleVisualOffsetAnimation); titleVisual.StartAnimation("Scale", titleVisualScaleAnimation); titleVisual.StartAnimation("Opacity", titleVisualOpacityAnimation); storiesVisual.StartAnimation("Translation.X", storiesVisualOffsetAnimationX); From 3641b5f1e9d439ae337e97d37d69ae4aee7efe5d Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 19 Jan 2026 18:23:42 +0400 Subject: [PATCH 050/169] Refactoring and null checks --- Telegram/App.xaml.cs | 8 ++--- Telegram/Navigation/WindowContext.cs | 12 ++++--- Telegram/Services/CloudUpdateService.cs | 46 ++++++++++++++----------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/Telegram/App.xaml.cs b/Telegram/App.xaml.cs index d160576c48..e2f656ce56 100644 --- a/Telegram/App.xaml.cs +++ b/Telegram/App.xaml.cs @@ -179,7 +179,7 @@ public override async void OnStart(StartKind startKind, IActivatedEventArgs args { WindowContext.Current.Activate(args, navigation, state); - _ = Task.Run(() => OnStartSync(startKind, navigation, update)); + _ = Task.Run(() => OnStartSync(startKind, update)); if (startKind != StartKind.Launch && WindowContext.Current.IsInMainView) { @@ -240,7 +240,7 @@ protected override INavigationService CreateNavigationService(ISession session, return new TLNavigationService(session, window, frame, id); } - private async void OnStartSync(StartKind startKind, INavigationService navigation, ICloudUpdateService updateService = null) + private async void OnStartSync(StartKind startKind, ICloudUpdateService updateService = null) { await RequestExtendedExecutionSessionAsync(); await Toast.RegisterBackgroundTasks(); @@ -259,7 +259,7 @@ private async void OnStartSync(StartKind startKind, INavigationService navigatio if (Constants.RELEASE && startKind == StartKind.Launch) { - if (await CloudUpdateService.LaunchAsync(navigation, true)) + if (await CloudUpdateService.LaunchAsync(true)) { return; } @@ -332,7 +332,7 @@ public override void OnResuming(object s, object e, AppExecutionState previousEx // #2034: Will this work? No one knows. SettingsService.Current.Appearance.UpdateNightMode(null); - OnStartSync(StartKind.Activate, WindowContext.Current.GetNavigationService()); + OnStartSync(StartKind.Activate); } public override Task OnSuspendingAsync(object s, SuspendingEventArgs e) diff --git a/Telegram/Navigation/WindowContext.cs b/Telegram/Navigation/WindowContext.cs index 7f001bc88b..0d04ca3140 100644 --- a/Telegram/Navigation/WindowContext.cs +++ b/Telegram/Navigation/WindowContext.cs @@ -109,6 +109,8 @@ public string PersistedId public WindowContext(Window window) { _window = window; + _current = this; + GarbageCollectionMonitor.StartMonitoring(window.CoreWindow); //Current = this; @@ -920,10 +922,12 @@ public static WindowContext Current { if (_current == null) { - if (Window.Current != null) - { - _current = new WindowContext(Window.Current); - } + //if (Window.Current != null) + //{ + // _current = new WindowContext(Window.Current); + //} + + Logger.Info(Environment.StackTrace); } return _current; diff --git a/Telegram/Services/CloudUpdateService.cs b/Telegram/Services/CloudUpdateService.cs index a087920997..eb64b65d1a 100644 --- a/Telegram/Services/CloudUpdateService.cs +++ b/Telegram/Services/CloudUpdateService.cs @@ -60,7 +60,7 @@ public async void Update() await UpdateAsync(false); } - public static async Task LaunchAsync(INavigationService navigation, bool checkAvailability) + public static async Task LaunchAsync(bool checkAvailability) { if (_disabled || !_updateLock.Wait(0)) { @@ -104,30 +104,34 @@ public static async Task LaunchAsync(INavigationService navigation, bool c Logger.Info($"Dispatching for version {update.Version}"); - // Terminate notify icon to make the update process smoother - _ = BridgeApplicationContext.ExitAsync(); - - // If package manager fails, we fall back on App Installer - await navigation.Dispatcher.DispatchAsync(async () => + var navigation = WindowContext.Main?.GetNavigationService(); + if (navigation != null) { - // Try to install the update first using the package manager - var installed = await InstallUpdateAsync(navigation, update.File); - if (installed is false) - { - // But only if App Installer is available - var result = checkAvailability - ? await Launcher.QueryFileSupportAsync(update.File) - : LaunchQuerySupportStatus.Available; - - Logger.Info($"QueryFileSupportAsync: {result}"); + // Terminate notify icon to make the update process smoother + _ = BridgeApplicationContext.ExitAsync(); - if (result == LaunchQuerySupportStatus.Available) + await navigation.Dispatcher.DispatchAsync(async () => + { + // Try to install the update first using the package manager + // If package manager fails, we fall back on App Installer + var installed = await InstallUpdateAsync(navigation, update.File); + if (installed is false) { - await Launcher.LaunchFileAsync(update.File); - await BootStrapper.ConsolidateAsync(); + // But only if App Installer is available + var result = checkAvailability + ? await Launcher.QueryFileSupportAsync(update.File) + : LaunchQuerySupportStatus.Available; + + Logger.Info($"QueryFileSupportAsync: {result}"); + + if (result == LaunchQuerySupportStatus.Available) + { + await Launcher.LaunchFileAsync(update.File); + await BootStrapper.ConsolidateAsync(); + } } - } - }); + }); + } _updateLock.Release(); return true; From 781950bca9bcdf1b75f209b2da50695409bba0d8 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 19 Jan 2026 18:27:44 +0400 Subject: [PATCH 051/169] Bump version to 12.3.3 --- Telegram.Msix/Package.appxmanifest | 2 +- Telegram/Package.appxmanifest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram.Msix/Package.appxmanifest b/Telegram.Msix/Package.appxmanifest index 6f0ef52f53..e8770d1020 100644 --- a/Telegram.Msix/Package.appxmanifest +++ b/Telegram.Msix/Package.appxmanifest @@ -1,6 +1,6 @@  - + Unigram—Telegram for Windows diff --git a/Telegram/Package.appxmanifest b/Telegram/Package.appxmanifest index b18bc5d862..2d8cda3ce5 100644 --- a/Telegram/Package.appxmanifest +++ b/Telegram/Package.appxmanifest @@ -11,7 +11,7 @@ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="mp uap uap3 uap4 uap5 uap6 uap11 rescap desktop desktop4"> - + Unigram Experimental From 576c7c88dc4d2415ab1386896adf99675de773a7 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 19 Jan 2026 18:31:40 +0400 Subject: [PATCH 052/169] Fix references --- .../Controls/Messages/Content/UnsupportedContent.xaml.cs | 7 ++----- Telegram/ViewModels/MainViewModel.cs | 2 +- Telegram/ViewModels/Settings/SettingsAdvancedViewModel.cs | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Telegram/Controls/Messages/Content/UnsupportedContent.xaml.cs b/Telegram/Controls/Messages/Content/UnsupportedContent.xaml.cs index a43da60741..be91389a8f 100644 --- a/Telegram/Controls/Messages/Content/UnsupportedContent.xaml.cs +++ b/Telegram/Controls/Messages/Content/UnsupportedContent.xaml.cs @@ -7,7 +7,6 @@ using System; using Telegram.Common; -using Telegram.Navigation; using Telegram.Services; using Telegram.Td.Api; using Telegram.ViewModels; @@ -95,10 +94,8 @@ private async void Button_Click(object sender, RoutedEventArgs e) } else { - var navigationService = WindowContext.Current.GetNavigationService(); var service = _message.ClientService.Session.Resolve(); - - if (navigationService != null && service != null) + if (service != null) { if (service.NextUpdate == null) { @@ -107,7 +104,7 @@ private async void Button_Click(object sender, RoutedEventArgs e) if (service.NextUpdate != null) { - await CloudUpdateService.LaunchAsync(navigationService, false); + await CloudUpdateService.LaunchAsync(false); } else { diff --git a/Telegram/ViewModels/MainViewModel.cs b/Telegram/ViewModels/MainViewModel.cs index f744c6ae17..fd066006f9 100644 --- a/Telegram/ViewModels/MainViewModel.cs +++ b/Telegram/ViewModels/MainViewModel.cs @@ -489,7 +489,7 @@ public void HideBirthdate() public async void UpdateApp() { - await CloudUpdateService.LaunchAsync(NavigationService, false); + await CloudUpdateService.LaunchAsync(false); } public async void CreateSecretChat() diff --git a/Telegram/ViewModels/Settings/SettingsAdvancedViewModel.cs b/Telegram/ViewModels/Settings/SettingsAdvancedViewModel.cs index 82c91fbd92..2592c4c33f 100644 --- a/Telegram/ViewModels/Settings/SettingsAdvancedViewModel.cs +++ b/Telegram/ViewModels/Settings/SettingsAdvancedViewModel.cs @@ -169,7 +169,7 @@ private async void UpdateImpl(bool launch) } else if (update.File != null && launch && Constants.RELEASE) { - await CloudUpdateService.LaunchAsync(NavigationService, false); + await CloudUpdateService.LaunchAsync(false); } UpdateFile(update, update?.Document, true); From 39c1672ab7c08bb366b4c1cc4ced4b00987a68bb Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 00:24:48 +0400 Subject: [PATCH 053/169] Fix window initialization --- Telegram/Navigation/BootStrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Navigation/BootStrapper.cs b/Telegram/Navigation/BootStrapper.cs index b9aa167448..405b26053e 100644 --- a/Telegram/Navigation/BootStrapper.cs +++ b/Telegram/Navigation/BootStrapper.cs @@ -83,7 +83,7 @@ protected override void OnWindowCreated(WindowCreatedEventArgs args) SystemNavigationManager.GetForCurrentView().BackRequested += BackHandler; CustomXamlResourceLoader.Current = new XamlResourceLoader(); - //CreateWindowWrapper(args.Window); + CreateWindowWrapper(args.Window); ViewService.OnWindowCreated(); args.Window.Activated += OnActivated; From ac4f75ed3daa8136815500bdfc5f07cf9d65a729 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 00:25:18 +0400 Subject: [PATCH 054/169] Bump version to 12.3.4 --- Telegram.Msix/Package.appxmanifest | 2 +- Telegram/Package.appxmanifest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram.Msix/Package.appxmanifest b/Telegram.Msix/Package.appxmanifest index e8770d1020..3ca210afaa 100644 --- a/Telegram.Msix/Package.appxmanifest +++ b/Telegram.Msix/Package.appxmanifest @@ -1,6 +1,6 @@  - + Unigram—Telegram for Windows diff --git a/Telegram/Package.appxmanifest b/Telegram/Package.appxmanifest index 2d8cda3ce5..2ab431e8fb 100644 --- a/Telegram/Package.appxmanifest +++ b/Telegram/Package.appxmanifest @@ -11,7 +11,7 @@ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="mp uap uap3 uap4 uap5 uap6 uap11 rescap desktop desktop4"> - + Unigram Experimental From a8b53e47294bdc11a712415a72cde3f07d5ae7a8 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 11:23:23 +0400 Subject: [PATCH 055/169] Fix interaction tracker crash --- Telegram/Controls/ChatListListView.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Telegram/Controls/ChatListListView.cs b/Telegram/Controls/ChatListListView.cs index 2208ec00c3..3942939553 100644 --- a/Telegram/Controls/ChatListListView.cs +++ b/Telegram/Controls/ChatListListView.cs @@ -410,15 +410,15 @@ private void OnLoaded(object sender, RoutedEventArgs e) ElementCompositionPreview.SetElementChildVisual(Ghost, _redirect); ElementCompositionPreview.SetElementChildVisual(this, _container); ConfigureInteractionTracker(); + } - if (_trackerOwner != null) - { - _trackerOwner.ValuesChanged += OnValuesChanged; - _trackerOwner.InertiaStateEntered += OnInertiaStateEntered; - _trackerOwner.InteractingStateEntered += OnInteractingStateEntered; - _trackerOwner.IdleStateEntered += OnIdleStateEntered; - _trackerOwner.CustomAnimationStateEntered += OnCustomAnimationStateEntered; - } + if (_trackerOwner != null) + { + _trackerOwner.ValuesChanged += OnValuesChanged; + _trackerOwner.InertiaStateEntered += OnInertiaStateEntered; + _trackerOwner.InteractingStateEntered += OnInteractingStateEntered; + _trackerOwner.IdleStateEntered += OnIdleStateEntered; + _trackerOwner.CustomAnimationStateEntered += OnCustomAnimationStateEntered; } if (_itemsSource == null) From 519947221301000086168ead3139ba5d044e666a Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 11:27:25 +0400 Subject: [PATCH 056/169] Refactoring --- Telegram/Controls/CarouselViewer.cs | 5 +---- Telegram/Controls/ChatListListView.cs | 7 +------ Telegram/Controls/Messages/MessageSelector.xaml.cs | 5 +---- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Telegram/Controls/CarouselViewer.cs b/Telegram/Controls/CarouselViewer.cs index 29079c133c..47a49be332 100644 --- a/Telegram/Controls/CarouselViewer.cs +++ b/Telegram/Controls/CarouselViewer.cs @@ -67,10 +67,8 @@ public CarouselViewer() private void OnLoaded(object sender, RoutedEventArgs e) { - if (!_hasInitialLoadedEventFired) + if (_trackerOwner == null) { - _hasInitialLoadedEventFired = true; - _hitTest = BootStrapper.Current.Compositor.CreateSpriteVisual(); _hitTest.Brush = BootStrapper.Current.Compositor.CreateColorBrush(Windows.UI.Colors.Transparent); @@ -300,7 +298,6 @@ public void ChangeView(CarouselDirection direction, bool disableAnimation = fals private readonly FrameworkElement[] _elements = new FrameworkElement[3]; private readonly Visual[] _visuals = new Visual[3]; - private bool _hasInitialLoadedEventFired; private bool _hasConfiguredElements; private WeakInteractionTrackerOwner _trackerOwner; diff --git a/Telegram/Controls/ChatListListView.cs b/Telegram/Controls/ChatListListView.cs index 3942939553..a2ba178520 100644 --- a/Telegram/Controls/ChatListListView.cs +++ b/Telegram/Controls/ChatListListView.cs @@ -383,17 +383,14 @@ void Continue(bool restore) private SpriteVisual _redirect; private ContainerVisual _indicator; - private bool _hasInitialLoadedEventFired; private WeakInteractionTrackerOwner _trackerOwner; private InteractionTracker _tracker; private VisualInteractionSource _interactionSource; private void OnLoaded(object sender, RoutedEventArgs e) { - if (!_hasInitialLoadedEventFired) + if (_trackerOwner == null) { - _hasInitialLoadedEventFired = true; - _visual = ElementComposition.GetElementVisual(ScrollViewer.ContentTemplateRoot); _redirect = _visual.Compositor.CreateSpriteVisual(); @@ -441,8 +438,6 @@ private void OnUnloaded(object sender, RoutedEventArgs e) _trackerOwner.CustomAnimationStateEntered -= OnCustomAnimationStateEntered; } - _hasInitialLoadedEventFired = false; - if (_itemsSource != null) { _itemsSource.Moved -= OnCollectionChanged; diff --git a/Telegram/Controls/Messages/MessageSelector.xaml.cs b/Telegram/Controls/Messages/MessageSelector.xaml.cs index 583858437b..764bd32692 100644 --- a/Telegram/Controls/Messages/MessageSelector.xaml.cs +++ b/Telegram/Controls/Messages/MessageSelector.xaml.cs @@ -63,10 +63,8 @@ public MessageSelector(MessageViewModel message, UIElement child) protected override void OnLoaded() { - if (!_hasInitialLoadedEventFired && RootGrid != null && IsTrackerEnabled && (SettingsService.Current.SwipeToReply || SettingsService.Current.SwipeToShare)) + if (_trackerOwner == null && RootGrid != null && IsTrackerEnabled && (SettingsService.Current.SwipeToReply || SettingsService.Current.SwipeToShare)) { - _hasInitialLoadedEventFired = true; - _compositor = BootStrapper.Current.Compositor; _container ??= _compositor.CreateContainerVisual(); @@ -563,7 +561,6 @@ protected override AutomationPeer OnCreateAutomationPeer() private ContainerVisual _container; private ContainerVisual _indicator; - private bool _hasInitialLoadedEventFired; private WeakInteractionTrackerOwner _trackerOwner; private InteractionTracker _tracker; private VisualInteractionSource _interactionSource; From da2740da4b0af41341f26ae96b72037f12bf8ab7 Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 15:46:36 +0400 Subject: [PATCH 057/169] Immediately mark outgoing calls as active Resolves #3216 --- Telegram/Services/Calls/VoipCall.cs | 20 ++++++++++++++------ Telegram/Services/Calls/VoipGroupCall.cs | 11 +++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Telegram/Services/Calls/VoipCall.cs b/Telegram/Services/Calls/VoipCall.cs index a64f632c1f..560c10542a 100644 --- a/Telegram/Services/Calls/VoipCall.cs +++ b/Telegram/Services/Calls/VoipCall.cs @@ -339,16 +339,16 @@ public void Accept() try { _systemCall?.TryShowAppUI(); - - // NotifyCallActive causes the main app window to be focused - // We call it immediately, so that the focus can move to the call window. - _systemCall?.NotifyCallActive(); } catch { // All the remote procedure calls must be wrapped in a try-catch block } + // NotifyCallActive causes the main app window to be focused + // We call it immediately, so that the focus can move to the call window. + _systemCall?.TryNotifyCallActive(); + ClientService.Send(new AcceptCall(Id, VoipManager.Protocol.ToTd())); // TODO: consider delivering a fake update to speed up initialization @@ -842,7 +842,7 @@ private async Task InitializeSystemCallAsync(User user, bool outgoing) user.FullName(), Strings.AppName, VoipPhoneCallMedia.Audio | VoipPhoneCallMedia.Video); - //_systemCall.TryNotifyCallActive(); + _systemCall.TryNotifyCallActive(); } else { @@ -874,10 +874,18 @@ static Uri GetPhoto(User user) _systemCall.EndRequested += OnEndRequested; } + else + { + Logger.Error(status); + } } - catch + catch (Exception ex) { + Logger.Error(ex); + + _coordinator?.MuteStateChanged -= OnMuteStateChanged; _coordinator = null; + _systemCall = null; } diff --git a/Telegram/Services/Calls/VoipGroupCall.cs b/Telegram/Services/Calls/VoipGroupCall.cs index 4c02a26d6e..61be996ef2 100644 --- a/Telegram/Services/Calls/VoipGroupCall.cs +++ b/Telegram/Services/Calls/VoipGroupCall.cs @@ -455,13 +455,20 @@ private async Task InitializeSystemCallAsync(int callId, string callTitle) _systemCall.TryNotifyCallActive(); _systemCall.EndRequested += OnEndRequested; } + else + { + Logger.Error(status); + } } - catch + catch (Exception ex) { + Logger.Error(ex); + + _coordinator?.MuteStateChanged += OnMuteStateChanged; _coordinator = null; + _systemCall = null; } - WatchDog.TrackEvent("VoipGroupCall", new Properties { { "Requested", _systemCall != null }, From 131849eb957c024ef7bce33376f855e6a687ec4c Mon Sep 17 00:00:00 2001 From: Fela Date: Tue, 20 Jan 2026 15:58:19 +0400 Subject: [PATCH 058/169] Fix edit media in saved messages --- Telegram/ViewModels/DialogViewModel.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Telegram/ViewModels/DialogViewModel.cs b/Telegram/ViewModels/DialogViewModel.cs index 4efc89ebc2..9d316b6838 100644 --- a/Telegram/ViewModels/DialogViewModel.cs +++ b/Telegram/ViewModels/DialogViewModel.cs @@ -3206,9 +3206,15 @@ protected override async Task BeforeSendMessageAsync(FormattedText formatt var factory = header.Editing.Media; if (factory is InputMessageContent input) { + var topicId = editing.TopicId; + if (topicId is MessageTopicSavedMessages) + { + topicId = null; + } + var options = new MessageSendOptions(header.SuggestedPostInfo, false, false, 0, false, null, 0, 0, true); - var response = await ClientService.SendAsync(new SendMessage(editing.ChatId, editing.TopicId, null, options, input)); + var response = await ClientService.SendAsync(new SendMessage(editing.ChatId, topicId, null, options, input)); if (response is Message preview) { _contentOverrides[editing.CombinedId] = preview.Content; From 4c9566da1b2867a06e94dc3840ec3c7c65730a37 Mon Sep 17 00:00:00 2001 From: Fela Date: Thu, 22 Jan 2026 18:00:33 +0400 Subject: [PATCH 059/169] Fix timestamp font --- Telegram/Controls/Cells/ChatCell.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/Controls/Cells/ChatCell.xaml b/Telegram/Controls/Cells/ChatCell.xaml index 374ab40de6..80e66b7ed8 100644 --- a/Telegram/Controls/Cells/ChatCell.xaml +++ b/Telegram/Controls/Cells/ChatCell.xaml @@ -208,7 +208,7 @@ Date: Thu, 22 Jan 2026 18:01:40 +0400 Subject: [PATCH 060/169] Bump version to 12.3.5 --- Telegram.Msix/Package.appxmanifest | 2 +- Telegram/Package.appxmanifest | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram.Msix/Package.appxmanifest b/Telegram.Msix/Package.appxmanifest index 3ca210afaa..2f9cca0b84 100644 --- a/Telegram.Msix/Package.appxmanifest +++ b/Telegram.Msix/Package.appxmanifest @@ -1,6 +1,6 @@  - + Unigram—Telegram for Windows diff --git a/Telegram/Package.appxmanifest b/Telegram/Package.appxmanifest index 2ab431e8fb..f99bdb97fd 100644 --- a/Telegram/Package.appxmanifest +++ b/Telegram/Package.appxmanifest @@ -11,7 +11,7 @@ xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="mp uap uap3 uap4 uap5 uap6 uap11 rescap desktop desktop4"> - + Unigram Experimental From d719bf1eea5df7d4c5a675153e7bdc804a6e35c7 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 23 Jan 2026 17:12:14 +0400 Subject: [PATCH 061/169] Try to fix once again text selection --- Telegram/Common/Extensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Telegram/Common/Extensions.cs b/Telegram/Common/Extensions.cs index e8d14e5672..b58ddc9d4f 100644 --- a/Telegram/Common/Extensions.cs +++ b/Telegram/Common/Extensions.cs @@ -415,6 +415,11 @@ public static int OffsetToIndex(this TextPointer pointer, StyledText text) } // Element end + if (paragraph.Padding == 0) + { + index++; + } + //index += paragraph.Padding; } From ca717fc7e927a87fa1ade1ebcd5bec14bbac43b8 Mon Sep 17 00:00:00 2001 From: Fela Date: Fri, 23 Jan 2026 17:12:58 +0400 Subject: [PATCH 062/169] Fix storage usage layout --- .../Views/Settings/SettingsStoragePage.xaml | 18 +++++++++--------- .../Views/Settings/SettingsStoragePage.xaml.cs | 5 ++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Telegram/Views/Settings/SettingsStoragePage.xaml b/Telegram/Views/Settings/SettingsStoragePage.xaml index e05b9fb458..dd09203360 100644 --- a/Telegram/Views/Settings/SettingsStoragePage.xaml +++ b/Telegram/Views/Settings/SettingsStoragePage.xaml @@ -622,7 +622,7 @@ - + - + + Padding="0,3,0,0"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Telegram/Views/Gifts/Popups/GiftCraftPopup.xaml.cs b/Telegram/Views/Gifts/Popups/GiftCraftPopup.xaml.cs new file mode 100644 index 0000000000..fd2c1c07be --- /dev/null +++ b/Telegram/Views/Gifts/Popups/GiftCraftPopup.xaml.cs @@ -0,0 +1,1492 @@ +// +// Copyright (c) Fela Ameghino 2015-2026 +// +// Distributed under the GNU General Public License v3.0. (See accompanying +// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt) +// + +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.UI.Xaml.Media; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using Telegram.Common; +using Telegram.Controls; +using Telegram.Controls.Cells; +using Telegram.Controls.Gifts; +using Telegram.Controls.Media; +using Telegram.Navigation; +using Telegram.Navigation.Services; +using Telegram.Services; +using Telegram.Streams; +using Telegram.Td; +using Telegram.Td.Api; +using Telegram.Views.Stars.Popups; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Text; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Documents; +using Windows.UI.Xaml.Hosting; +using Windows.UI.Xaml.Media; + +namespace Telegram.Views.Gifts.Popups +{ + public sealed partial class GiftCraftPopup : ContentPopup + { + private readonly IClientService _clientService; + private readonly INavigationService _navigationService; + + private readonly ReceivedGift[] _items = [null, null, null, null]; + + private readonly ReceivedGift _reference; + + private GiftsForCrafting _crafting; + + private TaskCompletionSource _crafted; + + public GiftCraftPopup(IClientService clientService, INavigationService navigationService, ReceivedGift gift) + { + InitializeComponent(); + + _clientService = clientService; + _navigationService = navigationService; + + _items[0] = gift; + _reference = gift; + + _cube = ElementCompositionPreview.GetElementVisual(Cube); + _cube.CenterPoint = new Vector3(FACE_CENTER, FACE_CENTER, -FACE_CENTER); + + for (int i = 0; i < _items.Length; i++) + { + UpdateContent(Gifts.Children[i] as Button, i, _items[i]); + } + + UpdateSelection(); + + InitializeGiftsForCrafting(); + InitializeGiftVariants(); + InitializeCube(); + } + + private record CraftingColors(Color Center, Color Edge, Color Pattern, Color Button1, Color Button2) + { + public CraftingColors(int center, int edge, int pattern, int button1, int button2) + : this(center.ToColor(), edge.ToColor(), pattern.ToColor(), button1.ToColor(), button2.ToColor()) + { + + } + } + + private readonly CraftingColors[] _colors = new[] + { + new CraftingColors(0x2C4359, 0x232E3F, 0x040C1A, 0x10A5DF, 0x2091E9), + new CraftingColors(0x2C4359, 0x232E3F, 0x040C1A, 0x10A5DF, 0x2091E9), + new CraftingColors(0x2C4359, 0x232E3F, 0x040C1A, 0x10A5DF, 0x2091E9), + new CraftingColors(0x1C4843, 0x1A2E37, 0x040C1A, 0x3ACA49, 0x007D9E), + new CraftingColors(0x5D2E16, 0x371B1A, 0x040C1A, 0xE27519, 0xDD4819), + }; + + private void InitializeCube() + { + Pattern.Center = new RectangleF(new Vector2(0, 0), new Vector2(140)); + + CreateFace(Face2, Quaternion.Identity); + CreateFace(Face3, CreateRotationY(-90)); + CreateFace(Face4, CreateRotationY(90)); + CreateFace(Face5, CreateRotationY(180)); + CreateFace(Face6, CreateRotationX(90)); + CreateFace(Face1, CreateRotationX(-90)); + + CreateGift(Gift1, new Vector3(-104, -40, 0)); + CreateGift(Gift2, new Vector3(-104, 40, 0)); + CreateGift(Gift3, new Vector3(104, -40, 0)); + CreateGift(Gift4, new Vector3(104, 40, 0)); + } + + private async void InitializeGiftsForCrafting() + { + if (_reference.Gift is not SentGiftUpgraded upgraded) + { + return; + } + + var response = await _clientService.SendAsync(new GetGiftsForCrafting(upgraded.Gift.RegularGiftId, string.Empty, 100)); + if (response is GiftsForCrafting crafting) + { + _crafting = crafting; + UpdateSelection(); + } + } + + private async void InitializeGiftVariants() + { + if (_reference.Gift is not SentGiftUpgraded upgraded) + { + return; + } + + var response = await _clientService.SendAsync(new GetUpgradedGiftVariants(upgraded.Gift.RegularGiftId, false, true)); + if (response is GiftUpgradeVariants variants) + { + var count = Math.Min(variants.Models.Count, 3); + + for (int i = count - 1; i >= 0; i--) + { + var player = new CustomEmojiIcon(); + player.LoopCount = 0; + player.Source = DelayedFileSource.FromSticker(_clientService, variants.Models[i].Sticker); + player.HorizontalAlignment = HorizontalAlignment.Left; + player.FlowDirection = FlowDirection.LeftToRight; + player.IsHitTestVisible = false; + player.Margin = new Thickness(0, -2, 0, -2); + player.Width = 16; + player.Height = 16; + player.FrameSize = new Windows.Foundation.Size(16, 16); + + Variants.Children.Insert(0, player); + } + } + } + + private void UpdateSelection() + { + UpdateText(); + UpdateProbability(); + UpdateColors(); + } + + private class BackdropComparer : IEqualityComparer + { + public bool Equals(UpgradedGiftBackdrop x, UpgradedGiftBackdrop y) + { + return x.Id == y.Id; + } + + public int GetHashCode(UpgradedGiftBackdrop obj) + { + return obj.Id.GetHashCode(); + } + } + + private class SymbolComparer : IEqualityComparer + { + public bool Equals(UpgradedGiftSymbol x, UpgradedGiftSymbol y) + { + return x.Sticker.Id == y.Sticker.Id; + } + + public int GetHashCode(UpgradedGiftSymbol obj) + { + return obj.Sticker.Id.GetHashCode(); + } + } + + private void UpdateColors() + { + var count = _items.Count(x => x != null); + var colors = _colors[Math.Max(0, count - 1)]; + + var radial = new RadialGradientBrush(); + radial.Center = new Point(0.5f, 0.3f); + radial.GradientOrigin = new Point(0.5f, 0.3f); + radial.RadiusX = 0.5; + radial.RadiusY = 0.5; + radial.GradientStops.Add(new GradientStop { Color = colors.Center }); + radial.GradientStops.Add(new GradientStop { Color = colors.Edge, Offset = 1 }); + + BackgroundRoot.Background = radial; + Pattern.Foreground = new SolidColorBrush(colors.Pattern); + + if (count > 0) + { + var linear = new LinearGradientBrush(); + linear.GradientStops.Add(new GradientStop { Color = colors.Button1 }); + linear.GradientStops.Add(new GradientStop { Color = colors.Button2, Offset = 1 }); + + CraftButtonBackground.Background = linear; + CraftButtonBackground.Visibility = Visibility.Visible; + } + else + { + CraftButtonBackground.Visibility = Visibility.Collapsed; + } + } + + private void UpdateProbability() + { + Attributes1.Children.Clear(); + Attributes2.Children.Clear(); + + var count = _items.Count(x => x != null); + if (count > 0) + { + var probability = _crafting?.AttributePersistenceProbabilities[_items.Length - 1]; + var sum = 0f; + + var backdrops = new Dictionary(new BackdropComparer()); + var symbols = new Dictionary(new SymbolComparer()); + + foreach (var gift in _items) + { + if (gift?.Gift is not SentGiftUpgraded upgraded) + { + continue; + } + + backdrops.TryGetValue(upgraded.Gift.Backdrop, out int backdropCount); + backdrops[upgraded.Gift.Backdrop] = ++backdropCount; + + symbols.TryGetValue(upgraded.Gift.Symbol, out int symbolCount); + symbols[upgraded.Gift.Symbol] = ++symbolCount; + + sum += upgraded.Gift.CraftProbabilityPerMille / 1000f; + } + + var backdropTarget = Attributes1; + var symbolTarget = backdrops.Count + symbols.Count > 4 + ? Attributes2 + : Attributes1; + + if (probability != null) + { + foreach (var backdrop in backdrops) + { + backdropTarget.Children.Add(new GiftAttributeGauge(_clientService, backdrop.Key, probability.PersistenceChancePerMille[backdrop.Value - 1] / 1000f)); + } + + foreach (var symbol in symbols) + { + symbolTarget.Children.Add(new GiftAttributeGauge(_clientService, symbol.Key, probability.PersistenceChancePerMille[symbol.Value - 1] / 1000f)); + } + } + + VariantsRoot.Visibility = backdrops.Count + symbols.Count > 4 + ? Visibility.Collapsed + : Visibility.Visible; + + InitializeProbability(sum); + } + else + { + Attributes1.Children.Add(new GiftAttributeGauge(_clientService, null as UpgradedGiftBackdrop, 0)); + Attributes1.Children.Add(new GiftAttributeGauge(_clientService, null as UpgradedGiftSymbol, 0)); + + VariantsRoot.Visibility = Visibility.Visible; + + InitializeProbability(0); + } + } + + private void InitializeProbability(float probability) + { + Probability.Text = (probability * 100).ToString("0.##") + "%"; + CraftingProbability.Text = string.Format(Strings.GiftCraftProgressSuccessChance, (probability * 100).ToString("0.##") + "%"); + + CraftButtonText.Text = Strings.GiftCraftButton; + + if (probability > 0) + { + TextBlockHelper.SetMarkdown(CraftButtonInfo, string.Format(Strings.GiftCraftSuccessChance, (probability * 100).ToString("0.##") + "%")); + } + else + { + TextBlockHelper.SetMarkdown(CraftButtonInfo, Strings.GiftCraftButtonEmpty); + } + + var compositor = BootStrapper.Current.Compositor; + var visual = compositor.CreateShapeVisual(); + + var background = compositor.CreateEllipseGeometry(); + background.Radius = new Vector2(34); + background.Center = new Vector2(36); + background.TrimStart = 0.25f; + + var backgroundShape = compositor.CreateSpriteShape(background); + backgroundShape.StrokeBrush = compositor.CreateColorBrush(Color.FromArgb(0x55, 255, 255, 255)); + backgroundShape.StrokeThickness = 4; + backgroundShape.StrokeStartCap = CompositionStrokeCap.Round; + backgroundShape.StrokeEndCap = CompositionStrokeCap.Round; + backgroundShape.RotationAngleInDegrees = 45 + 90; + backgroundShape.CenterPoint = new Vector2(36); + + var foreground = compositor.CreateEllipseGeometry(); + foreground.Radius = new Vector2(34); + foreground.Center = new Vector2(36); + foreground.TrimStart = 0.25f; + foreground.TrimEnd = 0.25f + (probability * 0.75f); + + var foregroundShape = compositor.CreateSpriteShape(foreground); + foregroundShape.StrokeBrush = compositor.CreateColorBrush(Color.FromArgb(255, 255, 255, 255)); + foregroundShape.StrokeThickness = 4; + foregroundShape.StrokeStartCap = CompositionStrokeCap.Round; + foregroundShape.StrokeEndCap = CompositionStrokeCap.Round; + foregroundShape.RotationAngleInDegrees = 45 + 90; + foregroundShape.CenterPoint = new Vector2(36); + + visual.Shapes.Add(backgroundShape); + visual.Shapes.Add(foregroundShape); + visual.Size = new Vector2(72); + + ElementCompositionPreview.SetElementChildVisual(Gauge, visual); + } + + private void UpdateText() + { + if (_reference.Gift is not SentGiftUpgraded upgraded) + { + return; + } + + var any = _items.Any(x => x != null); + + TextBlockHelper.SetMarkdown(Text1, any ? Strings.GiftCraftText1 : Strings.GiftCraftTextEmpty1); + + var markdown = ClientEx.ParseMarkdown(any ? Strings.GiftCraftText2 : Strings.GiftCraftTextEmpty2); + var previous = 0; + + var paragraph = new Paragraph(); + + foreach (var entity in markdown.Entities) + { + if (entity.Offset > previous) + { + paragraph.Inlines.Add(markdown.Text.Substring(previous, entity.Offset - previous)); + } + + var text = markdown.Text.Substring(entity.Offset, entity.Length); + if (text == "{0}" || text == "{0} #{1}") + { + var player = new CustomEmojiIcon(); + player.LoopCount = 0; + player.Source = DelayedFileSource.FromSticker(_clientService, upgraded.Gift.Model.Sticker); + player.HorizontalAlignment = HorizontalAlignment.Left; + player.FlowDirection = FlowDirection.LeftToRight; + player.IsHitTestVisible = false; + player.Margin = new Thickness(0, -2, 0, -6); + + var inline = new InlineUIContainer(); + inline.Child = player; + + // If the Span starts with a InlineUIContainer the RichTextBlock bugs and shows ellipsis + if (previous == 0) + { + paragraph.Inlines.Add(Icons.ZWNJ); + } + + paragraph.Inlines.Add(inline); + paragraph.Inlines.Add(Icons.ZWNJ); + + paragraph.Inlines.Add(Icons.Space); + + if (any) + { + paragraph.Inlines.Add(string.Format(text, upgraded.Gift.Title, upgraded.Gift.Number.ToString("N0")), FontWeights.SemiBold); + } + else + { + paragraph.Inlines.Add(string.Format(text, upgraded.Gift.Title), FontWeights.SemiBold); + } + } + else + { + paragraph.Inlines.Add(text, FontWeights.SemiBold); + } + + previous = entity.Offset + entity.Length; + } + + if (markdown.Text.Length > previous) + { + paragraph.Inlines.Add(markdown.Text.Substring(previous, markdown.Text.Length - previous)); + } + + Text2.Blocks.Clear(); + Text2.Blocks.Add(paragraph); + } + + private async void Button_Click(object sender, RoutedEventArgs e) + { + if (sender is Button button) + { + SelectGift(button, Gifts.Children.IndexOf(button)); + } + } + + private async void SelectGift(Button target, int index) + { + if (_items[index] != null) + { + UpdateContent(target, index, null); + UpdateSelection(); + return; + } + + Hide(); + + var popup = new GiftCraftChoosePopup(_clientService, _navigationService, _reference, _crafting); + + var confirm = await _navigationService.ShowPopupAsync(popup); + if (confirm == ContentDialogResult.Primary && popup.SelectedGift != null) + { + UpdateContent(target, index, popup.SelectedGift); + UpdateSelection(); + } + + await this.ShowQueuedAsync(XamlRoot); + } + + private void UpdateContent(Button target, int index, ReceivedGift gift) + { + _items[index] = gift; + + var overlay = Overlays.Children[index] as Grid; + var probability = overlay.Children[0] as BadgeControl; + var dismiss = overlay.Children[1] as Border; + + if (gift == null) + { + overlay.Visibility = Visibility.Collapsed; + target.Content = new TextBlock + { + Text = Icons.AddCircleFilled, + FontFamily = BootStrapper.Current.Resources["SymbolThemeFontFamily"] as FontFamily, + FontSize = 48, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }; + } + else if (gift.Gift is SentGiftUpgraded upgraded) + { + var background = new PatternBackground + { + Margin = new Thickness(-1), + CornerRadius = new CornerRadius(16), + Content = new AnimatedImage + { + AutoPlay = true, + Width = 64, + Height = 64, + FrameSize = new Windows.Foundation.Size(64, 64), + DecodeFrameType = Windows.UI.Xaml.Media.Imaging.DecodePixelType.Logical, + Source = DelayedFileSource.FromSticker(_clientService, upgraded.Gift.Model.Sticker) + } + }; + + background.Update(_clientService, upgraded.Gift); + + overlay.Visibility = Visibility.Visible; + target.Content = background; + + probability.Text = ((upgraded.Gift.CraftProbabilityPerMille / 1000d) * 100).ToString("0.##") + "%"; + + var badge = new SolidColorBrush(upgraded.Gift.Backdrop.Colors.EdgeColor.ToColor().Darken()); + probability.Background = badge; + dismiss.Background = badge; + } + } + + #region Cube + + private readonly Visual _cube; + + private const float FACE_SIZE = 96; + private const float FACE_CENTER = 48; + private const float FACE_SCALE = 64f / 96f; + + private void CreateFace(Grid element, Quaternion rotation) + { + var visual = ElementCompositionPreview.GetElementVisual(element); + visual.CenterPoint = new Vector3(FACE_CENTER, FACE_CENTER, -FACE_CENTER); + visual.Orientation = rotation; + visual.BackfaceVisibility = CompositionBackfaceVisibility.Hidden; + visual.RotationAngle = 0; + + if (rotation.IsIdentity) + { + return; + } + + for (int i = 0; i < element.Children.Count; i++) + { + if (i == 1) + { + element.Children.RemoveAt(1); + i++; + + continue; + } + + element.Children[i].Visibility = Visibility.Visible; + } + } + + private static Quaternion CreateRotationY(float angle) + { + return Quaternion.CreateFromAxisAngle(Vector3.UnitY, DegreesToRadians(angle)); + } + + private static Quaternion CreateRotationX(float angle) + { + return Quaternion.CreateFromAxisAngle(Vector3.UnitX, DegreesToRadians(angle)); + } + + private static float DegreesToRadians(float degrees) + { + return degrees * (MathF.PI / 180f); + } + + private void CreateGift(UIElement element, Vector3 offset) + { + ElementCompositionPreview.SetIsTranslationEnabled(element, true); + + var visual = ElementCompositionPreview.GetElementVisual(element); + visual.Properties.InsertVector3("Translation", offset); + visual.Scale = new Vector3(FACE_SCALE); + visual.CenterPoint = new Vector3(FACE_CENTER, FACE_CENTER, -FACE_CENTER); + visual.Orientation = Quaternion.Identity; + visual.BackfaceVisibility = CompositionBackfaceVisibility.Hidden; + visual.RotationAngleInDegrees = 0; + visual.Opacity = 1; + } + + private bool _spinning; + + private record Face(Visual Visual, float Duration, float Rotations, float Force, Vector3 Axis) + { + public Quaternion Orientation { get; set; } = Quaternion.Identity; + + public bool Snapped { get; set; } + + public float? LastHiddenTime { get; set; } + + public int LastFaceIndex { get; set; } + + public float LastFaceRotationAngle { get; set; } + } + + private record Spin(float Duration, float Rotations, float Force); + + private Spin[][] _spins = new[] + { + new[] + { + new Spin(2244, 3.7f, 1.5f), + }, + new[] + { + //new Spin(1620, 1.2f, 1.5f), + //new Spin(2244, 7.0f, 1.5f), + new Spin(1620, 1.2f, 3.0f), + new Spin(1620, 4.9f, 1.5f), + }, + new[] + { + new Spin(1620, 1.2f, 3.0f), + new Spin(1620, 1.6f, 2.0f), + //new Spin(1620, 2.3f, 2.0f), // 4.3 + new Spin(1620, 5.1f, 1.5f), + //new Spin(1620, 1.2f, 1.8f), + //new Spin(2244, 3.7f, 1.5f), + //new Spin(2244, 7.1f, 1.5f), + }, + new[] + { + new Spin(1333, 1.2f, 3.0f), + new Spin(1333, 1.6f, 2.0f), + new Spin(1333, 2.3f, 2.0f), // 4.3 + new Spin(1333, 5.1f, 1.5f), + }, + }; + + private void TransitionToCrafting() + { + var reference = _items.FirstOrDefault(x => x != null); + if (reference.Gift is not SentGiftUpgraded upgraded) + { + return; + } + + var visual1 = ElementComposition.GetElementVisual(PrepareRoot); + var visual2 = ElementComposition.GetElementVisual(CraftingRoot); + var visual3 = ElementComposition.GetElementVisual(Overlays); + + var show = visual1.Compositor.CreateScalarKeyFrameAnimation(); + show.InsertKeyFrame(0, 0); + show.InsertKeyFrame(1, 1); + + var hide = visual1.Compositor.CreateScalarKeyFrameAnimation(); + hide.InsertKeyFrame(0, 1); + hide.InsertKeyFrame(1, 0); + + visual1.StartAnimation("Opacity", hide); + visual2.StartAnimation("Opacity", show); + visual3.StartAnimation("Opacity", hide); + + CraftingName.Text = upgraded.Gift.ToName(); + CraftingRoot.Visibility = Visibility.Visible; + } + + private ulong _tickCount; + private float _accumulated; + + private readonly HashSet _excludedFaces = new(); + + private Face[] _faces; + private int _faceIndex; + + private Quaternion _orientation = Quaternion.Identity; + + private void OnRendering(object sender, object e) + { + var elapsed = Logger.TickCount - _tickCount; + + _tickCount = Logger.TickCount; + _accumulated += elapsed; + + var face = _faces[_faceIndex]; + var duration = face.Duration; + var rotations = face.Rotations; + var axis = face.Axis; + + var decay = CalculateSpinDecay(_accumulated, duration, face.Force); + + _cube.Orientation = SlerpOrientation(face, _orientation, decay, _faceIndex == _faces.Length - 1, _excludedFaces); + + var facesCount = _faceIndex; + var finalDecay = CalculateSpinDecay(face.Duration, face.Duration, face.Force); + var finalDuration = duration * finalDecay; + + if (_accumulated >= duration - Constants.FastAnimation.TotalMilliseconds * 1 && _faceIndex != _faces.Length - 1) + { + facesCount++; + + if (_faces[facesCount].Orientation.IsIdentity) + { + var finalOrientation = SlerpOrientation(face, _orientation, finalDecay, false, _excludedFaces); + + var childFace = _faces[facesCount]; + var child = childFace.Visual; + + childFace.Orientation = GetRotationToFront(finalOrientation, _excludedFaces); + + var compositor = _cube.Compositor; + + var linear = compositor.CreateLinearEasingFunction(); + + var orientation = compositor.CreateQuaternionKeyFrameAnimation(); + orientation.InsertKeyFrame(0, Quaternion.Identity); + orientation.InsertKeyFrame(1, childFace.Orientation, linear); + orientation.Duration = Constants.FastAnimation; + + var offset = compositor.CreateVector3KeyFrameAnimation(); + offset.InsertKeyFrame(1, Vector3.Zero, linear); + offset.Duration = Constants.FastAnimation; + + var scale = compositor.CreateVector3KeyFrameAnimation(); + scale.InsertKeyFrame(1, Vector3.One, linear); + scale.Duration = Constants.FastAnimation; + + child.StartAnimation("Orientation", orientation); + child.StartAnimation("Translation", offset); + child.StartAnimation("Scale", scale); + } + } + + for (int i = 0; i <= _faceIndex; i++) + { + _faces[i].Visual.Orientation = SlerpOrientation(face, _faces[i].Orientation, decay, _faceIndex == _faces.Length - 1, null); + } + + if (_accumulated >= duration) + { + float overflow = _accumulated - duration; + + for (int i = 0; i <= _faceIndex; i++) + { + var childFace = _faces[i]; + var child = childFace.Visual; + + childFace.Orientation = child.Orientation; + } + + _orientation = _cube.Orientation; + _accumulated = overflow; + + _faceIndex++; + + if (_faceIndex == _faces.Length - 1) + { + var finalFace = _faces[^1]; + finalDecay = CalculateSpinDecay(finalFace.Duration, finalFace.Duration, finalFace.Force); + + var finalSpinOrientation = Quaternion.Concatenate(_orientation, Quaternion.CreateFromAxisAngle(finalFace.Axis, MathF.PI * (finalFace.Rotations * finalDecay))); + var targetSnapOrientation = GetNearestCardinalOrientation(finalSpinOrientation, _excludedFaces, out int faceIndex, out float rotationAngle); + + finalFace.LastHiddenTime = FindLastHiddenMoment(finalFace.Axis, finalFace.Rotations, finalFace.Duration, finalFace.Force, faceIndex, _orientation); + finalFace.LastFaceIndex = faceIndex; + finalFace.LastFaceRotationAngle = rotationAngle; + } + else if (_faceIndex >= _faces.Length) + { + Windows.UI.Xaml.Media.CompositionTarget.Rendering -= OnRendering; + TransitionToCompleted(); + } + } + } + + private async void TransitionToCompleted(int faceIndex, float rotationAngle) + { + if (_crafted == null) + { + TransitionToFailed(faceIndex, rotationAngle); + return; + } + else if (_crafted.Task.IsCompleted) + { + if (_crafted.Task.Result is ReceivedGift receivedGift) + { + TransitionToSucceeded(receivedGift, faceIndex, rotationAngle); + } + else + { + TransitionToFailed(faceIndex, rotationAngle); + } + } + else + { + var response = await _crafted.Task; + if (response is ReceivedGift receivedGift) + { + TransitionToSucceeded(receivedGift, faceIndex, rotationAngle); + } + else + { + TransitionToFailed(faceIndex, rotationAngle); + } + } + } + + private void TransitionToFailed(int faceIndex, float rotationAngle) + { + var target = faceIndex switch + { + 0 => Face1, + 1 => Face2, + 2 => Face4, + 3 => Face3, + 4 => Face5, + 5 => Face6, + _ => null + }; + + if (target != null) + { + var visual = ElementComposition.GetElementVisual(target); + visual.RotationAngle = -rotationAngle; + + var animated = new AnimatedImage + { + Source = new LocalFileSource("ms-appx:///Assets/Animations/GiftCraftingFailed.tgs"), + AutoPlay = true, + Width = 48, + Height = 48, + FrameSize = new Windows.Foundation.Size(48, 48), + LoopCount = 1, + DecodeFrameType = Windows.UI.Xaml.Media.Imaging.DecodePixelType.Logical, + IsCachingEnabled = false, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }; + + for (int i = 0; i < target.Children.Count; i++) + { + if (i == 1) + { + target.Children.RemoveAt(1); + i++; + + continue; + } + + target.Children[i].Visibility = Visibility.Collapsed; + } + + target.Children.Add(animated); + } + } + + private void TransitionToSucceeded(ReceivedGift receivedGift, int faceIndex, float rotationAngle) + { + var target = faceIndex switch + { + 0 => Face1, + 1 => Face2, + 2 => Face4, + 3 => Face3, + 4 => Face5, + 5 => Face6, + _ => null + }; + + if (target != null && receivedGift.Gift is SentGiftUpgraded success) + { + var visual = ElementComposition.GetElementVisual(target); + visual.RotationAngle = -rotationAngle; + + var pattern = new PatternBackground + { + Margin = new Thickness(-1), + CornerRadius = new CornerRadius(16), + Content = new AnimatedImage + { + AutoPlay = true, + Width = 64, + Height = 64, + FrameSize = new Windows.Foundation.Size(64, 64), + DecodeFrameType = Windows.UI.Xaml.Media.Imaging.DecodePixelType.Logical, + Source = DelayedFileSource.FromSticker(_clientService, success.Gift.Model.Sticker) + } + }; + + pattern.Update(_clientService, success.Gift); + + for (int i = 0; i < target.Children.Count; i++) + { + if (i == 1) + { + target.Children.RemoveAt(1); + i++; + + continue; + } + + target.Children[i].Visibility = Visibility.Collapsed; + } + + target.Children.Add(pattern); + } + } + + private async void TransitionToCompleted() + { + if (_crafted == null) + { + TransitionToFailed(); + return; + } + else if (_crafted.Task.IsCompleted) + { + if (_crafted.Task.Result is ReceivedGift receivedGift) + { + TransitionToSucceeded(receivedGift); + } + else + { + TransitionToFailed(); + } + } + else + { + var response = await _crafted.Task; + if (response is ReceivedGift receivedGift) + { + TransitionToSucceeded(receivedGift); + } + else + { + TransitionToFailed(); + } + } + } + + private void TransitionToFailed() + { + var visual1 = ElementComposition.GetElementVisual(CraftingRoot); + var visual2 = ElementComposition.GetElementVisual(FailedRoot); + var visual3 = ElementComposition.GetElementVisual(FailedBackground); + + var show = visual1.Compositor.CreateScalarKeyFrameAnimation(); + show.InsertKeyFrame(0, 0); + show.InsertKeyFrame(1, 1); + + var hide = visual1.Compositor.CreateScalarKeyFrameAnimation(); + hide.InsertKeyFrame(0, 1); + hide.InsertKeyFrame(1, 0); + + visual1.StartAnimation("Opacity", hide); + visual2.StartAnimation("Opacity", show); + visual3.StartAnimation("Opacity", show); + + TextBlockHelper.SetMarkdown(FailedName, Locale.Declension(Strings.R.GiftCraftFailedText, _items.Count(x => x != null))); + FailedRoot.Visibility = Visibility.Visible; + FailedBackground.Visibility = Visibility.Visible; + FailedList.Children.Clear(); + + foreach (var item in _items) + { + if (item == null) + { + continue; + } + + var cell = new BurnedGiftCell(); + cell.UpdateGift(_clientService, item); + + FailedList.Children.Add(cell); + } + } + + private void TransitionToSucceeded(ReceivedGift receivedGift) + { + Hide(); + _navigationService.ShowPopup(new ReceivedGiftPopup(_clientService, _navigationService, receivedGift, _clientService.MyId, null)); + return; + + var size = 240; + var center = 120; + + var compositor = Window.Current.Compositor; + var shapeVisual = compositor.CreateShapeVisual(); + shapeVisual.Size = new Vector2(size); + + for (int i = 0; i < 6; i++) + { + CanvasGeometry geometry; + using (var builder = new CanvasPathBuilder(null)) + { + // Calculate start and end angles (in radians) + float startAngle = -(float)(Math.PI * 2 / 24); // Starting at 0 degrees + float sweepAngle = (float)(Math.PI * 2 / 12); // 30 degrees in radians (2π/12) + + // Calculate start and end points + Vector2 startPoint = new Vector2( + center + center * (float)Math.Cos(startAngle), + center + center * (float)Math.Sin(startAngle) + ); + + Vector2 endPoint = new Vector2( + center + center * (float)Math.Cos(startAngle + sweepAngle), + center + center * (float)Math.Sin(startAngle + sweepAngle) + ); + + // Begin the path at the start point + builder.BeginFigure(startPoint); + + // Add the arc + builder.AddArc( + endPoint, // End point of the arc + center, // X radius + center, // Y radius + 0, // Rotation angle (0 for circular arc) + CanvasSweepDirection.Clockwise, + CanvasArcSize.Small // Small arc (less than 180 degrees) + ); + + builder.AddLine(new Vector2(center, center)); + + builder.EndFigure(CanvasFigureLoop.Closed); + + geometry = CanvasGeometry.CreatePath(builder); + } + + + var ellipse = compositor.CreatePathGeometry(new CompositionPath(geometry)); + + var fillGradient = compositor.CreateLinearGradientBrush(); + fillGradient.ColorStops.Add(compositor.CreateColorGradientStop(0, Color.FromArgb(0, 255, 0, 0))); + fillGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.15f, Color.FromArgb(0, 255, 0, 0))); + fillGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.32f, Color.FromArgb(0x55, 255, 0, 0))); + fillGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.55f, Color.FromArgb(0x55, 255, 0, 0))); + fillGradient.ColorStops.Add(compositor.CreateColorGradientStop(1, Color.FromArgb(0, 255, 0, 0))); + + var strokeGradient = compositor.CreateLinearGradientBrush(); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(0, Color.FromArgb(0, 255, 0, 0))); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.2f, Color.FromArgb(0, 255, 0, 0))); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.40f, Color.FromArgb(0x55, 255, 0, 0))); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.50f, Color.FromArgb(0x88, 255, 0, 0))); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(0.80f, Color.FromArgb(0, 255, 0, 0))); + strokeGradient.ColorStops.Add(compositor.CreateColorGradientStop(1, Color.FromArgb(0, 255, 0, 0))); + + var ellipseShape = compositor.CreateSpriteShape(ellipse); + ellipseShape.FillBrush = fillGradient; + ellipseShape.StrokeBrush = strokeGradient; + ellipseShape.StrokeThickness = 2; + ellipseShape.CenterPoint = new Vector2(center); + ellipseShape.RotationAngleInDegrees = i * 2 * 30; + + shapeVisual.Shapes.Add(ellipseShape); + } + + var easing = compositor.CreateLinearEasingFunction(); + + var rotationAngle = compositor.CreateScalarKeyFrameAnimation(); + rotationAngle.InsertKeyFrame(0, 0); + rotationAngle.InsertKeyFrame(1, 360, easing); + rotationAngle.IterationBehavior = AnimationIterationBehavior.Forever; + rotationAngle.Duration = TimeSpan.FromSeconds(10); + + shapeVisual.CenterPoint = new Vector3(center); + shapeVisual.StartAnimation("RotationAngleInDegrees", rotationAngle); + + Success.Width = size; + Success.Height = size; + Success.Margin = new Thickness(0, -((size - 96) / 2), 0, -((size - 96) / 2)); + ElementCompositionPreview.SetElementChildVisual(Success, shapeVisual); + } + + public static double RadiansToDegrees(double radians) + { + return radians * (180.0 / Math.PI); + } + + private Quaternion SlerpOrientation(Face face, Quaternion orientation, float decay, bool final, HashSet excludedFaces) + { + var spinRotation = Quaternion.CreateFromAxisAngle(face.Axis, MathF.PI * (decay * face.Rotations)); + var currentOrientation = Quaternion.Concatenate(orientation, spinRotation); + + float snapThreshold = 0.7f; + float normalizedTime = Math.Min(1.0f, _accumulated / face.Duration); + + if (final && _accumulated >= face.LastHiddenTime) + { + if (excludedFaces != null && !face.Snapped) + { + face.Snapped = true; + TransitionToCompleted(face.LastFaceIndex, face.LastFaceRotationAngle); + } + } + + if (normalizedTime > snapThreshold && final) + { + float finalDecay = CalculateSpinDecay(face.Duration, face.Duration, face.Force); + + var finalSpinOrientation = Quaternion.Concatenate(_orientation, Quaternion.CreateFromAxisAngle(face.Axis, MathF.PI * (face.Rotations * finalDecay))); + var targetSnapOrientation = GetNearestCardinalOrientation(finalSpinOrientation, _excludedFaces, out int faceIndex, out float rotationAngle); + + if (excludedFaces != null && !face.Snapped) + { + face.Snapped = true; + TransitionToCompleted(faceIndex, rotationAngle); + } + + float snapBlend = (normalizedTime - snapThreshold) / (1.0f - snapThreshold); + snapBlend = snapBlend * snapBlend * (3.0f - 2.0f * snapBlend); + + if (_excludedFaces != excludedFaces) + { + var straighteningRotation = Quaternion.Concatenate( + Quaternion.Inverse(finalSpinOrientation), + targetSnapOrientation + ); + + var frontFaceOrientation = Quaternion.Concatenate(orientation, Quaternion.CreateFromAxisAngle(face.Axis, MathF.PI * (face.Rotations * finalDecay))); + var frontFaceSnapped = Quaternion.Concatenate( + frontFaceOrientation, + straighteningRotation + ); + + targetSnapOrientation = frontFaceSnapped; + } + + return Quaternion.Slerp(currentOrientation, targetSnapOrientation, snapBlend); + } + + return currentOrientation; + } + + private float? FindLastHiddenMoment(Vector3 axis, float totalRotations, float duration, float force, int targetFaceIndex, Quaternion startingOrientation) + { + Vector3 targetFaceNormal = _faceNormals[targetFaceIndex]; + Vector3 cameraDirection = new Vector3(0, 0, -1); // Camera looks at -Z + + int samples = 100; + float? lastHiddenTime = null; + + for (int i = samples; i >= 0; i--) + { + float t = (i / (float)samples) * duration; + float decay = CalculateSpinDecay(t, duration, force); + + var spinRotation = Quaternion.CreateFromAxisAngle(axis, MathF.PI * (decay * totalRotations)); + var orientation = Quaternion.Concatenate(startingOrientation, spinRotation); + + Vector3 worldNormal = Vector3.Transform(targetFaceNormal, orientation); + + float dot = Vector3.Dot(worldNormal, -cameraDirection); + + if (dot < 0) // Face is hidden + { + lastHiddenTime = t; + break; + } + } + + return lastHiddenTime; + } + + public float CalculateSpinDecay(float position, float duration, float force = 1.0f) + { + if (duration <= 0) return 0f; + + float normalizedTime = Math.Clamp(position / duration, 0, 1); + + float decayRate = 1.0f / MathF.Max(0.1f, force); + float decay = MathF.Exp(-decayRate * normalizedTime * 5.0f); + + return 1 - Math.Clamp(decay, 0, 1); + } + + private Vector3 CalculateAxis(UIElement element) + { + var transform1 = element.TransformToVisual(this); + var point1 = transform1.TransformPoint(new Point()).ToVector2(); + + var transform2 = Cube.TransformToVisual(this); + var point2 = transform2.TransformPoint(new Point()).ToVector2(); + + var x1 = point1.X + ((element.ActualSize.X * FACE_SCALE) / 2); + var y1 = point1.Y + ((element.ActualSize.Y * FACE_SCALE) / 2); + + var x2 = point2.X + ((Cube.ActualSize.X * 1) / 2); + var y2 = point2.Y + ((Cube.ActualSize.Y * 1) / 2); + + float dx = x1 - x2; + float dy = y1 - y2; + + float angleRadians = MathF.Atan2(dy, dx); + Vector2 dir2D = new Vector2( + MathF.Cos(-angleRadians), + MathF.Sin(-angleRadians) + ); + + dir2D = -dir2D; + + return Vector3.Normalize(new Vector3( + dir2D.Y, + dir2D.X, + 0f + )); + } + + private static readonly Vector3[] _faceNormals = new[] + { + new Vector3(0, 1, 0), // [1] Top + new Vector3(0, 0, 1), // [2] Front (center) + new Vector3(1, 0, 0), // [3] Right + new Vector3(-1, 0, 0), // [4] Left + new Vector3(0, 0, -1), // [5] Back + new Vector3(0, -1, 0) // [6] Bottom + }; + + private Quaternion GetRotationToFront(Quaternion orientation, HashSet excludedFaces) + { + int facingFaceIndex = GetNearestFaceIndex(orientation, excludedFaces); + if (facingFaceIndex == -1) + { + return orientation; + } + + if (excludedFaces != null) + { + excludedFaces.Add(facingFaceIndex); + } + + Vector3 fromNormal = _faceNormals[1]; + Vector3 toNormal = _faceNormals[facingFaceIndex]; + + Vector3 rotationAxis = Vector3.Cross(fromNormal, toNormal); + float rotationAngle = MathF.Acos(Vector3.Dot( + Vector3.Normalize(fromNormal), + Vector3.Normalize(toNormal) + )); + + Quaternion faceSwapRotation; + if (rotationAxis.LengthSquared() < 0.0001f) + { + if (Vector3.Dot(fromNormal, toNormal) > 0) + { + faceSwapRotation = Quaternion.Identity; + } + else + { + // 180° flip - choose perpendicular axis + Vector3 perpAxis = Math.Abs(fromNormal.X) < 0.9f + ? new Vector3(1, 0, 0) + : new Vector3(0, 1, 0); + rotationAxis = Vector3.Cross(fromNormal, perpAxis); + faceSwapRotation = Quaternion.CreateFromAxisAngle( + Vector3.Normalize(rotationAxis), + MathF.PI + ); + } + } + else + { + faceSwapRotation = Quaternion.CreateFromAxisAngle( + Vector3.Normalize(rotationAxis), + rotationAngle + ); + } + + Quaternion newOrientation = orientation * faceSwapRotation; + return newOrientation; + } + + private void Craft_Click(object sender, RoutedEventArgs e) + { + if (_spinning) + { + Clear_Click(null, null); + return; + } + + var count = _items.Count(x => x != null); + if (count == 0) + { + VisualUtilities.ShakeView(CraftButton); + return; + } + + TransitionToCrafting(); + + var diff = _items.Length - count; + var spins = _spins[count - 1]; + + _orientation = Quaternion.Identity; + _accumulated = 0; + _tickCount = 0; + _excludedFaces.Clear(); + _excludedFaces.Add(1); + + _faces = new Face[count]; + _faceIndex = 0; + + int j = 0; + + for (int i = 0; i < _items.Length; i++) + { + var child = ElementComposition.GetElementVisual(Gifts.Children[i]); + + if (_items[i] == null) + { + var opacity = child.Compositor.CreateScalarKeyFrameAnimation(); + opacity.InsertKeyFrame(1, 0); + + child.StartAnimation("Opacity", opacity); + continue; + } + + if (j == 0) + { + var offset = child.Compositor.CreateVector3KeyFrameAnimation(); + offset.InsertKeyFrame(1, Vector3.Zero); + offset.Duration = Constants.SoftAnimation; + + var scale = child.Compositor.CreateVector3KeyFrameAnimation(); + scale.InsertKeyFrame(1, Vector3.One); + scale.Duration = Constants.SoftAnimation; + + child.StartAnimation("Translation", offset); + child.StartAnimation("Scale", scale); + } + + var spin = spins[j]; + + _faces[j++] = new Face(child, spin.Duration, spin.Rotations, spin.Force, CalculateAxis(Gifts.Children[i])); + } + + if (_faces.Length == 1) + { + var finalFace = _faces[^1]; + var finalDecay = CalculateSpinDecay(finalFace.Duration, finalFace.Duration, finalFace.Force); // decay at t=duration + + var finalSpinOrientation = Quaternion.Concatenate(Quaternion.Identity, Quaternion.CreateFromAxisAngle(finalFace.Axis, MathF.PI * (finalFace.Rotations * finalDecay))); + var targetSnapOrientation = GetNearestCardinalOrientation(finalSpinOrientation, _excludedFaces, out int faceIndex, out float rotationAngle); + + finalFace.LastHiddenTime = FindLastHiddenMoment(finalFace.Axis, finalFace.Rotations, finalFace.Duration, finalFace.Force, faceIndex, _orientation); + finalFace.LastFaceIndex = faceIndex; + finalFace.LastFaceRotationAngle = rotationAngle; + } + + _tickCount = Logger.TickCount; + + _spinning = true; + Windows.UI.Xaml.Media.CompositionTarget.Rendering += OnRendering; + + var receivedGiftIds = _items.Where(x => x != null).Select(x => x.ReceivedGiftId).ToList(); + var craftGifts = new CraftGift(receivedGiftIds); + + _crafted = new TaskCompletionSource(); + _clientService.Send(craftGifts, SetResult); + } + + private async void SetResult(Object result) + { + if (result is Error error) + { + _crafted.TrySetResult(result); + + this.BeginOnUIThread(() => + { + ToastPopup.ShowError(XamlRoot, error); + Clear_Click(null, null); + }); + } + else if (result is CraftGiftResultSuccess success) + { + _clientService.Send(new GetReceivedGift(success.ReceivedGiftId), SetResult); + } + else + { + _crafted.TrySetResult(result); + } + } + + private void Clear_Click(object sender, RoutedEventArgs e) + { + _spinning = false; + Windows.UI.Xaml.Media.CompositionTarget.Rendering -= OnRendering; + + ElementCompositionPreview.SetElementChildVisual(Success, null); + + _cube.Orientation = Quaternion.Identity; + + var visual1 = ElementComposition.GetElementVisual(PrepareRoot); + var visual3 = ElementComposition.GetElementVisual(Overlays); + visual1.Opacity = 1; + visual3.Opacity = 1; + + CraftingRoot.Visibility = Visibility.Collapsed; + FailedRoot.Visibility = Visibility.Collapsed; + FailedBackground.Visibility = Visibility.Collapsed; + + CreateFace(Face2, Quaternion.Identity); + CreateFace(Face3, CreateRotationY(-90)); + CreateFace(Face4, CreateRotationY(90)); + CreateFace(Face5, CreateRotationY(180)); + CreateFace(Face6, CreateRotationX(90)); + CreateFace(Face1, CreateRotationX(-90)); + + CreateGift(Gift1, new Vector3(-104, -40, 0)); + CreateGift(Gift2, new Vector3(-104, 40, 0)); + CreateGift(Gift3, new Vector3(104, -40, 0)); + CreateGift(Gift4, new Vector3(104, 40, 0)); + + for (int i = 0; i < _items.Length; i++) + { + _items[i] = null; + } + + UpdateSelection(); + } + + private int GetNearestFaceIndex(Quaternion orientation, HashSet excludedFaces) + { + Vector3 cameraDirection = new Vector3(0, 0, -1); // Camera looks at -Z + + var faceCandidates = new List<(int index, float dot)>(); + + for (int i = 0; i < _faceNormals.Length; i++) + { + if (excludedFaces.Contains(i)) + continue; + + Vector3 worldNormal = Vector3.Transform(_faceNormals[i], orientation); + float dot = Vector3.Dot(worldNormal, -cameraDirection); + + faceCandidates.Add((i, dot)); + } + + if (faceCandidates.Count == 0) + return -1; + + faceCandidates.Sort((a, b) => b.dot.CompareTo(a.dot)); + return faceCandidates[0].index; + } + + private Quaternion GetNearestCardinalOrientation(Quaternion orientation, HashSet excludedFaces, out int faceIndex, out float rotationAngle) + { + int bestFaceIndex = GetNearestFaceIndex(orientation, excludedFaces); + if (bestFaceIndex == -1) + { + faceIndex = -1; + rotationAngle = 0; + return orientation; + } + + // 0 => face 1 + // 1 => face 2 + // 2 => face 4 + // 3 => face 3 + // 4 => face 5 + // 5 => face 6 + + Vector3 targetFaceNormal = _faceNormals[bestFaceIndex]; + Vector3 desiredForward = new Vector3(0, 0, 1); // We want this face to point forward (+Z) + + Quaternion faceAlignment; + Vector3 rotationAxis = Vector3.Cross(targetFaceNormal, desiredForward); + + if (rotationAxis.LengthSquared() < 0.0001f) + { + if (Vector3.Dot(targetFaceNormal, desiredForward) > 0) + { + faceAlignment = Quaternion.Identity; + } + else + { + Vector3 perpAxis = Math.Abs(targetFaceNormal.X) < 0.9f + ? new Vector3(1, 0, 0) + : new Vector3(0, 1, 0); + faceAlignment = Quaternion.CreateFromAxisAngle(perpAxis, MathF.PI); + } + } + else + { + float angle = MathF.Acos(Math.Clamp(Vector3.Dot( + Vector3.Normalize(targetFaceNormal), + Vector3.Normalize(desiredForward) + ), -1f, 1f)); + faceAlignment = Quaternion.CreateFromAxisAngle(Vector3.Normalize(rotationAxis), angle); + } + + Quaternion bestOrientation = faceAlignment; + float bestDistance = float.MaxValue; + float bestRotationAngle = 0; + + for (int i = 0; i < 4; i++) + { + float rollAngle = i * MathF.PI / 2; // 0°, 90°, 180°, 270° + Quaternion rollRotation = Quaternion.CreateFromAxisAngle(desiredForward, rollAngle); + Quaternion candidate = Quaternion.Concatenate(faceAlignment, rollRotation); + + float distance = QuaternionAngularDistance(orientation, candidate); + + if (distance < bestDistance) + { + bestDistance = distance; + bestOrientation = candidate; + bestRotationAngle = rollAngle; + } + } + + faceIndex = bestFaceIndex; + rotationAngle = bestRotationAngle; + return bestOrientation; + } + + private float QuaternionAngularDistance(Quaternion a, Quaternion b) + { + float dot = Math.Abs(a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W); + dot = Math.Clamp(dot, 0f, 1f); + return 2.0f * MathF.Acos(dot); + } + + #endregion + } +} diff --git a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml index fcf86016cf..befbc1ef0b 100644 --- a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml +++ b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml @@ -187,6 +187,29 @@ Grid.Column="1" /> + + + + + + + + + + + diff --git a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs index 5115671773..168879a7b4 100644 --- a/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs +++ b/Telegram/Views/Stars/Popups/ReceivedGiftPopup.xaml.cs @@ -289,6 +289,12 @@ private void InitializeUpgraded(IClientService clientService, ReceivedGift recei UpgradedAnimatedPhoto.Source = DelayedFileSource.FromSticker(clientService, gift.Model.Sticker); UpgradedTitle.Text = gift.Title; + if (gift.IsCrafted) + { + RibbonRoot.Visibility = Visibility.Visible; + Ribbon.Text = Strings.GiftCrafted; + } + if (clientService.TryGetChat(gift.PublisherChatId, out Chat publisherChat) && clientService.TryGetSupergroup(publisherChat, out Supergroup publisher) && publisher.HasActiveUsername(out string username)) @@ -327,10 +333,13 @@ private void InitializeUpgraded(IClientService clientService, ReceivedGift recei UpgradedModel.Text = gift.Model.Name; UpgradedModelRarity.Glyph = gift.Model.Rarity.ToText(); + gift.Model.Rarity.ToColor(UpgradedModelRarity); UpgradedBackdrop.Text = gift.Backdrop.Name; UpgradedBackdropRarity.Glyph = gift.Backdrop.Rarity.ToText(); + gift.Backdrop.Rarity.ToColor(UpgradedBackdropRarity); UpgradedSymbol.Text = gift.Symbol.Name; UpgradedSymbolRarity.Glyph = gift.Symbol.Rarity.ToText(); + gift.Symbol.Rarity.ToColor(UpgradedSymbolRarity); if (gift.ValueAmount != 0) { @@ -692,7 +701,7 @@ private async void ShowVariants() { if (_gift.Gift is SentGiftUpgraded upgraded) { - var response = await _clientService.SendAsync(new GetUpgradedGiftVariants(upgraded.Gift.RegularGiftId, true, false)); + var response = await _clientService.SendAsync(new GetUpgradedGiftVariants(upgraded.Gift.RegularGiftId, !upgraded.Gift.IsCrafted, upgraded.Gift.IsCrafted)); if (response is GiftUpgradeVariants variants) { Hide(); @@ -850,6 +859,12 @@ private void More_ContextRequested(object sender, RoutedEventArgs e) if (_gift.Gift is SentGiftUpgraded upgraded && upgraded.Gift.OwnerId.AreTheSame(_clientService.MyId)) { + if (upgraded.Gift.CraftProbabilityPerMille != 0) + { + // TODO: Icon + flyout.CreateFlyoutItem(Craft, Strings.GiftCraft, Icons.Hamburger); + } + if (upgraded.Gift.ResaleParameters != null) { flyout.CreateFlyoutItem(ChangePrice, Strings.Gift2ChangePrice, Icons.Tag); @@ -869,6 +884,15 @@ private void More_ContextRequested(object sender, RoutedEventArgs e) flyout.ShowAt(sender as UIElement, FlyoutPlacementMode.BottomEdgeAlignedRight); } + private void Craft() + { + if (_gift.Gift is SentGiftUpgraded upgraded) + { + Hide(); + _navigationService.ShowPopup(new GiftCraftPopup(_clientService, _navigationService, _gift)); + } + } + private void SetTheme() { if (_gift.Gift is SentGiftUpgraded upgraded) diff --git a/Telegram/Views/Stars/Popups/ResoldGiftsPopup.xaml.cs b/Telegram/Views/Stars/Popups/ResoldGiftsPopup.xaml.cs index 447307a8b9..9cb08dc869 100644 --- a/Telegram/Views/Stars/Popups/ResoldGiftsPopup.xaml.cs +++ b/Telegram/Views/Stars/Popups/ResoldGiftsPopup.xaml.cs @@ -37,6 +37,14 @@ namespace Telegram.Views.Stars.Popups { + public interface IResoldGiftsPopup + { + void UpdateAttributes(); + void UpdateItems(GiftsForResale gifts, bool updateFilters); + + ResourceDictionary Resources { get; } + } + public partial class ResoldGiftFilter { public ResoldGiftFilter(UpgradedGiftModelCount model) @@ -90,31 +98,31 @@ public partial class ResoldGiftFilterManager private readonly HashSet _selected = new(); private readonly IClientService _clientService; - private readonly ResoldGiftsPopup _popup; + private readonly IResoldGiftsPopup _popup; private readonly Microsoft.UI.Xaml.Controls.DropDownButton _sender; private MenuFlyout _flyout; private IList _prev; - public ResoldGiftFilterManager(IClientService clientService, ResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList models) + public ResoldGiftFilterManager(IClientService clientService, IResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList models) : this(clientService, popup, sender, models.Select(x => new ResoldGiftFilter(x))) { _attributeType = new UpgradedGiftAttributeIdModel(-1); } - public ResoldGiftFilterManager(IClientService clientService, ResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList backdrops) + public ResoldGiftFilterManager(IClientService clientService, IResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList backdrops) : this(clientService, popup, sender, backdrops.Select(x => new ResoldGiftFilter(x))) { _attributeType = new UpgradedGiftAttributeIdBackdrop(-1); } - public ResoldGiftFilterManager(IClientService clientService, ResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList symbols) + public ResoldGiftFilterManager(IClientService clientService, IResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IList symbols) : this(clientService, popup, sender, symbols.Select(x => new ResoldGiftFilter(x))) { _attributeType = new UpgradedGiftAttributeIdSymbol(-1); } - public ResoldGiftFilterManager(IClientService clientService, ResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IEnumerable items) + public ResoldGiftFilterManager(IClientService clientService, IResoldGiftsPopup popup, Microsoft.UI.Xaml.Controls.DropDownButton sender, IEnumerable items) { _clientService = clientService; _popup = popup; @@ -353,7 +361,7 @@ private string DefaultString() public partial class ResoldGiftsCollection : ObservableCollection, ISupportIncrementalLoading { private readonly IClientService _clientService; - private readonly ResoldGiftsPopup _popup; + private readonly IResoldGiftsPopup _popup; private readonly long _giftId; private readonly GiftForResaleOrder _order = new GiftForResaleOrderPrice(); @@ -363,7 +371,7 @@ public partial class ResoldGiftsCollection : ObservableCollection private string _nextOffset = string.Empty; private bool _hasMoreItems = true; - public ResoldGiftsCollection(IClientService clientService, ResoldGiftsPopup popup, long giftId, GiftForResaleOrder order, IList attributes) + public ResoldGiftsCollection(IClientService clientService, IResoldGiftsPopup popup, long giftId, GiftForResaleOrder order, IList attributes) { _clientService = clientService; _popup = popup; @@ -372,7 +380,7 @@ public ResoldGiftsCollection(IClientService clientService, ResoldGiftsPopup popu _attributes = attributes; } - public ResoldGiftsCollection(IClientService clientService, ResoldGiftsPopup popup, long giftId) + public ResoldGiftsCollection(IClientService clientService, IResoldGiftsPopup popup, long giftId) { _clientService = clientService; _popup = popup; @@ -421,7 +429,7 @@ private async Task LoadMoreItemsAsync(CancellationToken tok public GiftForResaleOrder Order => _order; } - public sealed partial class ResoldGiftsPopup : ContentPopup + public sealed partial class ResoldGiftsPopup : ContentPopup, IResoldGiftsPopup { private readonly IClientService _clientService; private readonly INavigationService _navigationService; From feabbc2d12714962f8a651f491a8d0884dfa2ee0 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 9 Feb 2026 12:44:53 +0400 Subject: [PATCH 083/169] Update TDLib submodule --- Libraries/tdlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/tdlib b/Libraries/tdlib index 0da5c72f83..6d50906157 160000 --- a/Libraries/tdlib +++ b/Libraries/tdlib @@ -1 +1 @@ -Subproject commit 0da5c72f8365fb4857096e716d53175ddbdf5a15 +Subproject commit 6d509061574d684117f74133056aa43df89022fc From 1cc40e793352ff77f823404e096588f03f30f1fc Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 9 Feb 2026 12:46:02 +0400 Subject: [PATCH 084/169] Fix login widget --- Telegram/Common/MessageHelper.cs | 2 +- .../ViewModels/DialogViewModel.Messages.cs | 2 +- .../Views/Popups/LoginUrlInfoPopup.xaml.cs | 18 ++---------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/Telegram/Common/MessageHelper.cs b/Telegram/Common/MessageHelper.cs index 75e94cdaed..22737a898f 100644 --- a/Telegram/Common/MessageHelper.cs +++ b/Telegram/Common/MessageHelper.cs @@ -438,7 +438,7 @@ private static async void OpenLoginUrl(IClientService clientService, INavigation var popup = new LoginUrlInfoPopup(clientService, navigation, requestConfirmation); var confirm = await navigation.ShowPopupAsync(popup); - if (confirm != ContentDialogResult.Primary || !popup.HasAccepted) + if (confirm != ContentDialogResult.Primary) { return; } diff --git a/Telegram/ViewModels/DialogViewModel.Messages.cs b/Telegram/ViewModels/DialogViewModel.Messages.cs index 815e143bd6..b168d6771a 100644 --- a/Telegram/ViewModels/DialogViewModel.Messages.cs +++ b/Telegram/ViewModels/DialogViewModel.Messages.cs @@ -1444,7 +1444,7 @@ public async void OpenInlineButton(MessageViewModel message, InlineKeyboardButto { var dialog = new LoginUrlInfoPopup(ClientService, NavigationService, requestConfirmation); var confirm = await ShowPopupAsync(dialog); - if (confirm != ContentDialogResult.Primary || !dialog.HasAccepted) + if (confirm != ContentDialogResult.Primary) { return; } diff --git a/Telegram/Views/Popups/LoginUrlInfoPopup.xaml.cs b/Telegram/Views/Popups/LoginUrlInfoPopup.xaml.cs index 54b1e99186..2ff211f753 100644 --- a/Telegram/Views/Popups/LoginUrlInfoPopup.xaml.cs +++ b/Telegram/Views/Popups/LoginUrlInfoPopup.xaml.cs @@ -114,21 +114,7 @@ public LoginUrlInfoPopup(IClientService clientService, INavigationService naviga SecondaryButtonText = Strings.Cancel; } - public bool HasAccepted - { - get - { - return false; - } - } - - public bool AllowWriteAccess - { - get - { - return false; - } - } + public bool AllowWriteAccess => AllowMessages.IsChecked is true; public bool AllowPhoneNumberAccess { get; private set; } @@ -148,7 +134,7 @@ private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, Conten AllowPhoneNumberAccess = true; } - Hide(); + Hide(ContentDialogResult.Primary); } } From 965515d39c6672718be1306190bc344bb93ae127 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 9 Feb 2026 12:46:23 +0400 Subject: [PATCH 085/169] Missing changes --- Telegram/Common/MessageHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/Common/MessageHelper.cs b/Telegram/Common/MessageHelper.cs index 22737a898f..edfbf1c441 100644 --- a/Telegram/Common/MessageHelper.cs +++ b/Telegram/Common/MessageHelper.cs @@ -662,7 +662,7 @@ public static async void NavigateToUpgradedGift(IClientService clientService, IN if (response is UpgradedGift gift) { var text = gift.OriginalDetails?.Text ?? string.Empty.AsFormattedText(); - var receivedGift = new ReceivedGift(string.Empty, null, text, 0, true, false, false, false, false, false, 0, new SentGiftUpgraded(gift), Array.Empty(), 0, 0, false, 0, 0, 0, 0, 0, string.Empty); + var receivedGift = new ReceivedGift(string.Empty, null, text, 0, true, false, false, false, false, false, 0, new SentGiftUpgraded(gift), Array.Empty(), 0, 0, false, 0, 0, 0, 0, 0, string.Empty, 0); navigation.ShowPopup(new ReceivedGiftPopup(clientService, navigation, receivedGift, null, null)); } @@ -1225,7 +1225,7 @@ public static async void NavigateToProxy(IClientService clientService, INavigati var confirm = await navigation.ShowPopupAsync(new AddProxyPopup(clientService, navigation, proxy)); if (confirm == ContentDialogResult.Primary) { - clientService.Send(new AddProxy(server ?? string.Empty, port, Constants.RELEASE, type)); + LifetimeService.Current.Proxy.AddProxy(proxy, Constants.RELEASE); } } From 1ca5c887192b412c7f76d8aade7ec363240fdcac Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 9 Feb 2026 12:46:38 +0400 Subject: [PATCH 086/169] New deeplinks (needs update) --- Telegram/Common/MessageHelper.cs | 502 +++++++++++++++++++++++++++++-- 1 file changed, 472 insertions(+), 30 deletions(-) diff --git a/Telegram/Common/MessageHelper.cs b/Telegram/Common/MessageHelper.cs index edfbf1c441..0b8db43f46 100644 --- a/Telegram/Common/MessageHelper.cs +++ b/Telegram/Common/MessageHelper.cs @@ -20,18 +20,19 @@ using Telegram.Td; using Telegram.Td.Api; using Telegram.ViewModels; +using Telegram.ViewModels.Settings; using Telegram.ViewModels.Stories; using Telegram.ViewModels.Supergroups; using Telegram.Views; +using Telegram.Views.Business; using Telegram.Views.Chats.Popups; +using Telegram.Views.Create; using Telegram.Views.Folders; using Telegram.Views.Folders.Popups; using Telegram.Views.Host; using Telegram.Views.Popups; using Telegram.Views.Premium.Popups; using Telegram.Views.Settings; -using Telegram.Views.Settings.Privacy; -using Telegram.Views.Stars; using Telegram.Views.Stars.Popups; using Windows.ApplicationModel; using Windows.ApplicationModel.DataTransfer; @@ -459,9 +460,6 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ { switch (internalLink) { - case InternalLinkTypeActiveSessions: - navigation.Navigate(typeof(SettingsSessionsPage)); - break; case InternalLinkTypeAuthenticationCode authenticationCode: if (clientService.AuthorizationState is AuthorizationStateWaitCode) { @@ -484,12 +482,6 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ case InternalLinkTypeBusinessChat businessChat: NavigateToBusinessChat(clientService, navigation, businessChat.LinkName); break; - case InternalLinkTypeChangePhoneNumber: - navigation.Navigate(typeof(SettingsProfilePage)); - break; - case InternalLinkTypeLanguageSettings: - navigation.Navigate(typeof(SettingsLanguagePage)); - break; case InternalLinkTypeChatBoost chatBoost: NavigateToChatBoost(clientService, navigation, chatBoost.Url); break; @@ -499,9 +491,6 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ case InternalLinkTypeChatFolderInvite chatFolderInvite: NavigateToChatFolderInviteLink(clientService, navigation, chatFolderInvite.InviteLink); break; - case InternalLinkTypeChatFolderSettings: - navigation.Navigate(typeof(FoldersPage)); - break; case InternalLinkTypeGame game: NavigateToUsername(clientService, navigation, game.BotUsername, null, game.GameShortName); break; @@ -522,15 +511,12 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ break; case InternalLinkTypePassportDataRequest: break; - case InternalLinkTypePremiumFeatures premiumFeatures: + case InternalLinkTypePremiumFeaturesPage premiumFeatures: navigation.ShowPromo(new PremiumSourceLink(premiumFeatures.Referrer)); break; case InternalLinkTypePremiumGiftCode premiumGiftCode: NavigateToPremiumGiftCode(clientService, navigation, premiumGiftCode.Code, source); break; - case InternalLinkTypePrivacyAndSecuritySettings: - navigation.Navigate(typeof(SettingsPrivacyAndSecurityPage)); - break; case InternalLinkTypePhoneNumberConfirmation phoneNumberConfirmation: NavigateToConfirmPhone(clientService, phoneNumberConfirmation.PhoneNumber, phoneNumberConfirmation.Hash); break; @@ -542,7 +528,26 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ break; case InternalLinkTypeQrCodeAuthentication: break; - case InternalLinkTypeSettings: + case InternalLinkTypeCallsPage calls: + NavigateToCalls(clientService, navigation, calls.Section); + break; + case InternalLinkTypeMyProfilePage myProfile: + NavigateToMyProfile(clientService, navigation, myProfile.Section); + break; + case InternalLinkTypeNewChannelChat: + navigation.ShowPopup(new NewChannelPopup()); + break; + case InternalLinkTypeNewGroupChat: + navigation.ShowPopup(new NewGroupPopup()); + break; + case InternalLinkTypeNewPrivateChat: + navigation.ShowPopup(new ContactsPopup()); + break; + case InternalLinkTypeSavedMessages: + navigation.NavigateToChat(clientService.Options.MyId, force: false); + break; + case InternalLinkTypeSettings settings: + NavigateToSettings(clientService, navigation, settings.Section); break; case InternalLinkTypeStickerSet stickerSet: NavigateToStickerSet(navigation, stickerSet.StickerSetName); @@ -556,9 +561,6 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ case InternalLinkTypeTheme theme: NavigateToTheme(clientService, navigation, theme.ThemeName); break; - case InternalLinkTypeThemeSettings: - navigation.Navigate(typeof(SettingsAppearancePage)); - break; case InternalLinkTypeUnknownDeepLink unknownDeepLink: NavigateToUnknownDeepLink(clientService, navigation, unknownDeepLink.Link); break; @@ -586,9 +588,6 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ case InternalLinkTypeGroupCall groupCall: NavigateToGroupCall(clientService, navigation, new InputGroupCallLink(groupCall.InviteLink)); break; - case InternalLinkTypeMyStars: - navigation.Navigate(typeof(StarsPage)); - break; case InternalLinkTypeBotAddToChannel botAddToChannel: NavigateToBotAddToChannel(clientService, navigation, botAddToChannel.BotUsername, botAddToChannel.AdministratorRights); break; @@ -601,14 +600,457 @@ public static void OpenTelegramUrl(IClientService clientService, INavigationServ case InternalLinkTypeGiftCollection giftCollection: NavigateToUsername(clientService, navigation, giftCollection.GiftOwnerUsername); break; - case InternalLinkTypeLoginEmailSettings: + } + } + + private static void NavigateToCalls(IClientService clientService, INavigationService navigation, string section) + { + switch (section) + { + case "start-call": + CallsViewModel.NewCall(clientService, navigation); + break; + case "all": break; + case "missed": break; + case "edit": break; + case "show-tab": break; + default: + navigation.ShowPopup(new CallsPopup()); + break; + } + } + + private static void NavigateToMyProfile(IClientService clientService, INavigationService navigation, string section) + { + switch (section) + { + case "posts": break; + case "posts/all-stories": break; + case "posts/add-album": break; + case "gifts": break; + case "archived-posts": break; + default: + navigation.Navigate(typeof(ProfilePage), clientService.Options.MyId); + break; + } + } + + private static void NavigateToSettings(IClientService clientService, INavigationService navigation, SettingsSection section) + { + switch (section) + { + case SettingsSectionAppearance appearance: + switch (appearance.Subsection) + { + case "themes": goto default; + case "themes/edit": + case "themes/create": + navigation.Navigate(typeof(SettingsThemesPage)); + break; + case "wallpapers": goto default; + case "wallpapers/edit": + case "wallpapers/set": + case "wallpapers/choose-photo": + navigation.Navigate(typeof(SettingsBackgroundsPage)); + break; + case "your-color/profile": goto default; + case "your-color/profile/add-icons": + case "your-color/profile/use-gift": + case "your-color/profile/reset": + case "your-color/name": + case "your-color/name/add-icons": + case "your-color/name/use-gift": + navigation.Navigate(typeof(SettingsProfileColorPage)); + break; + case "stickers-and-emoji": goto default; + case "stickers-and-emoji/edit": + case "stickers-and-emoji/trending": + case "stickers-and-emoji/archived": + case "stickers-and-emoji/emoji": + case "stickers-and-emoji/suggest-by-emoji": + case "stickers-and-emoji/large-emoji": + case "stickers-and-emoji/dynamic-order": + navigation.Navigate(typeof(SettingsStickersPage)); + break; + case "stickers-and-emoji/archived/edit": + navigation.Navigate(typeof(SettingsStickersPage), StickersType.Archived); + break; + case "stickers-and-emoji/emoji/edit": + case "stickers-and-emoji/emoji/archived": + case "stickers-and-emoji/emoji/suggest": + case "stickers-and-emoji/emoji/show-more": + navigation.Navigate(typeof(SettingsStickersPage), StickersType.Emoji); + break; + case "stickers-and-emoji/emoji/archived/edit": + navigation.Navigate(typeof(SettingsStickersPage), StickersType.EmojiArchived); + break; + case "stickers-and-emoji/emoji/quick-reaction": + case "stickers-and-emoji/emoji/quick-reaction/choose": + case "night-mode": + case "auto-night-mode": + case "text-size": + case "text-size/use-system": + case "message-corners": + case "animations": + case "app-icon": + case "tap-for-next-media": + default: + navigation.Navigate(typeof(SettingsAppearancePage)); + break; + } + break; + case SettingsSectionAskQuestion: + break; + case SettingsSectionBusiness business: + switch (business.Subsection) + { + case "do-not-hide-ads": + default: + navigation.Navigate(typeof(BusinessPage)); + break; + } + break; + case SettingsSectionChatFolders chatFolders: + switch (chatFolders.Subsection) + { + case "edit": + case "create": + case "add-recommended": + case "show-tags": + case "tab-view": + default: + navigation.Navigate(typeof(FoldersPage)); + break; + } + break; + case SettingsSectionDataAndStorage dataAndStorage: + switch (dataAndStorage.Subsection) + { + case "storage": + case "storage/edit": + case "storage/auto-remove": + case "storage/clear-cache": + case "storage/max-cache": + navigation.Navigate(typeof(SettingsStoragePage)); + break; + case "usage": + case "usage/mobile": + case "usage/wifi": + case "usage/roaming": + case "usage/reset": + navigation.Navigate(typeof(SettingsNetworkPage)); + break; + //case "usage/mobile/auto-download": break; + //case "usage/mobile/auto-download/enable": break; + //case "usage/mobile/auto-download/usage": break; + //case "usage/mobile/auto-download/photos": break; + //case "usage/mobile/auto-download/stories": break; + //case "usage/mobile/auto-download/videos": break; + //case "usage/mobile/auto-download/files": break; + //case "usage/wifi/auto-download": break; + //case "usage/wifi/auto-download/enable": break; + //case "usage/wifi/auto-download/usage": break; + //case "usage/wifi/auto-download/photos": break; + //case "usage/wifi/auto-download/stories": break; + //case "usage/wifi/auto-download/videos": break; + //case "usage/wifi/auto-download/files": break; + //case "usage/roaming/auto-download": break; + //case "usage/roaming/auto-download/enable": break; + //case "usage/roaming/auto-download/usage": break; + //case "usage/roaming/auto-download/photos": break; + //case "usage/roaming/auto-download/stories": break; + //case "usage/roaming/auto-download/videos": break; + //case "usage/roaming/auto-download/files": break; + case "auto-download/data": + case "auto-download/data/enable": + case "auto-download/data/usage": + case "auto-download/data/photos": + case "auto-download/data/stories": + case "auto-download/data/videos": + case "auto-download/data/files": + case "auto-download/wifi": + case "auto-download/wifi/enable": + case "auto-download/wifi/usage": + case "auto-download/wifi/photos": + case "auto-download/wifi/stories": + case "auto-download/wifi/videos": + case "auto-download/wifi/files": + case "auto-download/roaming": + case "auto-download/roaming/enable": + case "auto-download/roaming/usage": + case "auto-download/roaming/photos": + case "auto-download/roaming/stories": + case "auto-download/roaming/videos": + case "auto-download/roaming/files": + case "auto-download/reset": + case "save-to-photos/chats": + case "save-to-photos/chats/max-video-size": + case "save-to-photos/chats/add-exception": + case "save-to-photos/chats/delete-all": + case "save-to-photos/groups": + case "save-to-photos/groups/max-video-size": + case "save-to-photos/groups/add-exception": + case "save-to-photos/groups/delete-all": + case "save-to-photos/channels": + case "save-to-photos/channels/max-video-size": + case "save-to-photos/channels/add-exception": + case "save-to-photos/channels/delete-all": + case "less-data-calls": + case "open-links": + case "share-sheet": + case "share-sheet/suggested-chats": + case "share-sheet/suggest-by": + case "share-sheet/reset": + case "saved-edited-photos": + case "pause-music": + case "raise-to-listen": + case "raise-to-speak": + case "show-18-content": + default: + navigation.Navigate(typeof(SettingsDataAndStoragePage)); + break; + case "proxy": + case "proxy/edit": + case "proxy/use-proxy": + case "proxy/add-proxy": + case "proxy/share-list": + case "proxy/use-for-calls": + navigation.Navigate(typeof(SettingsProxyPage)); + break; + } + break; + case SettingsSectionDevices devices: + switch (devices.Subsection) + { + case "edit": + case "link-desktop": + case "terminate-sessions": + case "auto-terminate": + default: + navigation.Navigate(typeof(SettingsSessionsPage)); + break; + } + break; + case SettingsSectionEditProfile editProfile: + switch (editProfile.Subsection) + { + case "set-photo": + case "first-name": + case "last-name": + case "emoji-status": + case "bio": + case "birthday": + case "change-number": + case "username": + case "your-color": + case "channel": + case "add-account": + case "log-out": + case "profile-photo/use-emoji": + default: + navigation.Navigate(typeof(SettingsProfilePage)); + break; + case "profile-color/profile": + case "profile-color/profile/add-icons": + case "profile-color/profile/use-gift": + case "profile-color/name": + case "profile-color/name/add-icons": + case "profile-color/name/use-gift": + navigation.Navigate(typeof(SettingsProfileColorPage)); + break; + } + break; + case SettingsSectionFaq: + break; + case SettingsSectionFeatures: + break; + case SettingsSectionInAppBrowser inAppBrowser: + switch (inAppBrowser.Subsection) + { + case "enable-browser": break; + case "clear-cookies": break; + case "clear-cache": break; + case "history": break; + case "clear-history": break; + case "never-open": break; + case "clear-list": break; + case "search": break; + default: break; + } + break; + case SettingsSectionLanguage language: + switch (language.Subsection) + { + case "show-button": + case "translate-chats": + case "do-not-translate": + default: + navigation.Navigate(typeof(SettingsLanguagePage)); + break; + } + break; + case SettingsSectionMyStars myStars: + switch (myStars.Subsection) + { + case "top-up": break; + case "stats": break; + case "gift": break; + case "earn": break; + default: break; + } + break; + case SettingsSectionMyToncoins myToncoins: break; - case InternalLinkTypePasswordSettings: - navigation.NavigateToPassword(); + case SettingsSectionPowerSaving powerSaving: + switch (powerSaving.Subsection) + { + case "videos": + case "gifs": + case "stickers": + case "emoji": + case "effects": + case "preload": + case "background": + case "call-animations": + case "particles": + case "transitions": + default: + navigation.Navigate(typeof(SettingsPowerSavingPage)); + break; + } + break; + case SettingsSectionPremium premium: break; - case InternalLinkTypePhoneNumberPrivacySettings: - navigation.Navigate(typeof(SettingsPrivacyPhonePage)); + case SettingsSectionPrivacyAndSecurity privacyAndSecurity: + switch (privacyAndSecurity.Subsection) + { + case "blocked": goto default; + case "blocked/edit": + case "blocked/block-user": + case "blocked/block-user/chats": + case "blocked/block-user/contacts": + navigation.Navigate(typeof(SettingsBlockedChatsPage)); + break; + case "active-websites": goto default; + case "active-websites/edit": + case "active-websites/disconnect-all": + navigation.Navigate(typeof(SettingsWebSessionsPage)); + break; + case "passcode": goto default; + case "passcode/disable": + case "passcode/change": + case "passcode/auto-lock": + case "passcode/face-id": + case "passcode/fingerprint": + break; + case "2sv": goto default; + case "2sv/change": + case "2sv/disable": + case "2sv/change-email": + break; + case "passkey": goto default; + case "passkey/create": + break; + case "auto-delete": goto default; + case "auto-delete/set-custom": + break; + case "login-email": goto default; + case "phone-number": goto default; + case "phone-number/never": + case "phone-number/always": + break; + case "last-seen": goto default; + case "last-seen/never": + case "last-seen/always": + case "last-seen/hide-read-time": + break; + case "profile-photos": goto default; + case "profile-photos/never": + case "profile-photos/always": + case "profile-photos/set-public": + case "profile-photos/update-public": + case "profile-photos/remove-public": + break; + case "bio": goto default; + case "bio/never": + case "bio/always": + break; + case "gifts": goto default; + case "gifts/show-icon": + case "gifts/never": + case "gifts/always": + case "gifts/accepted-types": + break; + case "birthday": goto default; + case "birthday/add": + case "birthday/never": + case "birthday/always": + break; + case "saved-music": goto default; + case "saved-music/never": + case "saved-music/always": + break; + case "forwards": goto default; + case "forwards/never": + case "forwards/always": + break; + case "calls": goto default; + case "calls/never": + case "calls/always": + case "calls/p2p": + break; + case "calls/p2p/never": + case "calls/p2p/always": + break; + case "calls/ios-integration": break; + case "voice": goto default; + case "voice/never": + case "voice/always": + break; + case "messages": goto default; + case "messages/set-price": + case "messages/exceptions": + break; + case "invites": goto default; + case "invites/never": + case "invites/always": + break; + case "self-destruct": + case "data-settings": + case "data-settings/sync-contacts": + case "data-settings/delete-synced": + case "data-settings/suggest-contacts": + case "data-settings/delete-cloud-drafts": + case "data-settings/clear-payment-info": + case "data-settings/link-previews": + case "data-settings/bot-settings": + case "data-settings/map-provider": + case "archive-and-mute": + default: + navigation.Navigate(typeof(SettingsPrivacyAndSecurityPage)); + break; + } break; + case SettingsSectionPrivacyPolicy: + break; + case SettingsSectionQrCode qrCode: + switch (qrCode.Subsection) + { + case "share": break; + case "scan": break; + default: break; + } + break; + case SettingsSectionSearch: + break; + case SettingsSectionSendGift sendGift: + switch (sendGift.Subsection) + { + case "self": break; + default: break; + } + break; + } } From 030b01768b92bfe732e98c623591f1f6f8feba97 Mon Sep 17 00:00:00 2001 From: Fela Date: Mon, 9 Feb 2026 12:48:39 +0400 Subject: [PATCH 087/169] Bot buttons styles --- Telegram/Common/CommonStyles.xaml | 468 ++++++++++++++++++ .../Messages/ReplyMarkupInlinePanel.cs | 21 + Telegram/Controls/ReplyMarkupPanel.cs | 123 ++++- 3 files changed, 611 insertions(+), 1 deletion(-) diff --git a/Telegram/Common/CommonStyles.xaml b/Telegram/Common/CommonStyles.xaml index b3f35e7d2c..834b99c0f8 100644 --- a/Telegram/Common/CommonStyles.xaml +++ b/Telegram/Common/CommonStyles.xaml @@ -1284,6 +1284,12 @@ + + + + + + + + + + + - - - -