Fix Run-crash for real (type-guard before VisualTreeHelper); avatar via HttpClient decode

This commit is contained in:
2026-08-24 14:57:34 -07:00
parent d9e352f996
commit 100980087e
2 changed files with 52 additions and 32 deletions
+44 -26
View File
@@ -1,5 +1,8 @@
using System.Collections;
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -133,37 +136,51 @@ public partial class MainWindow : Window
: null;
}
private void LoadAvatarImage()
private static readonly HttpClient AvatarHttp = new() { Timeout = TimeSpan.FromSeconds(15) };
private string? _loadedAvatarUrl;
private async void LoadAvatarImage()
{
var url = _viewModel.AccountAvatarUrl;
if (_viewModel.IsConnected && !string.IsNullOrWhiteSpace(url))
if (!_viewModel.IsConnected)
{
try
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(url, UriKind.Absolute);
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
bitmap.Freeze();
AvatarImage.Source = bitmap;
AvatarInitial.Visibility = Visibility.Collapsed;
return;
}
catch (Exception ex)
{
AppLog.Write($"Avatar load failed ({url}): {ex.Message}");
}
ShowAvatarFallback(null);
return;
}
else if (_viewModel.IsConnected)
if (string.IsNullOrWhiteSpace(url))
{
AppLog.Write("Avatar: connected but no profile image URL on the session");
ShowAvatarFallback(null);
return;
}
if (url == _loadedAvatarUrl && AvatarImage.Source != null) return;
try
{
var bytes = await AvatarHttp.GetByteArrayAsync(url);
using var ms = new MemoryStream(bytes);
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = ms;
bitmap.EndInit();
bitmap.Freeze();
_loadedAvatarUrl = url;
AvatarImage.Source = bitmap;
AvatarInitial.Visibility = Visibility.Collapsed;
}
catch (Exception ex)
{
AppLog.Write($"Avatar load failed ({url}): {ex.Message}");
ShowAvatarFallback(_viewModel.AccountDisplayName);
}
}
private void ShowAvatarFallback(string? name)
{
_loadedAvatarUrl = null;
AvatarImage.Source = null;
AvatarInitial.Text = string.IsNullOrWhiteSpace(_viewModel.AccountDisplayName)
? "?"
: _viewModel.AccountDisplayName.Substring(0, 1).ToUpperInvariant();
AvatarInitial.Visibility = _viewModel.IsConnected ? Visibility.Visible : Visibility.Collapsed;
AvatarInitial.Text = string.IsNullOrWhiteSpace(name) ? "?" : name.Substring(0, 1).ToUpperInvariant();
AvatarInitial.Visibility = Visibility.Visible;
}
private void SourceNameBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
@@ -326,8 +343,9 @@ public partial class MainWindow : Window
{
while (child != null && !ReferenceEquals(child, ancestor))
{
var parent = VisualTreeHelper.GetParent(child);
child = parent ?? LogicalTreeHelper.GetParent(child);
child = child is System.Windows.Media.Visual or System.Windows.Media.Media3D.Visual3D
? VisualTreeHelper.GetParent(child)
: LogicalTreeHelper.GetParent(child);
}
return child != null;
}