mirror of
https://github.com/bitwarden/mobile
synced 2026-01-04 17:43:17 +00:00
PM-3350 Fix Avatar toolbar icon on extensions to load properly and to take advantage of using directly SkiaSharp to do the native conversion to UIImage. Also improved the toolbar item so that size is set appropriately.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using Bit.App.Controls;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using CoreGraphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
using SkiaSharp.Views.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Utilities
|
||||
@@ -30,12 +32,19 @@ namespace Bit.iOS.Core.Utilities
|
||||
throw new NullReferenceException(nameof(_stateService));
|
||||
}
|
||||
|
||||
var avatarImageSource = new AvatarImageSource(await _stateService.GetActiveUserIdAsync(),
|
||||
await _stateService.GetNameAsync(), await _stateService.GetEmailAsync(),
|
||||
await _stateService.GetAvatarColorAsync());
|
||||
using (var avatarUIImage = await avatarImageSource.GetNativeImageAsync())
|
||||
var avatarInfo = await _stateService.GetActiveUserCustomDataAsync<AvatarInfo?>(a => a?.Profile is null
|
||||
? null
|
||||
: new AvatarInfo(a.Profile.UserId, a.Profile.Name, a.Profile.Email, a.Profile.AvatarColor));
|
||||
|
||||
if (!avatarInfo.HasValue)
|
||||
{
|
||||
return avatarUIImage?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) ?? UIImage.GetSystemImage(DEFAULT_SYSTEM_AVATAR_IMAGE);
|
||||
return UIImage.GetSystemImage(DEFAULT_SYSTEM_AVATAR_IMAGE);
|
||||
}
|
||||
|
||||
using (var avatarUIImage = SKAvatarImageHelper.Draw(avatarInfo.Value))
|
||||
{
|
||||
return avatarUIImage?.ToUIImage()?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
|
||||
?? UIImage.GetSystemImage(DEFAULT_SYSTEM_AVATAR_IMAGE);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -100,5 +109,32 @@ namespace Bit.iOS.Core.Utilities
|
||||
containerView.UserInteractionEnabled = !overlayVisible;
|
||||
containerView.Subviews[0].UserInteractionEnabled = !overlayVisible;
|
||||
}
|
||||
|
||||
public async Task<UIControl> CreateAccountSwitchToolbarButtonItemCustomViewAsync()
|
||||
{
|
||||
const float size = 40f;
|
||||
var image = await CreateAvatarImageAsync();
|
||||
var accountSwitchButton = new UIControl(new CGRect(0, 0, size, size));
|
||||
if (image != null)
|
||||
{
|
||||
var accountSwitchAvatarImageView = new UIImageView(new CGRect(0, 0, size, size))
|
||||
{
|
||||
Image = image
|
||||
};
|
||||
accountSwitchButton.AddSubview(accountSwitchAvatarImageView);
|
||||
}
|
||||
|
||||
return accountSwitchButton;
|
||||
}
|
||||
|
||||
public void DisposeAccountSwitchToolbarButtonItemImage(UIControl accountSwitchButton)
|
||||
{
|
||||
if (accountSwitchButton?.Subviews?.FirstOrDefault() is UIImageView accountSwitchImageView && accountSwitchImageView.Image != null)
|
||||
{
|
||||
var img = accountSwitchImageView.Image;
|
||||
accountSwitchImageView.Image = null;
|
||||
img.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Utilities
|
||||
{
|
||||
public static class ImageSourceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the native image from the ImageSource.
|
||||
/// Taken from https://github.com/xamarin/Xamarin.Forms/blob/02dee20dfa1365d0104758e534581d1fa5958990/Xamarin.Forms.Platform.iOS/Renderers/ImageElementManager.cs#L264
|
||||
/// </summary>
|
||||
public static async Task<UIImage> GetNativeImageAsync(this ImageSource source, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (source == null || source.IsEmpty)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var handler = Microsoft.Maui.Controls.Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler>(source);
|
||||
if (handler == null)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(new InvalidOperationException("GetNativeImageAsync failed cause IImageSourceHandler couldn't be found"));
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
float scale = (float)UIScreen.MainScreen.Scale;
|
||||
return await handler.LoadImageAsync(source, scale: scale, cancelationToken: cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(new OperationCanceledException("GetNativeImageAsync was cancelled"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(new InvalidOperationException("GetNativeImageAsync failed", ex));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user