111 lines
3.8 KiB
C#
111 lines
3.8 KiB
C#
using Bit.App.Pages;
|
|
|
|
namespace Bit.App.Controls
|
|
{
|
|
public abstract class BaseCipherViewCell : ExtendedGrid
|
|
{
|
|
protected virtual CachedImage Icon { get; }
|
|
|
|
protected virtual IconLabel IconPlaceholder { get; }
|
|
|
|
// HACK: PM-5896 Fix for Background Crash on iOS
|
|
// While loading the cipher icon and the user sent the app to background
|
|
// the app was crashing sometimes when the "LoadingPlaceholder" or "ErrorPlaceholder"
|
|
// were being accessed, thus locked, and as soon the app got suspended by the OS
|
|
// the app would crash because there can't be any lock files by the app when it gets suspended.
|
|
// So, the approach has changed to reuse the IconLabel default icon to use it for these placeholders
|
|
// as well. In order to do that both icon controls change their visibility dynamically here reacting to
|
|
// CachedImage events and binding context changes.
|
|
|
|
protected override void OnBindingContextChanged()
|
|
{
|
|
Icon.Source = null;
|
|
if (BindingContext is CipherItemViewModel cipherItemVM)
|
|
{
|
|
Icon.Source = cipherItemVM.IconImageSource;
|
|
if (!cipherItemVM.IconImageSuccesfullyLoaded)
|
|
{
|
|
UpdateIconImages(cipherItemVM.ShowIconImage);
|
|
}
|
|
}
|
|
|
|
base.OnBindingContextChanged();
|
|
}
|
|
|
|
private void UpdateIconImages(bool showIcon)
|
|
{
|
|
MainThread.BeginInvokeOnMainThread(() =>
|
|
{
|
|
if (!showIcon)
|
|
{
|
|
Icon.IsVisible = false;
|
|
IconPlaceholder.IsVisible = true;
|
|
return;
|
|
}
|
|
|
|
IconPlaceholder.IsVisible = Icon.IsLoading;
|
|
});
|
|
}
|
|
|
|
#if !UT
|
|
public void Icon_Success(object sender, FFImageLoading.Maui.CachedImageEvents.SuccessEventArgs e)
|
|
{
|
|
if (BindingContext is CipherItemViewModel cipherItemVM)
|
|
{
|
|
cipherItemVM.IconImageSuccesfullyLoaded = true;
|
|
}
|
|
MainThread.BeginInvokeOnMainThread(() =>
|
|
{
|
|
Icon.IsVisible = true;
|
|
IconPlaceholder.IsVisible = false;
|
|
});
|
|
}
|
|
|
|
public void Icon_Error(object sender, FFImageLoading.Maui.CachedImageEvents.ErrorEventArgs e)
|
|
{
|
|
if (BindingContext is CipherItemViewModel cipherItemVM)
|
|
{
|
|
cipherItemVM.IconImageSuccesfullyLoaded = false;
|
|
}
|
|
MainThread.BeginInvokeOnMainThread(() =>
|
|
{
|
|
Icon.IsVisible = false;
|
|
IconPlaceholder.IsVisible = true;
|
|
});
|
|
}
|
|
#else
|
|
private void Icon_Success(object sender, EventArgs e) {}
|
|
private void Icon_Error(object sender, EventArgs e) {}
|
|
#endif
|
|
}
|
|
|
|
public class StubBaseCipherViewCellSoLinkerDoesntRemoveMethods : BaseCipherViewCell
|
|
{
|
|
protected override CachedImage Icon => new CachedImage();
|
|
protected override IconLabel IconPlaceholder => new IconLabel();
|
|
|
|
public static void CallThisSoLinkerDoesntRemoveMethods()
|
|
{
|
|
#if !UT
|
|
var stub = new StubBaseCipherViewCellSoLinkerDoesntRemoveMethods();
|
|
|
|
try
|
|
{
|
|
stub.Icon_Success(stub, new FFImageLoading.Maui.CachedImageEvents.SuccessEventArgs(new FFImageLoading.Work.ImageInformation(), FFImageLoading.Work.LoadingResult.Disk));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
|
|
try
|
|
{
|
|
stub.Icon_Error(stub, new FFImageLoading.Maui.CachedImageEvents.ErrorEventArgs(new InvalidOperationException("stub")));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|