1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

Compare commits

...

1 Commits

Author SHA1 Message Date
Federico Maccaroni
f312e8c4d2 PM-7052 WIP fix theme change on iOS Autofill extension (with ClipLogger activated) 2024-03-26 10:58:09 -03:00
15 changed files with 306 additions and 88 deletions

View File

@@ -1,66 +1,66 @@
//using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
//using System.Text; using System.Text;
//using Bit.Core.Abstractions; using Bit.Core.Abstractions;
//#if IOS #if IOS
//using UIKit; using UIKit;
//#endif #endif
//namespace Bit.Core.Services namespace Bit.Core.Services
//{ {
// /// <summary> /// <summary>
// /// This logger can be used to help debug iOS extensions where we cannot use the .NET debugger yet /// This logger can be used to help debug iOS extensions where we cannot use the .NET debugger yet
// /// so we can use this that copies the logs to the clipboard so one /// so we can use this that copies the logs to the clipboard so one
// /// can paste them and analyze its output. /// can paste them and analyze its output.
// /// </summary> /// </summary>
// public class ClipLogger : ILogger public class ClipLogger : ILogger
// { {
// private static readonly StringBuilder _currentBreadcrumbs = new StringBuilder(); private static readonly StringBuilder _currentBreadcrumbs = new StringBuilder();
// static ILogger _instance; static ILogger _instance;
// public static ILogger Instance public static ILogger Instance
// { {
// get get
// { {
// if (_instance is null) if (_instance is null)
// { {
// _instance = new ClipLogger(); _instance = new ClipLogger();
// } }
// return _instance; return _instance;
// } }
// } }
// protected ClipLogger() protected ClipLogger()
// { {
// } }
// public static void Log(string breadcrumb) public static void Log(string breadcrumb)
// { {
// _currentBreadcrumbs.AppendLine($"{DateTime.Now.ToShortTimeString()}: {breadcrumb}"); _currentBreadcrumbs.AppendLine($"{DateTime.Now.ToShortTimeString()}: {breadcrumb}");
//#if IOS #if IOS
// UIPasteboard.General.String = _currentBreadcrumbs.ToString(); MainThread.BeginInvokeOnMainThread(() => UIPasteboard.General.String = _currentBreadcrumbs.ToString());
//#endif #endif
// } }
// public void Error(string message, IDictionary<string, string> extraData = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) public void Error(string message, IDictionary<string, string> extraData = null, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
// { {
// var classAndMethod = $"{Path.GetFileNameWithoutExtension(sourceFilePath)}.{memberName}"; var classAndMethod = $"{Path.GetFileNameWithoutExtension(sourceFilePath)}.{memberName}";
// var filePathAndLineNumber = $"{Path.GetFileName(sourceFilePath)}:{sourceLineNumber}"; var filePathAndLineNumber = $"{Path.GetFileName(sourceFilePath)}:{sourceLineNumber}";
// var properties = new Dictionary<string, string> var properties = new Dictionary<string, string>
// { {
// ["File"] = filePathAndLineNumber, ["File"] = filePathAndLineNumber,
// ["Method"] = memberName ["Method"] = memberName
// }; };
// Log(message ?? $"Error found in: {classAndMethod}, {filePathAndLineNumber}"); Log(message ?? $"Error found in: {classAndMethod}, {filePathAndLineNumber}");
// } }
// public void Exception(Exception ex) => Log(ex?.ToString()); public void Exception(Exception ex) => Log(ex?.ToString());
// public Task InitAsync() => Task.CompletedTask; public Task InitAsync() => Task.CompletedTask;
// public Task<bool> IsEnabled() => Task.FromResult(true); public Task<bool> IsEnabled() => Task.FromResult(true);
// public Task SetEnabled(bool value) => Task.CompletedTask; public Task SetEnabled(bool value) => Task.CompletedTask;
// } }
//} }

View File

