(doAsync, canExecute, allowsMultipleExecutions ? AsyncRelayCommandOptions.AllowConcurrentExecutions : AsyncRelayCommandOptions.None);
+ }
+
+ public event EventHandler CanExecuteChanged;
+
+ public bool CanExecute(object parameter) => _relayCommand.CanExecute(parameter);
+ public void Execute(object parameter) => _relayCommand.Execute(parameter);
+ public void RaiseCanExecuteChanged() => _relayCommand.NotifyCanExecuteChanged();
+ }
+}
diff --git a/src/App/Utilities/Automation/AutomationIdsHelper.cs b/src/Core/Utilities/Automation/AutomationIdsHelper.cs
similarity index 100%
rename from src/App/Utilities/Automation/AutomationIdsHelper.cs
rename to src/Core/Utilities/Automation/AutomationIdsHelper.cs
diff --git a/src/App/Utilities/Automation/SuffixType.cs b/src/Core/Utilities/Automation/SuffixType.cs
similarity index 100%
rename from src/App/Utilities/Automation/SuffixType.cs
rename to src/Core/Utilities/Automation/SuffixType.cs
diff --git a/src/App/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs b/src/Core/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs
similarity index 93%
rename from src/App/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs
rename to src/Core/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs
index 59e9790ec..4a4d81850 100644
--- a/src/App/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs
+++ b/src/Core/Utilities/BoxRowVsBoxRowInputPaddingConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/ColoredPasswordConverter.cs b/src/Core/Utilities/ColoredPasswordConverter.cs
similarity index 93%
rename from src/App/Utilities/ColoredPasswordConverter.cs
rename to src/Core/Utilities/ColoredPasswordConverter.cs
index 60222d2fb..ba5f76769 100644
--- a/src/App/Utilities/ColoredPasswordConverter.cs
+++ b/src/Core/Utilities/ColoredPasswordConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs
index 2fa4f4ad0..cd8f37f8d 100644
--- a/src/Core/Utilities/CoreHelpers.cs
+++ b/src/Core/Utilities/CoreHelpers.cs
@@ -7,6 +7,7 @@ using System.Web;
using Bit.Core.Models.Domain;
using Bit.Core.Services;
using Newtonsoft.Json;
+using Color = Microsoft.Maui.Graphics.Color;
namespace Bit.Core.Utilities
{
@@ -268,7 +269,7 @@ namespace Bit.Core.Utilities
{
if (new ColorConverter().ConvertFromString(hexColor) is Color bgColor)
{
- var luminance = bgColor.R * 0.299 + bgColor.G * 0.587 + bgColor.B * 0.114;
+ var luminance = bgColor.Red * 0.299 + bgColor.Green * 0.587 + bgColor.Blue * 0.114;
return luminance > threshold ? "#ff000000" : "#ffffffff";
}
diff --git a/src/App/Utilities/DateTimeConverter.cs b/src/Core/Utilities/DateTimeConverter.cs
similarity index 95%
rename from src/App/Utilities/DateTimeConverter.cs
rename to src/Core/Utilities/DateTimeConverter.cs
index cd8f2cec4..5393bd3d1 100644
--- a/src/App/Utilities/DateTimeConverter.cs
+++ b/src/Core/Utilities/DateTimeConverter.cs
@@ -1,7 +1,8 @@
using System;
using Bit.App.Abstractions;
using Bit.Core.Utilities;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/EnumHelper.cs b/src/Core/Utilities/EnumHelper.cs
similarity index 91%
rename from src/App/Utilities/EnumHelper.cs
rename to src/Core/Utilities/EnumHelper.cs
index ef9faf286..59343a579 100644
--- a/src/App/Utilities/EnumHelper.cs
+++ b/src/Core/Utilities/EnumHelper.cs
@@ -1,9 +1,9 @@
using System;
using System.Linq;
using System.Reflection;
-using Bit.App.Resources;
+using Bit.Core.Resources.Localization;
using Bit.Core.Attributes;
-using Xamarin.CommunityToolkit.Helpers;
+using CommunityToolkit.Maui.Converters;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/GeneratedValueFormatter.cs b/src/Core/Utilities/GeneratedValueFormatter.cs
similarity index 85%
rename from src/App/Utilities/GeneratedValueFormatter.cs
rename to src/Core/Utilities/GeneratedValueFormatter.cs
index a718862b2..6f0199ea4 100644
--- a/src/App/Utilities/GeneratedValueFormatter.cs
+++ b/src/Core/Utilities/GeneratedValueFormatter.cs
@@ -1,6 +1,7 @@
using System;
using System.Web;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
@@ -38,7 +39,8 @@ namespace Bit.App.Utilities
// iOS won't hide the zero-width space char without these div attrs, but Android won't respect
// display:inline-block and adds a newline after the password/username. Hence, only iOS gets the div.
- if (Device.RuntimePlatform == Device.iOS)
+ // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
+ if (Device.RuntimePlatform == Device.iOS)
{
result += "";
}
@@ -112,7 +114,8 @@ namespace Bit.App.Utilities
}
// Close off iOS div
- if (Device.RuntimePlatform == Device.iOS)
+ // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
+ if (Device.RuntimePlatform == Device.iOS)
{
result += "
";
}
diff --git a/src/App/Utilities/I18nExtension.cs b/src/Core/Utilities/I18nExtension.cs
similarity index 90%
rename from src/App/Utilities/I18nExtension.cs
rename to src/Core/Utilities/I18nExtension.cs
index b66040c75..e048d1afe 100644
--- a/src/App/Utilities/I18nExtension.cs
+++ b/src/Core/Utilities/I18nExtension.cs
@@ -1,8 +1,9 @@
using System;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
-using Xamarin.Forms;
-using Xamarin.Forms.Xaml;
+using Microsoft.Maui.Controls.Xaml;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/IPasswordPromptable.cs b/src/Core/Utilities/IPasswordPromptable.cs
similarity index 100%
rename from src/App/Utilities/IPasswordPromptable.cs
rename to src/Core/Utilities/IPasswordPromptable.cs
diff --git a/src/App/Utilities/IconGlyphConverter.cs b/src/Core/Utilities/IconGlyphConverter.cs
similarity index 94%
rename from src/App/Utilities/IconGlyphConverter.cs
rename to src/Core/Utilities/IconGlyphConverter.cs
index c68c103ac..1c51688fb 100644
--- a/src/App/Utilities/IconGlyphConverter.cs
+++ b/src/Core/Utilities/IconGlyphConverter.cs
@@ -1,7 +1,8 @@
using System;
using System.Globalization;
using Bit.Core.Models.View;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/IconGlyphExtensions.cs b/src/Core/Utilities/IconGlyphExtensions.cs
similarity index 100%
rename from src/App/Utilities/IconGlyphExtensions.cs
rename to src/Core/Utilities/IconGlyphExtensions.cs
diff --git a/src/App/Utilities/IconImageConverter.cs b/src/Core/Utilities/IconImageConverter.cs
similarity index 98%
rename from src/App/Utilities/IconImageConverter.cs
rename to src/Core/Utilities/IconImageConverter.cs
index 0c4a98a29..70225579a 100644
--- a/src/App/Utilities/IconImageConverter.cs
+++ b/src/Core/Utilities/IconImageConverter.cs
@@ -4,7 +4,8 @@ using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/InverseBoolConverter.cs b/src/Core/Utilities/InverseBoolConverter.cs
similarity index 92%
rename from src/App/Utilities/InverseBoolConverter.cs
rename to src/Core/Utilities/InverseBoolConverter.cs
index b0ee98993..27f6a0e8c 100644
--- a/src/App/Utilities/InverseBoolConverter.cs
+++ b/src/Core/Utilities/InverseBoolConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/IsNotNullConverter.cs b/src/Core/Utilities/IsNotNullConverter.cs
similarity index 92%
rename from src/App/Utilities/IsNotNullConverter.cs
rename to src/Core/Utilities/IsNotNullConverter.cs
index 5888ab362..c0d309fee 100644
--- a/src/App/Utilities/IsNotNullConverter.cs
+++ b/src/Core/Utilities/IsNotNullConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/IsNullConverter.cs b/src/Core/Utilities/IsNullConverter.cs
similarity index 92%
rename from src/App/Utilities/IsNullConverter.cs
rename to src/Core/Utilities/IsNullConverter.cs
index 0d6f85964..6961eb177 100644
--- a/src/App/Utilities/IsNullConverter.cs
+++ b/src/Core/Utilities/IsNullConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/LocalizableEnumConverter.cs b/src/Core/Utilities/LocalizableEnumConverter.cs
similarity index 92%
rename from src/App/Utilities/LocalizableEnumConverter.cs
rename to src/Core/Utilities/LocalizableEnumConverter.cs
index 8c1dc287a..1da0cf1ba 100644
--- a/src/App/Utilities/LocalizableEnumConverter.cs
+++ b/src/Core/Utilities/LocalizableEnumConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/Core/Utilities/ObservableRangeCollection.cs b/src/Core/Utilities/ObservableRangeCollection.cs
new file mode 100644
index 000000000..7eaf9d786
--- /dev/null
+++ b/src/Core/Utilities/ObservableRangeCollection.cs
@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+
+#nullable enable
+
+namespace Bit.Core.Utilities
+{
+ // TODO: [MAUI-Migration] CHECK WHEN MIGRATION IS DONE
+
+ ///
+ /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
+ ///
+ ///
+ public class ObservableRangeCollection : ObservableCollection
+ {
+ ///
+ /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
+ ///
+ public ObservableRangeCollection()
+ : base()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
+ ///
+ /// collection: The collection from which the elements are copied.
+ /// The collection parameter cannot be null.
+ public ObservableRangeCollection(IEnumerable collection)
+ : base(collection)
+ {
+ }
+
+ ///
+ /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
+ ///
+ public void AddRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
+ {
+ if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset)
+ throw new ArgumentException("Mode must be either Add or Reset for AddRange.", nameof(notificationMode));
+ if (collection == null)
+ throw new ArgumentNullException(nameof(collection));
+
+ CheckReentrancy();
+
+ var startIndex = Count;
+
+ var itemsAdded = AddArrangeCore(collection);
+
+ if (!itemsAdded)
+ return;
+
+ if (notificationMode == NotifyCollectionChangedAction.Reset)
+ {
+ RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
+ return;
+ }
+
+ var changedItems = collection is List
+ ? (List)collection
+ : new List(collection);
+
+ RaiseChangeNotificationEvents(
+ action: NotifyCollectionChangedAction.Add,
+ changedItems: changedItems,
+ startingIndex: startIndex);
+ }
+
+ ///
+ /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive.
+ ///
+ public void RemoveRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset)
+ {
+ if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset)
+ throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", nameof(notificationMode));
+ if (collection == null)
+ throw new ArgumentNullException(nameof(collection));
+
+ CheckReentrancy();
+
+ if (notificationMode == NotifyCollectionChangedAction.Reset)
+ {
+ var raiseEvents = false;
+ foreach (var item in collection)
+ {
+ Items.Remove(item);
+ raiseEvents = true;
+ }
+
+ if (raiseEvents)
+ RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
+
+ return;
+ }
+
+ var changedItems = new List(collection);
+ for (var i = 0; i < changedItems.Count; i++)
+ {
+ if (!Items.Remove(changedItems[i]))
+ {
+ changedItems.RemoveAt(i); // Can't use a foreach because changedItems is intended to be (carefully) modified
+ i--;
+ }
+ }
+
+ if (changedItems.Count == 0)
+ return;
+
+ RaiseChangeNotificationEvents(
+ action: NotifyCollectionChangedAction.Remove,
+ changedItems: changedItems);
+ }
+
+ ///
+ /// Clears the current collection and replaces it with the specified item.
+ ///
+ public void Replace(T item) => ReplaceRange(new T[] { item });
+
+ ///
+ /// Clears the current collection and replaces it with the specified collection.
+ ///
+ public void ReplaceRange(IEnumerable collection)
+ {
+ if (collection == null)
+ throw new ArgumentNullException(nameof(collection));
+
+ CheckReentrancy();
+
+ var previouslyEmpty = Items.Count == 0;
+
+ Items.Clear();
+
+ AddArrangeCore(collection);
+
+ var currentlyEmpty = Items.Count == 0;
+
+ if (previouslyEmpty && currentlyEmpty)
+ return;
+
+ RaiseChangeNotificationEvents(action: NotifyCollectionChangedAction.Reset);
+ }
+
+ bool AddArrangeCore(IEnumerable collection)
+ {
+ var itemAdded = false;
+ foreach (var item in collection)
+ {
+ Items.Add(item);
+ itemAdded = true;
+ }
+ return itemAdded;
+ }
+
+ void RaiseChangeNotificationEvents(NotifyCollectionChangedAction action, List? changedItems = null, int startingIndex = -1)
+ {
+ OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
+ OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
+
+ if (changedItems == null)
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(action));
+ else
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, changedItems: changedItems, startingIndex: startingIndex));
+ }
+ }
+}
diff --git a/src/App/Utilities/PageExtensions.cs b/src/Core/Utilities/PageExtensions.cs
similarity index 97%
rename from src/App/Utilities/PageExtensions.cs
rename to src/Core/Utilities/PageExtensions.cs
index ec64f20ef..fe8132a65 100644
--- a/src/App/Utilities/PageExtensions.cs
+++ b/src/Core/Utilities/PageExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/PermissionManager.cs b/src/Core/Utilities/PermissionManager.cs
similarity index 83%
rename from src/App/Utilities/PermissionManager.cs
rename to src/Core/Utilities/PermissionManager.cs
index 8af2ecff2..100ce7cb5 100644
--- a/src/App/Utilities/PermissionManager.cs
+++ b/src/Core/Utilities/PermissionManager.cs
@@ -1,6 +1,6 @@
using System.Threading.Tasks;
-using Xamarin.Essentials;
-using static Xamarin.Essentials.Permissions;
+using static Microsoft.Maui.ApplicationModel.Permissions;
+using Microsoft.Maui.ApplicationModel;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/ProgressBarExtensions.cs b/src/Core/Utilities/ProgressBarExtensions.cs
similarity index 88%
rename from src/App/Utilities/ProgressBarExtensions.cs
rename to src/Core/Utilities/ProgressBarExtensions.cs
index 7dcf15f85..d73d49ffe 100644
--- a/src/App/Utilities/ProgressBarExtensions.cs
+++ b/src/Core/Utilities/ProgressBarExtensions.cs
@@ -1,6 +1,4 @@
-using Xamarin.Forms;
-
-namespace Bit.App.Utilities
+namespace Bit.App.Utilities
{
public static class ProgressBarExtensions
{
@@ -17,7 +15,7 @@ namespace Bit.App.Utilities
private static void ProgressBarProgressChanged(ProgressBar progressBar, double progress)
{
- ViewExtensions.CancelAnimations(progressBar);
+ Microsoft.Maui.Controls.ViewExtensions.CancelAnimations(progressBar);
progressBar.ProgressTo(progress, 500, Easing.SinIn);
}
}
diff --git a/src/App/Utilities/Prompts/ValidatablePromptConfig.cs b/src/Core/Utilities/Prompts/ValidatablePromptConfig.cs
similarity index 100%
rename from src/App/Utilities/Prompts/ValidatablePromptConfig.cs
rename to src/Core/Utilities/Prompts/ValidatablePromptConfig.cs
diff --git a/src/App/Utilities/SendIconGlyphConverter.cs b/src/Core/Utilities/SendIconGlyphConverter.cs
similarity index 94%
rename from src/App/Utilities/SendIconGlyphConverter.cs
rename to src/Core/Utilities/SendIconGlyphConverter.cs
index 512586768..1cf2fc5f1 100644
--- a/src/App/Utilities/SendIconGlyphConverter.cs
+++ b/src/Core/Utilities/SendIconGlyphConverter.cs
@@ -3,7 +3,8 @@ using System.Globalization;
using Bit.Core;
using Bit.Core.Enums;
using Bit.Core.Models.View;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/StringHasValueConverter.cs b/src/Core/Utilities/StringHasValueConverter.cs
similarity index 94%
rename from src/App/Utilities/StringHasValueConverter.cs
rename to src/Core/Utilities/StringHasValueConverter.cs
index 4410c9143..b0f3245db 100644
--- a/src/App/Utilities/StringHasValueConverter.cs
+++ b/src/Core/Utilities/StringHasValueConverter.cs
@@ -1,5 +1,6 @@
using System;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/ThemeManager.cs b/src/Core/Utilities/ThemeManager.cs
similarity index 93%
rename from src/App/Utilities/ThemeManager.cs
rename to src/Core/Utilities/ThemeManager.cs
index ead18f8a1..ce12dcd66 100644
--- a/src/App/Utilities/ThemeManager.cs
+++ b/src/Core/Utilities/ThemeManager.cs
@@ -6,7 +6,9 @@ using Bit.App.Styles;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
-using Xamarin.Forms;
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
@@ -63,7 +65,8 @@ namespace Bit.App.Utilities
resources.MergedDictionaries.Add(new ControlTemplates());
// Platform styles
- if (Device.RuntimePlatform == Device.Android)
+ // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
+ if (Device.RuntimePlatform == Device.Android)
{
resources.MergedDictionaries.Add(new Styles.Android());
}
@@ -150,9 +153,9 @@ namespace Bit.App.Utilities
{
// called from iOS extension
var app = new App(new AppOptions { IosExtension = true });
- return app.RequestedTheme == OSAppTheme.Dark;
+ return app.RequestedTheme == AppTheme.Dark;
}
- return Application.Current.RequestedTheme == OSAppTheme.Dark;
+ return Application.Current.RequestedTheme == AppTheme.Dark;
}
public static void ApplyResourcesTo(VisualElement element)
diff --git a/src/App/Utilities/TimerTask.cs b/src/Core/Utilities/TimerTask.cs
similarity index 98%
rename from src/App/Utilities/TimerTask.cs
rename to src/Core/Utilities/TimerTask.cs
index 0288408ac..27e0b81af 100644
--- a/src/App/Utilities/TimerTask.cs
+++ b/src/Core/Utilities/TimerTask.cs
@@ -2,7 +2,8 @@
using System.Threading;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/TotpHelper.cs b/src/Core/Utilities/TotpHelper.cs
similarity index 100%
rename from src/App/Utilities/TotpHelper.cs
rename to src/Core/Utilities/TotpHelper.cs
diff --git a/src/App/Utilities/UpperCaseConverter.cs b/src/Core/Utilities/UpperCaseConverter.cs
similarity index 93%
rename from src/App/Utilities/UpperCaseConverter.cs
rename to src/Core/Utilities/UpperCaseConverter.cs
index 592f95326..a02c83de9 100644
--- a/src/App/Utilities/UpperCaseConverter.cs
+++ b/src/Core/Utilities/UpperCaseConverter.cs
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/App/Utilities/VerificationActionsFlowHelper.cs b/src/Core/Utilities/VerificationActionsFlowHelper.cs
similarity index 99%
rename from src/App/Utilities/VerificationActionsFlowHelper.cs
rename to src/Core/Utilities/VerificationActionsFlowHelper.cs
index 8d916f051..a12bf3063 100644
--- a/src/App/Utilities/VerificationActionsFlowHelper.cs
+++ b/src/Core/Utilities/VerificationActionsFlowHelper.cs
@@ -7,7 +7,8 @@ using Bit.App.Pages.Accounts;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui;
namespace Bit.App.Utilities
{
diff --git a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs
index f2fcfc008..53161a44c 100644
--- a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs
+++ b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs
@@ -3,7 +3,7 @@ using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Pages;
-using Bit.App.Resources;
+using Bit.Core.Resources.Localization;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
@@ -15,8 +15,7 @@ using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Views;
using Foundation;
using UIKit;
-using Xamarin.Essentials;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls.Compatibility;
namespace Bit.iOS.Core.Controllers
{
diff --git a/src/iOS.Core/Controllers/LoginAddViewController.cs b/src/iOS.Core/Controllers/LoginAddViewController.cs
index 359e84f00..385655fc1 100644
--- a/src/iOS.Core/Controllers/LoginAddViewController.cs
+++ b/src/iOS.Core/Controllers/LoginAddViewController.cs
@@ -5,7 +5,7 @@ using System.Threading.Tasks;
using AuthenticationServices;
using Bit.App.Models;
using Bit.App.Pages;
-using Bit.App.Resources;
+using Bit.Core.Resources.Localization;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
@@ -17,7 +17,7 @@ using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Views;
using Foundation;
using UIKit;
-using Xamarin.Forms;
+using Microsoft.Maui.Controls.Compatibility;
namespace Bit.iOS.Core.Controllers
{
diff --git a/src/iOS.Core/Controllers/PasswordGeneratorViewController.cs b/src/iOS.Core/Controllers/PasswordGeneratorViewController.cs
index 17bf8a911..64b709f68 100644
--- a/src/iOS.Core/Controllers/PasswordGeneratorViewController.cs
+++ b/src/iOS.Core/Controllers/PasswordGeneratorViewController.cs
@@ -6,7 +6,7 @@ using Foundation;
using UIKit;
using CoreGraphics;
using Bit.iOS.Core.Utilities;
-using Bit.App.Resources;
+using Bit.Core.Resources.Localization;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System.Threading.Tasks;
diff --git a/src/iOS.Core/Effects/NoEmojiKeyboardEffect.cs b/src/iOS.Core/Effects/NoEmojiKeyboardEffect.cs
index abc3db490..3bc2c9b29 100644
--- a/src/iOS.Core/Effects/NoEmojiKeyboardEffect.cs
+++ b/src/iOS.Core/Effects/NoEmojiKeyboardEffect.cs
@@ -1,10 +1,6 @@
-using System;
-using Bit.iOS.Core.Effects;
+using Microsoft.Maui.Controls.Platform;
using UIKit;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.iOS;
-[assembly: ExportEffect(typeof(NoEmojiKeyboardEffect), nameof(NoEmojiKeyboardEffect))]
namespace Bit.iOS.Core.Effects
{
public class NoEmojiKeyboardEffect : PlatformEffect
@@ -22,4 +18,3 @@ namespace Bit.iOS.Core.Effects
}
}
}
-
diff --git a/src/iOS.Core/Effects/ScrollEnabledEffect.cs b/src/iOS.Core/Effects/ScrollEnabledEffect.cs
index 13fde6994..214473d74 100644
--- a/src/iOS.Core/Effects/ScrollEnabledEffect.cs
+++ b/src/iOS.Core/Effects/ScrollEnabledEffect.cs
@@ -1,25 +1,27 @@
-using Bit.iOS.Core.Effects;
-using UIKit;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.iOS;
+// TODO: [MAUI-Migration] Check if moving this to the main project works for extensions.
-[assembly: ResolutionGroupName("Bitwarden")]
-[assembly: ExportEffect(typeof(ScrollEnabledEffect), "ScrollEnabledEffect")]
-namespace Bit.iOS.Core.Effects
-{
- public class ScrollEnabledEffect : PlatformEffect
- {
- protected override void OnAttached()
- {
- // this can be for any view that inherits from UIScrollView like UITextView.
- if (Element != null && Control is UIScrollView scrollView)
- {
- scrollView.ScrollEnabled = App.Effects.ScrollEnabledEffect.GetIsScrollEnabled(Element);
- }
- }
+//using Bit.iOS.Core.Effects;
+//using UIKit;
+//using Xamarin.Forms;
+//using Xamarin.Forms.Platform.iOS;
- protected override void OnDetached()
- {
- }
- }
-}
+//[assembly: ResolutionGroupName("Bitwarden")]
+//[assembly: ExportEffect(typeof(ScrollEnabledEffect), "ScrollEnabledEffect")]
+//namespace Bit.iOS.Core.Effects
+//{
+// public class ScrollEnabledEffect : PlatformEffect
+// {
+// protected override void OnAttached()
+// {
+// // this can be for any view that inherits from UIScrollView like UITextView.
+// if (Element != null && Control is UIScrollView scrollView)
+// {
+// scrollView.ScrollEnabled = App.Effects.ScrollEnabledEffect.GetIsScrollEnabled(Element);
+// }
+// }
+
+// protected override void OnDetached()
+// {
+// }
+// }
+//}
diff --git a/src/iOS.Core/Effects/ScrollViewContentInsetAdjustmentBehaviorEffect.cs b/src/iOS.Core/Effects/ScrollViewContentInsetAdjustmentBehaviorEffect.cs
index 17450523c..91167367c 100644
--- a/src/iOS.Core/Effects/ScrollViewContentInsetAdjustmentBehaviorEffect.cs
+++ b/src/iOS.Core/Effects/ScrollViewContentInsetAdjustmentBehaviorEffect.cs
@@ -1,37 +1,39 @@
-using Bit.iOS.Core.Effects;
-using UIKit;
-using Xamarin.Forms;
-using Xamarin.Forms.Platform.iOS;
+// TODO: [MAUI-Migration] Check if moving this to the main project works for extensions.
-[assembly: ExportEffect(typeof(ScrollViewContentInsetAdjustmentBehaviorEffect), nameof(ScrollViewContentInsetAdjustmentBehaviorEffect))]
-namespace Bit.iOS.Core.Effects
-{
- public class ScrollViewContentInsetAdjustmentBehaviorEffect : PlatformEffect
- {
- protected override void OnAttached()
- {
- if (Element != null && Control is UIScrollView scrollView)
- {
- switch (App.Effects.ScrollViewContentInsetAdjustmentBehaviorEffect.GetContentInsetAdjustmentBehavior(Element))
- {
- case App.Effects.ScrollContentInsetAdjustmentBehavior.Automatic:
- scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Automatic;
- break;
- case App.Effects.ScrollContentInsetAdjustmentBehavior.ScrollableAxes:
- scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.ScrollableAxes;
- break;
- case App.Effects.ScrollContentInsetAdjustmentBehavior.Never:
- scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Never;
- break;
- case App.Effects.ScrollContentInsetAdjustmentBehavior.Always:
- scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Always;
- break;
- }
- }
- }
+//using Bit.iOS.Core.Effects;
+//using UIKit;
+//using Xamarin.Forms;
+//using Xamarin.Forms.Platform.iOS;
- protected override void OnDetached()
- {
- }
- }
-}
+//[assembly: ExportEffect(typeof(ScrollViewContentInsetAdjustmentBehaviorEffect), nameof(ScrollViewContentInsetAdjustmentBehaviorEffect))]
+//namespace Bit.iOS.Core.Effects
+//{
+// public class ScrollViewContentInsetAdjustmentBehaviorEffect : PlatformEffect
+// {
+// protected override void OnAttached()
+// {
+// if (Element != null && Control is UIScrollView scrollView)
+// {
+// switch (App.Effects.ScrollViewContentInsetAdjustmentBehaviorEffect.GetContentInsetAdjustmentBehavior(Element))
+// {
+// case App.Effects.ScrollContentInsetAdjustmentBehavior.Automatic:
+// scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Automatic;
+// break;
+// case App.Effects.ScrollContentInsetAdjustmentBehavior.ScrollableAxes:
+// scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.ScrollableAxes;
+// break;
+// case App.Effects.ScrollContentInsetAdjustmentBehavior.Never:
+// scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Never;
+// break;
+// case App.Effects.ScrollContentInsetAdjustmentBehavior.Always:
+// scrollView.ContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Always;
+// break;
+// }
+// }
+// }
+
+// protected override void OnDetached()
+// {
+// }
+// }
+//}
diff --git a/src/iOS.Core/Handlers/ButtonHandlerMappings.cs b/src/iOS.Core/Handlers/ButtonHandlerMappings.cs
new file mode 100644
index 000000000..04104cd77
--- /dev/null
+++ b/src/iOS.Core/Handlers/ButtonHandlerMappings.cs
@@ -0,0 +1,21 @@
+using System;
+using Bit.iOS.Core.Utilities;
+
+namespace Bit.iOS.Core.Handlers
+{
+ public class ButtonHandlerMappings
+ {
+ public static void Setup()
+ {
+ // TODO: [Maui-Migration] Check if this is needed given that on MAUI FontAutoScalingEnabled is true by default.
+ //Microsoft.Maui.Handlers.ButtonHandler.Mapper.AppendToMapping("CustomButtonHandler", (handler, button) =>
+ //{
+ // var pointSize = iOSHelpers.GetAccessibleFont