@@ -21,7 +21,8 @@ namespace Bit.Core.Services
#if !FDROID #if !FDROID
// just in case the caller throws the exception in a moment where the logger can't be resolved // just in case the caller throws the exception in a moment where the logger can't be resolved
// we need to track the error as well // we need to track the error as well
Microsoft.AppCenter.Crashes.Crashes.TrackError(ex); //Microsoft.AppCenter.Crashes.Crashes.TrackError(ex);
ClipLogger.Log(ex?.ToString());
#endif #endif
} }
} }

View File

@@ -154,7 +154,11 @@ namespace Bit.App.Utilities
// Currently on iOS when resuming the app after showing a System "Share/Sheet" (or other similar UI) // Currently on iOS when resuming the app after showing a System "Share/Sheet" (or other similar UI)
// MAUI reports the incorrect Theme. To avoid this we are fetching the current OS Theme directly on iOS from the iOS API. // MAUI reports the incorrect Theme. To avoid this we are fetching the current OS Theme directly on iOS from the iOS API.
// MAUI Issue: https://github.com/dotnet/maui/issues/19614 // MAUI Issue: https://github.com/dotnet/maui/issues/19614
#if IOS
public static bool OsDarkModeEnabled(UITraitCollection? traitCollection = null)
#else
public static bool OsDarkModeEnabled() public static bool OsDarkModeEnabled()
#endif
{ {
#if UT #if UT
return false; return false;
@@ -167,8 +171,19 @@ namespace Bit.App.Utilities
if (!OperatingSystem.IsIOSVersionAtLeast(13, 0)) if (!OperatingSystem.IsIOSVersionAtLeast(13, 0))
return false; return false;
var traits = InvokeOnMainThread(() => WindowStateManager.Default.GetCurrentUIViewController()?.TraitCollection) ?? UITraitCollection.CurrentTraitCollection; ClipLogger.Log($"TC, UIStyle: {traitCollection?.UserInterfaceStyle}");
var uiStyle = traits.UserInterfaceStyle; var uiStyle = traitCollection?.UserInterfaceStyle;
if (traitCollection is null)
{
ClipLogger.Log($"TC null getting trait collection from wsm");
var traits = InvokeOnMainThread(() =>
{
return WindowStateManager.Default.GetCurrentUIViewController()?.TraitCollection;
}) ?? UITraitCollection.CurrentTraitCollection;
uiStyle = traits.UserInterfaceStyle;
}
ClipLogger.Log($"UIStyle: {uiStyle}");
requestedTheme = uiStyle switch requestedTheme = uiStyle switch
{ {

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using AuthenticationServices; using AuthenticationServices;
using Bit.App.Abstractions; using Bit.App.Abstractions;
@@ -47,6 +48,10 @@ namespace Bit.iOS.Autofill
{ {
try try
{ {
ClipLogger.Log($"[ViewDidLoad]");
ClipLogger.Log($"ViewDidLoad: {TraitCollection?.UserInterfaceStyle}");
InitAppIfNeededAsync().FireAndForget(ex => OnProvidingCredentialException(ex)); InitAppIfNeededAsync().FireAndForget(ex => OnProvidingCredentialException(ex));
base.ViewDidLoad(); base.ViewDidLoad();
@@ -149,18 +154,6 @@ namespace Bit.iOS.Autofill
} }
} }
//public override async void ProvideCredentialWithoutUserInteraction(ASPasswordCredentialIdentity credentialIdentity)
//{
// try
// {
// await ProvideCredentialWithoutUserInteractionAsync(credentialIdentity);
// }
// catch (Exception ex)
// {
// OnProvidingCredentialException(ex);
// }
//}
[Export("prepareInterfaceToProvideCredentialForRequest:")] [Export("prepareInterfaceToProvideCredentialForRequest:")]
public override async void PrepareInterfaceToProvideCredential(IASCredentialRequest credentialRequest) public override async void PrepareInterfaceToProvideCredential(IASCredentialRequest credentialRequest)
{ {
@@ -194,18 +187,6 @@ namespace Bit.iOS.Autofill
} }
} }
//public override async void PrepareInterfaceToProvideCredential(ASPasswordCredentialIdentity credentialIdentity)
//{
// try
// {
// await PrepareInterfaceToProvideCredentialAsync(c => c.PasswordCredentialIdentity = credentialIdentity);
// }
// catch (Exception ex)
// {
// OnProvidingCredentialException(ex);
// }
//}
public override async void PrepareInterfaceForExtensionConfiguration() public override async void PrepareInterfaceForExtensionConfiguration()
{ {
try try
@@ -546,7 +527,45 @@ namespace Bit.iOS.Autofill
_nfcSession, out _nfcDelegate, out _accountsManager); _nfcSession, out _nfcDelegate, out _accountsManager);
} }
private async Task InitAppIfNeededAsync() public override void ViewIsAppearing(bool animated)
{
base.ViewIsAppearing(animated);
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
return;
}
ClipLogger.Log($"ViewIsAppearing: {TraitCollection?.UserInterfaceStyle}");
var appOptions = new AppOptions { IosExtension = true };
var app = new App.App(appOptions);
ThemeManager.SetTheme(app.Resources);
iOSCoreHelpers.AppearanceAdjustments();
View.BackgroundColor = UIColor.SystemBackground;
Logo.Image = UIImage.FromFile("splash_logo");
View.SetNeedsLayout();
ClipLogger.Log($"Window null: {View.Window is null}");
//View.Window?.UpdateTraitsIfNeeded();
ServiceContainer.Resolve<IMessagingService>().Send("update_traits");
//((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
//{
// MainThread.BeginInvokeOnMainThread(() =>
// {
// View.BackgroundColor = UIColor.SystemBackground;
// Logo.Image = UIImage.FromFile("splash_logo");
// });
//});
}
private async Task InitAppIfNeededAsync([CallerMemberName] string memberName = "")
{ {
if (ServiceContainer.RegisteredServices == null || ServiceContainer.RegisteredServices.Count == 0) if (ServiceContainer.RegisteredServices == null || ServiceContainer.RegisteredServices.Count == 0)
{ {
@@ -554,6 +573,13 @@ namespace Bit.iOS.Autofill
} }
await _stateService.Value.ReloadStateAsync(); await _stateService.Value.ReloadStateAsync();
ClipLogger.Log($"InitAppIfNeeded {memberName}");
//if (_viewIsAppeared)
//{
// var app = new App.App(new AppOptions { IosExtension = true });
// ThemeManager.SetTheme(app.Resources);
// iOSCoreHelpers.AppearanceAdjustments();
//}
} }
private void LaunchHomePage() private void LaunchHomePage()

View File

@@ -1,6 +1,7 @@
using Bit.Core.Services; using Bit.Core.Services;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using Foundation; using Foundation;
using Microsoft.Maui.ApplicationModel;
using ObjCRuntime; using ObjCRuntime;
using UIKit; using UIKit;
@@ -50,6 +51,22 @@ namespace Bit.iOS.Autofill.ListItems
_separator.TrailingAnchor.ConstraintEqualTo(ContentView.TrailingAnchor, -7), _separator.TrailingAnchor.ConstraintEqualTo(ContentView.TrailingAnchor, -7),
_separator.BottomAnchor.ConstraintEqualTo(ContentView.LayoutMarginsGuide.BottomAnchor, 2) _separator.BottomAnchor.ConstraintEqualTo(ContentView.LayoutMarginsGuide.BottomAnchor, 2)
}); });
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
return;
}
((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
{
ClipLogger.Log($"[HeaderItemView] TraitCollection: {traits.UserInterfaceStyle}");
MainThread.BeginInvokeOnMainThread(() =>
{
ContentView.BackgroundColor = UIColor.SystemBackground;
_header.TextColor = ThemeHelpers.TextColor;
_separator.BackgroundColor = ThemeHelpers.SeparatorColor;
});
});
} }
catch (System.Exception ex) catch (System.Exception ex)
{ {

View File

@@ -3,6 +3,7 @@ using Bit.App.Controls;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using Microsoft.Maui.ApplicationModel;
using UIKit; using UIKit;
namespace Bit.iOS.Autofill namespace Bit.iOS.Autofill

View File

@@ -161,6 +161,18 @@ namespace Bit.iOS.Autofill
} }
} }
protected override void OnUpdateTraitAppearance()
{
base.OnUpdateTraitAppearance();
_searchBar.BackgroundColor = _searchBar.BarTintColor = ThemeHelpers.ListHeaderBackgroundColor;
_searchBar.UpdateThemeIfNeeded();
TableView.BackgroundColor = ThemeHelpers.BackgroundColor;
_emptyViewButton.Layer.BorderColor = UIColor.FromName(ColorConstants.LIGHT_TEXT_MUTED).CGColor;
}
public async Task DoFido2GetAssertionAsync(IFido2GetAssertionUserInterface fido2GetAssertionUserInterface) public async Task DoFido2GetAssertionAsync(IFido2GetAssertionUserInterface fido2GetAssertionUserInterface)
{ {
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0)) if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
@@ -436,6 +448,20 @@ namespace Bit.iOS.Autofill
} }
}); });
} }
if (message.Command == "update_traits" && UIDevice.CurrentDevice.CheckSystemVersion(17,0))
{
MainThread.InvokeOnMainThreadAsync(() =>
{
ClipLogger.Log($"[{nameof(LoginListViewController)}] updating traits");
ClipLogger.Log($"[{nameof(LoginListViewController)}] style: {TraitCollection?.UserInterfaceStyle}");
UpdateTraitsIfNeeded();
OnUpdateTraitAppearance();
View.SetNeedsLayout();
});
}
}); });
} }
@@ -535,6 +561,17 @@ namespace Bit.iOS.Autofill
} }
} }
//public override void ViewIsAppearing(bool animated)
//{
// base.ViewIsAppearing(animated);
// ClipLogger.Log($"[{nameof(LoginListViewController)}] TraitCollection: {TraitCollection?.UserInterfaceStyle}");
// ((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
// {
// ClipLogger.Log($"[LoginListViewController] changed TraitCollection: {traits.UserInterfaceStyle}");
// });
//}
public void ReloadTableViewData() => TableView.ReloadData(); public void ReloadTableViewData() => TableView.ReloadData();
public class TableSource : BaseLoginListTableSource<LoginListViewController> public class TableSource : BaseLoginListTableSource<LoginListViewController>

View File

@@ -420,6 +420,8 @@
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="FcI-Ph-m9e"> <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="FcI-Ph-m9e">
<rect key="frame" x="0.0" y="0.0" width="414" height="830"/> <rect key="frame" x="0.0" y="0.0" width="414" height="830"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="separatorColor" name="LightSecondary300"/>
<color key="sectionIndexBackgroundColor" systemColor="systemBackgroundColor"/>
<prototypes> <prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="oQZ-wW-5uB"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="oQZ-wW-5uB">
<rect key="frame" x="0.0" y="55.5" width="414" height="44"/> <rect key="frame" x="0.0" y="55.5" width="414" height="44"/>
@@ -650,6 +652,9 @@
<image name="check.png" width="90" height="90"/> <image name="check.png" width="90" height="90"/>
<image name="empty_items_state" width="157" height="111"/> <image name="empty_items_state" width="157" height="111"/>
<image name="splash_logo" width="282" height="44"/> <image name="splash_logo" width="282" height="44"/>
<namedColor name="LightSecondary300">
<color red="0.80800002813339233" green="0.83099997043609619" blue="0.86299997568130493" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</namedColor>
<namedColor name="LightTextMuted"> <namedColor name="LightTextMuted">
<color red="0.42699998617172241" green="0.45899999141693115" blue="0.49399998784065247" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.42699998617172241" green="0.45899999141693115" blue="0.49399998784065247" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor> </namedColor>

View File

@@ -221,6 +221,29 @@ namespace Bit.iOS.Core.Controllers
} }
} }
//public override void ViewIsAppearing(bool animated)
//{
// base.ViewIsAppearing(animated);
// if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
// {
// return;
// }
// ClipLogger.Log($"baselock ViewIsAppearing: {TraitCollection?.UserInterfaceStyle}");
// ((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
// {
// ClipLogger.Log($"[BaseLockPass] TraitCollection: {traits.UserInterfaceStyle}");
// MainThread.BeginInvokeOnMainThread(() =>
// {
// View.BackgroundColor = UIColor.SystemBackground;
// TableView.BackgroundColor = ThemeHelpers.BackgroundColor;
// TableView.SeparatorColor = ThemeHelpers.SeparatorColor;
// });
// });
//}
public override void ViewDidAppear(bool animated) public override void ViewDidAppear(bool animated)
{ {
try try

View File

@@ -1,5 +1,4 @@
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using System;
using UIKit; using UIKit;
namespace Bit.iOS.Core.Controllers namespace Bit.iOS.Core.Controllers
@@ -24,6 +23,35 @@ namespace Bit.iOS.Core.Controllers
public override void ViewDidLoad() public override void ViewDidLoad()
{ {
base.ViewDidLoad(); base.ViewDidLoad();
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
OnUpdateTraitAppearance();
}
}
public override void ViewIsAppearing(bool animated)
{
base.ViewIsAppearing(animated);
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
return;
}
OnUpdateTraitAppearance();
((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
{
MainThread.BeginInvokeOnMainThread(() =>
{
OnUpdateTraitAppearance();
});
});
}
protected virtual void OnUpdateTraitAppearance()
{
if (View != null) if (View != null)
{ {
View.BackgroundColor = ThemeHelpers.BackgroundColor; View.BackgroundColor = ThemeHelpers.BackgroundColor;

View File

@@ -1,5 +1,5 @@
using Bit.Core.Services;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using System;
using UIKit; using UIKit;
namespace Bit.iOS.Core.Controllers namespace Bit.iOS.Core.Controllers
@@ -28,9 +28,39 @@ namespace Bit.iOS.Core.Controllers
public override void ViewDidLoad() public override void ViewDidLoad()
{ {
base.ViewDidLoad(); base.ViewDidLoad();
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
OnUpdateTraitAppearance();
}
}
public override void ViewIsAppearing(bool animated)
{
base.ViewIsAppearing(animated);
if (!UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
return;
}
OnUpdateTraitAppearance();
((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
{
MainThread.BeginInvokeOnMainThread(() =>
{
OnUpdateTraitAppearance();
});
});
}
protected virtual void OnUpdateTraitAppearance()
{
if (View != null) if (View != null)
{ {
View.BackgroundColor = ThemeHelpers.BackgroundColor; View.BackgroundColor = ThemeHelpers.BackgroundColor;
ClipLogger.Log($"[{GetType().FullName}] back color: {View.BackgroundColor}");
} }
UpdateNavigationBarTheme(); UpdateNavigationBarTheme();
} }

View File

@@ -1,6 +1,7 @@
using Bit.App.Pages; using Bit.App.Pages;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using Microsoft.Maui.Controls.Handlers.Compatibility; using Microsoft.Maui.Controls.Handlers.Compatibility;
@@ -21,6 +22,7 @@ namespace Bit.iOS.Core.Handlers
{ {
if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY) if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
{ {
ClipLogger.Log($"CustomTabbedHandler ThemeManager.UPDATED_THEME_MESSAGE_KEY");
MainThread.BeginInvokeOnMainThread(() => MainThread.BeginInvokeOnMainThread(() =>
{ {
iOSCoreHelpers.AppearanceAdjustments(); iOSCoreHelpers.AppearanceAdjustments();

View File

@@ -1,4 +1,5 @@
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Services;
using Microsoft.Maui.Platform; using Microsoft.Maui.Platform;
using UIKit; using UIKit;
@@ -80,6 +81,8 @@ namespace Bit.iOS.Core.Utilities
private static void SetThemeVariables(string theme, bool osDarkModeEnabled) private static void SetThemeVariables(string theme, bool osDarkModeEnabled)
{ {
ClipLogger.Log($"[SetThemeVariables] {theme}, {osDarkModeEnabled}");
if (string.IsNullOrWhiteSpace(theme) && osDarkModeEnabled) if (string.IsNullOrWhiteSpace(theme) && osDarkModeEnabled)
{ {
theme = ThemeManager.Dark; theme = ThemeManager.Dark;

View File

@@ -124,7 +124,7 @@ namespace Bit.iOS.Core.Utilities
else else
{ {
#if DEBUG #if DEBUG
logger = DebugLogger.Instance; logger = ClipLogger.Instance;
#else #else
logger = Logger.Instance; logger = Logger.Instance;
#endif #endif
@@ -248,9 +248,9 @@ namespace Bit.iOS.Core.Utilities
var bootstrapTask = BootstrapAsync(postBootstrapFunc); var bootstrapTask = BootstrapAsync(postBootstrapFunc);
} }
public static void AppearanceAdjustments() public static void AppearanceAdjustments(UITraitCollection? traitCollection = null)
{ {
ThemeHelpers.SetAppearance(ThemeManager.GetTheme(), ThemeManager.OsDarkModeEnabled()); ThemeHelpers.SetAppearance(ThemeManager.GetTheme(), ThemeManager.OsDarkModeEnabled(traitCollection));
UIApplication.SharedApplication.StatusBarHidden = false; UIApplication.SharedApplication.StatusBarHidden = false;
UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.LightContent; UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.LightContent;
} }
@@ -292,6 +292,21 @@ namespace Bit.iOS.Core.Utilities
{ {
ListenYubiKey(listen, deviceActionService, nfcSession, nfcDelegate); ListenYubiKey(listen, deviceActionService, nfcSession, nfcDelegate);
} }
else if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
{
MainThread.BeginInvokeOnMainThread(() =>
{
try
{
ClipLogger.Log($"message updated theme message key");
AppearanceAdjustments();
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
});
}
}); });
} }

View File

@@ -93,6 +93,21 @@ namespace Bit.iOS.Core.Views
_separator.TrailingAnchor.ConstraintEqualTo(ContentView.TrailingAnchor, -7), _separator.TrailingAnchor.ConstraintEqualTo(ContentView.TrailingAnchor, -7),
_separator.BottomAnchor.ConstraintEqualTo(ContentView.BottomAnchor, 0) _separator.BottomAnchor.ConstraintEqualTo(ContentView.BottomAnchor, 0)
}); });
((IUITraitChangeObservable)this).RegisterForTraitChanges<UITraitUserInterfaceStyle>((env, traits) =>
{
ClipLogger.Log($"[CipherLoginTableViewCell] TraitCollection: {traits.UserInterfaceStyle}");
MainThread.BeginInvokeOnMainThread(() =>
{
ContentView.BackgroundColor = UIColor.SystemBackground;
_title.TextColor = ThemeHelpers.TextColor;
_subtitle.TextColor = ThemeHelpers.MutedColor;
_mainIcon.TextColor = ThemeHelpers.PrimaryColor;
_orgIcon.TextColor = ThemeHelpers.MutedColor;
_separator.BackgroundColor = ThemeHelpers.SeparatorColor;
_mainStackView.BackgroundColor = UIColor.SystemCyan;
});
});
} }
catch (System.Exception ex) catch (System.Exception ex)
{ {