mirror of
https://github.com/bitwarden/mobile
synced 2025-12-10 21:33:36 +00:00
MAUI Migration Single Project - Android - Fonts, renderers, effects
This commit is contained in:
@@ -45,10 +45,8 @@
|
|||||||
<MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />
|
<MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />
|
||||||
|
|
||||||
<!-- Custom Fonts -->
|
<!-- Custom Fonts -->
|
||||||
<MauiFont Include="Resources\Fonts\*" />
|
|
||||||
|
|
||||||
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
|
|
||||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||||
|
<MauiFont Include="Resources\Fonts\*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -302,6 +300,10 @@
|
|||||||
<None Remove="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher.png" />
|
<None Remove="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher.png" />
|
||||||
<None Remove="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher_round.png" />
|
<None Remove="Platforms\Android\Resources\mipmap-xhdpi\ic_launcher_round.png" />
|
||||||
<None Remove="Platforms\Android\google-services.json" />
|
<None Remove="Platforms\Android\google-services.json" />
|
||||||
|
<None Remove="Resources\Fonts\" />
|
||||||
|
<None Remove="Resources\Fonts\bwi-font.ttf" />
|
||||||
|
<None Remove="Resources\Fonts\MaterialIcons_Regular.ttf" />
|
||||||
|
<None Remove="Resources\Fonts\RobotoMono_Regular.ttf" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Core\" />
|
<Folder Include="Core\" />
|
||||||
@@ -313,6 +315,7 @@
|
|||||||
<Folder Include="Core\Resources\" />
|
<Folder Include="Core\Resources\" />
|
||||||
<Folder Include="Core\Services\" />
|
<Folder Include="Core\Services\" />
|
||||||
<Folder Include="Core\Utilities\" />
|
<Folder Include="Core\Utilities\" />
|
||||||
|
<Folder Include="Resources\Fonts\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Core\Resources\eff_long_word_list.txt" />
|
<EmbeddedResource Include="Core\Resources\eff_long_word_list.txt" />
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Bit.App.Controls
|
|||||||
FontFamily = "bwi-font";
|
FontFamily = "bwi-font";
|
||||||
break;
|
break;
|
||||||
case Device.Android:
|
case Device.Android:
|
||||||
FontFamily = "bwi-font.ttf#bwi-font";
|
FontFamily = "bwi-font";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Bit.App.Controls
|
|||||||
FontFamily = "bwi-font";
|
FontFamily = "bwi-font";
|
||||||
break;
|
break;
|
||||||
case Device.Android:
|
case Device.Android:
|
||||||
FontFamily = "bwi-font.ttf#bwi-font";
|
FontFamily = "bwi-font";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Bit.App.Controls
|
|||||||
FontFamily = "Material Icons";
|
FontFamily = "Material Icons";
|
||||||
break;
|
break;
|
||||||
case Device.Android:
|
case Device.Android:
|
||||||
FontFamily = "MaterialIcons_Regular.ttf#Material Icons";
|
FontFamily = "MaterialIcons_Regular";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Bit.App.Controls
|
|||||||
FontFamily = "Material Icons";
|
FontFamily = "Material Icons";
|
||||||
break;
|
break;
|
||||||
case Device.Android:
|
case Device.Android:
|
||||||
FontFamily = "MaterialIcons_Regular.ttf#Material Icons";
|
FontFamily = "MaterialIcons_Regular";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,11 @@ namespace Bit.App.Controls
|
|||||||
{
|
{
|
||||||
public MonoEntry()
|
public MonoEntry()
|
||||||
{
|
{
|
||||||
// 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 ANDROID
|
||||||
switch (Device.RuntimePlatform)
|
FontFamily = "RobotoMono_Regular";
|
||||||
{
|
#elif IOS
|
||||||
case Device.iOS:
|
|
||||||
FontFamily = "Menlo-Regular";
|
FontFamily = "Menlo-Regular";
|
||||||
break;
|
#endif
|
||||||
case Device.Android:
|
|
||||||
FontFamily = "RobotoMono_Regular.ttf#Roboto Mono";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Bit.App.Controls
|
|||||||
FontFamily = "Menlo-Regular";
|
FontFamily = "Menlo-Regular";
|
||||||
break;
|
break;
|
||||||
case Device.Android:
|
case Device.Android:
|
||||||
FontFamily = "RobotoMono_Regular.ttf#Roboto Mono";
|
FontFamily = "RobotoMono_Regular";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,38 @@
|
|||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
using Bit.App.Droid.Utilities;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bit.App.Effects
|
namespace Bit.App.Effects
|
||||||
{
|
{
|
||||||
public class FabShadowEffect : RoutingEffect
|
public class FabShadowEffect : RoutingEffect
|
||||||
{
|
{
|
||||||
public FabShadowEffect()
|
|
||||||
: base("Bitwarden.FabShadowEffect")
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
public class FabShadowPlatformEffect : PlatformEffect
|
||||||
|
{
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
if (Control is Android.Widget.Button button)
|
||||||
|
{
|
||||||
|
var gd = new GradientDrawable();
|
||||||
|
gd.SetColor(ThemeHelpers.FabColor);
|
||||||
|
gd.SetCornerRadius(100);
|
||||||
|
|
||||||
|
button.SetBackground(gd);
|
||||||
|
button.Elevation = 6;
|
||||||
|
button.TranslationZ = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,32 @@
|
|||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Widget;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Bit.App.Effects
|
namespace Bit.App.Effects
|
||||||
{
|
{
|
||||||
public class FixedSizeEffect : RoutingEffect
|
public class FixedSizeEffect : RoutingEffect
|
||||||
{
|
{
|
||||||
public FixedSizeEffect()
|
|
||||||
: base("Bitwarden.FixedSizeEffect")
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
public class FixedSizePlatformEffect : PlatformEffect
|
||||||
|
{
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
if (Element is Label label && Control is TextView textView)
|
||||||
|
{
|
||||||
|
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Widget;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bit.App.Effects
|
namespace Bit.App.Effects
|
||||||
{
|
{
|
||||||
public class NoEmojiKeyboardEffect : RoutingEffect
|
public class NoEmojiKeyboardEffect : RoutingEffect
|
||||||
{
|
{
|
||||||
public NoEmojiKeyboardEffect()
|
|
||||||
: base("Bitwarden.NoEmojiKeyboardEffect")
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
public class NoEmojiKeyboardPlatformEffect : PlatformEffect
|
||||||
|
{
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
if (Control is EditText editText)
|
||||||
|
{
|
||||||
|
editText.InputType = Android.Text.InputTypes.ClassText | Android.Text.InputTypes.TextVariationVisiblePassword | Android.Text.InputTypes.TextFlagMultiLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
#if ANDROID
|
||||||
|
using Android.Widget;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bit.App.Effects
|
namespace Bit.App.Effects
|
||||||
{
|
{
|
||||||
public class RemoveFontPaddingEffect : RoutingEffect
|
public class RemoveFontPaddingEffect : RoutingEffect
|
||||||
{
|
{
|
||||||
public RemoveFontPaddingEffect()
|
|
||||||
: base("Bitwarden.RemoveFontPaddingEffect")
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
public class RemoveFontPaddingPlatformEffect : PlatformEffect
|
||||||
|
{
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
if (Control is TextView textView)
|
||||||
|
{
|
||||||
|
textView.SetIncludeFontPadding(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
namespace Bit.App.Effects
|
namespace Bit.App.Effects
|
||||||
{
|
{
|
||||||
public class TabBarEffect : RoutingEffect
|
public class TabBarEffect : RoutingEffect
|
||||||
{
|
{
|
||||||
public TabBarEffect()
|
|
||||||
: base("Bitwarden.TabBarEffect")
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
public class TabBarPlatformEffect : PlatformEffect
|
||||||
|
{
|
||||||
|
protected override void OnAttached()
|
||||||
|
{
|
||||||
|
// TODO: [MAUI-Migration] [Critical]
|
||||||
|
// now Container is View instead of ViewGroup, let's review this
|
||||||
|
//if (!(Container.GetChildAt(0) is ViewGroup layout))
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDetached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Bit.App.Controls;
|
||||||
using CommunityToolkit.Maui;
|
using CommunityToolkit.Maui;
|
||||||
using FFImageLoading.Maui;
|
using FFImageLoading.Maui;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -13,7 +14,7 @@ namespace Bit.App;
|
|||||||
|
|
||||||
public static class MauiProgram
|
public static class MauiProgram
|
||||||
{
|
{
|
||||||
public static MauiApp CreateMauiApp(Action<IEffectsBuilder> effectsBuilder)
|
public static MauiApp CreateMauiApp()
|
||||||
{
|
{
|
||||||
var builder = MauiApp.CreateBuilder();
|
var builder = MauiApp.CreateBuilder();
|
||||||
builder
|
builder
|
||||||
@@ -23,12 +24,47 @@ public static class MauiProgram
|
|||||||
.UseBarcodeReader()
|
.UseBarcodeReader()
|
||||||
.UseSkiaSharp()
|
.UseSkiaSharp()
|
||||||
.UseFFImageLoading()
|
.UseFFImageLoading()
|
||||||
.ConfigureEffects(effectsBuilder)
|
.ConfigureEffects(effects =>
|
||||||
|
{
|
||||||
|
#if ANDROID
|
||||||
|
effects.Add<Effects.FabShadowEffect, Effects.FabShadowPlatformEffect>();
|
||||||
|
effects.Add<Effects.FixedSizeEffect, Effects.FixedSizePlatformEffect>();
|
||||||
|
effects.Add<Effects.NoEmojiKeyboardEffect, Effects.NoEmojiKeyboardPlatformEffect>();
|
||||||
|
effects.Add<Effects.TabBarEffect, Effects.TabBarPlatformEffect>();
|
||||||
|
effects.Add<Effects.RemoveFontPaddingEffect, Effects.RemoveFontPaddingPlatformEffect>();
|
||||||
|
#endif
|
||||||
|
})
|
||||||
.ConfigureFonts(fonts =>
|
.ConfigureFonts(fonts =>
|
||||||
{
|
{
|
||||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
fonts.AddFont("RobotoMono_Regular.ttf#Roboto Mono", "RobotoMono_Regular");
|
||||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
fonts.AddFont("bwi-font.ttf#bwi-font", "bwi-font");
|
||||||
|
fonts.AddFont("MaterialIcons_Regular.ttf#Material Icons", "MaterialIcons_Regular");
|
||||||
});
|
});
|
||||||
|
// TODO: [MAUI-Migration] Convert renderers to handlers
|
||||||
|
// Currently, there's an issue on reusing renderers https://github.com/dotnet/maui/issues/9936
|
||||||
|
// .ConfigureMauiHandlers(handlers =>
|
||||||
|
// {
|
||||||
|
//#if ANDROID
|
||||||
|
// handlers.AddHandler(typeof(Editor), typeof(Droid.Renderers.CustomEditorRenderer));
|
||||||
|
// handlers.AddHandler(typeof(Entry), typeof(Droid.Renderers.CustomEntryRenderer));
|
||||||
|
// handlers.AddHandler(typeof(CustomLabel), typeof(Droid.Renderers.CustomLabelRenderer));
|
||||||
|
// //handlers.AddHandler(typeof(ContentPage), typeof(Droid.Renderers.CustomPageRenderer));
|
||||||
|
// handlers.AddHandler(typeof(Picker), typeof(Droid.Renderers.CustomPickerRenderer));
|
||||||
|
// handlers.AddHandler(typeof(SearchBar), typeof(Droid.Renderers.CustomSearchBarRenderer));
|
||||||
|
// handlers.AddHandler(typeof(Switch), typeof(Droid.Renderers.CustomSwitchRenderer));
|
||||||
|
// handlers.AddHandler(typeof(TabbedPage), typeof(Droid.Renderers.CustomTabbedRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedDatePicker), typeof(Droid.Renderers.ExtendedDatePickerRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedGrid), typeof(Droid.Renderers.ExtendedGridRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedSlider), typeof(Droid.Renderers.ExtendedSliderRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedStackLayout), typeof(Droid.Renderers.ExtendedStackLayoutRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedStepper), typeof(Droid.Renderers.ExtendedStepperRenderer));
|
||||||
|
// handlers.AddHandler(typeof(ExtendedTimePicker), typeof(Droid.Renderers.ExtendedTimePickerRenderer));
|
||||||
|
// handlers.AddHandler(typeof(HybridWebView), typeof(Droid.Renderers.HybridWebViewRenderer));
|
||||||
|
// handlers.AddHandler(typeof(SelectableLabel), typeof(Droid.Renderers.SelectableLabelRenderer));
|
||||||
|
//#elif IOS
|
||||||
|
// // TODO: configure
|
||||||
|
//#endif
|
||||||
|
// });
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
builder.Logging.AddDebug();
|
builder.Logging.AddDebug();
|
||||||
|
|||||||
@@ -199,11 +199,14 @@ namespace Bit.App.Pages
|
|||||||
Text = string.Format("{0}:", AppResources.PasswordHistory),
|
Text = string.Format("{0}:", AppResources.PasswordHistory),
|
||||||
FontAttributes = FontAttributes.Bold
|
FontAttributes = FontAttributes.Bold
|
||||||
});
|
});
|
||||||
|
if (Cipher?.PasswordHistory != null)
|
||||||
|
{
|
||||||
fs.Spans.Add(new Span
|
fs.Spans.Add(new Span
|
||||||
{
|
{
|
||||||
Text = string.Format(" {0}", Cipher.PasswordHistory.Count.ToString()),
|
Text = string.Format(" {0}", Cipher.PasswordHistory.Count.ToString()),
|
||||||
TextColor = ThemeManager.GetResourceColor("PrimaryColor")
|
TextColor = ThemeManager.GetResourceColor("PrimaryColor")
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace Bit.App.Pages
|
|||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
if (_syncService.SyncInProgress)
|
if (_syncService.SyncInProgress)
|
||||||
{
|
{
|
||||||
IsBusy = true;
|
MainThread.BeginInvokeOnMainThread(() => IsBusy = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountAvatar?.OnAppearing();
|
_accountAvatar?.OnAppearing();
|
||||||
@@ -105,7 +105,7 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
if (message.Command == "syncStarted")
|
if (message.Command == "syncStarted")
|
||||||
{
|
{
|
||||||
Device.BeginInvokeOnMainThread(() => IsBusy = true);
|
MainThread.BeginInvokeOnMainThread(() => IsBusy = true);
|
||||||
}
|
}
|
||||||
else if (message.Command == "syncCompleted")
|
else if (message.Command == "syncCompleted")
|
||||||
{
|
{
|
||||||
@@ -114,7 +114,7 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||||
}
|
}
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
MainThread.BeginInvokeOnMainThread(() =>
|
||||||
{
|
{
|
||||||
IsBusy = false;
|
IsBusy = false;
|
||||||
if (_vm.LoadedOnce)
|
if (_vm.LoadedOnce)
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
using Android.Graphics.Drawables;
|
|
||||||
using Bit.App.Droid.Effects;
|
|
||||||
using Bit.App.Droid.Utilities;
|
|
||||||
using Microsoft.Maui.Controls.Platform;
|
|
||||||
|
|
||||||
[assembly: ExportEffect(typeof(FabShadowEffect), "FabShadowEffect")]
|
|
||||||
namespace Bit.App.Droid.Effects
|
|
||||||
{
|
|
||||||
public class FabShadowEffect : PlatformEffect
|
|
||||||
{
|
|
||||||
protected override void OnAttached ()
|
|
||||||
{
|
|
||||||
if (Control is Android.Widget.Button button)
|
|
||||||
{
|
|
||||||
var gd = new GradientDrawable();
|
|
||||||
gd.SetColor(ThemeHelpers.FabColor);
|
|
||||||
gd.SetCornerRadius(100);
|
|
||||||
|
|
||||||
button.SetBackground(gd);
|
|
||||||
button.Elevation = 6;
|
|
||||||
button.TranslationZ = 20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetached ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using Android.Widget;
|
|
||||||
using Bit.App.Droid.Effects;
|
|
||||||
using Microsoft.Maui.Controls.Platform;
|
|
||||||
|
|
||||||
[assembly: ExportEffect(typeof(FixedSizeEffect), "FixedSizeEffect")]
|
|
||||||
namespace Bit.App.Droid.Effects
|
|
||||||
{
|
|
||||||
public class FixedSizeEffect : PlatformEffect
|
|
||||||
{
|
|
||||||
protected override void OnAttached()
|
|
||||||
{
|
|
||||||
if (Element is Label label && Control is TextView textView)
|
|
||||||
{
|
|
||||||
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetached()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using Android.Widget;
|
|
||||||
using Bit.App.Droid.Effects;
|
|
||||||
using Microsoft.Maui.Controls.Platform;
|
|
||||||
|
|
||||||
[assembly: ExportEffect(typeof(NoEmojiKeyboardEffect), nameof(NoEmojiKeyboardEffect))]
|
|
||||||
namespace Bit.App.Droid.Effects
|
|
||||||
{
|
|
||||||
public class NoEmojiKeyboardEffect : PlatformEffect
|
|
||||||
{
|
|
||||||
protected override void OnAttached()
|
|
||||||
{
|
|
||||||
if (Control is EditText editText)
|
|
||||||
{
|
|
||||||
editText.InputType = Android.Text.InputTypes.ClassText | Android.Text.InputTypes.TextVariationVisiblePassword | Android.Text.InputTypes.TextFlagMultiLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetached()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using Android.Widget;
|
|
||||||
using Bit.App.Droid.Effects;
|
|
||||||
using Microsoft.Maui.Controls.Platform;
|
|
||||||
|
|
||||||
[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
|
|
||||||
namespace Bit.App.Droid.Effects
|
|
||||||
{
|
|
||||||
public class RemoveFontPaddingEffect : PlatformEffect
|
|
||||||
{
|
|
||||||
protected override void OnAttached()
|
|
||||||
{
|
|
||||||
if (Control is TextView textView)
|
|
||||||
{
|
|
||||||
textView.SetIncludeFontPadding(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetached()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using Android.Views;
|
|
||||||
using Bit.App.Droid.Effects;
|
|
||||||
using Google.Android.Material.BottomNavigation;
|
|
||||||
using Microsoft.Maui.Controls;
|
|
||||||
using Microsoft.Maui.Controls.Platform;
|
|
||||||
|
|
||||||
[assembly: ResolutionGroupName("Bitwarden")]
|
|
||||||
[assembly: ExportEffect(typeof(TabBarEffect), "TabBarEffect")]
|
|
||||||
namespace Bit.App.Droid.Effects
|
|
||||||
{
|
|
||||||
public class TabBarEffect : PlatformEffect
|
|
||||||
{
|
|
||||||
protected override void OnAttached()
|
|
||||||
{
|
|
||||||
// TODO: [MAUI-Migration] [Critical]
|
|
||||||
// now Container is View instead of ViewGroup, let's review this
|
|
||||||
//if (!(Container.GetChildAt(0) is ViewGroup layout))
|
|
||||||
//{
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
//if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
|
|
||||||
//{
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
//bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetached()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -98,16 +98,7 @@ namespace Bit.App.Droid
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override MauiApp CreateMauiApp()
|
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||||
{
|
|
||||||
return MauiProgram.CreateMauiApp(effects =>
|
|
||||||
{
|
|
||||||
effects.Add<Bit.App.Effects.FabShadowEffect, Droid.Effects.FabShadowEffect>();
|
|
||||||
effects.Add<Bit.App.Effects.FixedSizeEffect, Droid.Effects.FixedSizeEffect>();
|
|
||||||
effects.Add<Bit.App.Effects.NoEmojiKeyboardEffect, Droid.Effects.NoEmojiKeyboardEffect>();
|
|
||||||
effects.Add<Bit.App.Effects.TabBarEffect, Droid.Effects.TabBarEffect>();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnCreate()
|
public override void OnCreate()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Android.Views.InputMethods;
|
||||||
|
using Bit.App.Droid.Utilities;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomEditorRenderer : EditorRenderer
|
||||||
|
{
|
||||||
|
public CustomEditorRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// Workaround for issue described here:
|
||||||
|
// https://github.com/xamarin/Xamarin.Forms/issues/8291#issuecomment-617456651
|
||||||
|
protected override void OnAttachedToWindow()
|
||||||
|
{
|
||||||
|
base.OnAttachedToWindow();
|
||||||
|
EditText.Enabled = false;
|
||||||
|
EditText.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateBorderColor();
|
||||||
|
if (Control != null && e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||||
|
Control.PaddingBottom + 20);
|
||||||
|
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||||
|
(ImeAction)ImeFlags.NoExtractUi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateBorderColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBorderColor()
|
||||||
|
{
|
||||||
|
if (Control != null)
|
||||||
|
{
|
||||||
|
var states = new[]
|
||||||
|
{
|
||||||
|
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||||
|
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||||
|
};
|
||||||
|
var colors = new int[]
|
||||||
|
{
|
||||||
|
ThemeHelpers.PrimaryColor,
|
||||||
|
ThemeHelpers.MutedColor
|
||||||
|
};
|
||||||
|
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Android.Graphics;
|
||||||
|
using Android.Text;
|
||||||
|
using Android.Views.InputMethods;
|
||||||
|
using Android.Widget;
|
||||||
|
using Bit.App.Droid.Utilities;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
using Microsoft.Maui.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomEntryRenderer : EntryRenderer
|
||||||
|
{
|
||||||
|
public CustomEntryRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateBorderColor();
|
||||||
|
if (Control != null && e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||||
|
Control.PaddingBottom + 20);
|
||||||
|
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||||
|
(ImeAction)ImeFlags.NoExtractUi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround for bug preventing long-press -> copy/paste on Android 11
|
||||||
|
// See https://issuetracker.google.com/issues/37095917
|
||||||
|
protected override void OnAttachedToWindow()
|
||||||
|
{
|
||||||
|
base.OnAttachedToWindow();
|
||||||
|
Control.Enabled = false;
|
||||||
|
Control.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround for failure to disable text prediction on non-password fields
|
||||||
|
// see https://github.com/xamarin/Xamarin.Forms/issues/10857
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
// Check if changed property is "IsPassword", otherwise ignore
|
||||||
|
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
|
||||||
|
{
|
||||||
|
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
|
||||||
|
EditText.InputType = Element.Keyboard.ToInputType();
|
||||||
|
bool isText = (EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText,
|
||||||
|
isNumber = (EditText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
|
||||||
|
if (isText || isNumber)
|
||||||
|
{
|
||||||
|
if (Element.IsPassword)
|
||||||
|
{
|
||||||
|
// Element is a password field, set inputType to TextVariationPassword which disables
|
||||||
|
// predictive text by default
|
||||||
|
EditText.InputType = EditText.InputType |
|
||||||
|
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Element is not a password field, set inputType to TextVariationVisiblePassword to
|
||||||
|
// disable predictive text while still displaying the content.
|
||||||
|
EditText.InputType = EditText.InputType |
|
||||||
|
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The workaround above forces a reset of the style properties, so we need to re-apply the font.
|
||||||
|
// see https://xamarin.github.io/bugzilla-archives/33/33666/bug.html
|
||||||
|
var typeface = Typeface.CreateFromAsset(Context.Assets, "RobotoMono_Regular.ttf");
|
||||||
|
if (Control is TextView label)
|
||||||
|
{
|
||||||
|
label.Typeface = typeface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateBorderColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBorderColor()
|
||||||
|
{
|
||||||
|
if (Control != null)
|
||||||
|
{
|
||||||
|
var states = new[]
|
||||||
|
{
|
||||||
|
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||||
|
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||||
|
};
|
||||||
|
var colors = new int[]
|
||||||
|
{
|
||||||
|
ThemeHelpers.PrimaryColor,
|
||||||
|
ThemeHelpers.MutedColor
|
||||||
|
};
|
||||||
|
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.OS;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomLabelRenderer : LabelRenderer
|
||||||
|
{
|
||||||
|
public CustomLabelRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (Control != null && e.NewElement is CustomLabel label)
|
||||||
|
{
|
||||||
|
if (label.FontWeight.HasValue && Build.VERSION.SdkInt >= BuildVersionCodes.P)
|
||||||
|
{
|
||||||
|
Control.Typeface = Android.Graphics.Typeface.Create(null, label.FontWeight.Value, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var label = sender as CustomLabel;
|
||||||
|
switch (e.PropertyName)
|
||||||
|
{
|
||||||
|
case nameof(CustomLabel.AutomationId):
|
||||||
|
Control.ContentDescription = label.AutomationId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using AndroidX.AppCompat.Widget;
|
||||||
|
using Bit.App.Resources;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomPageRenderer : PageRenderer
|
||||||
|
{
|
||||||
|
public CustomPageRenderer(Context context) : base(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
// TODO: [MAUI-Migration] [Critical]
|
||||||
|
//Activity context = (Activity)this.Context;
|
||||||
|
//var toolbar = context.FindViewById<Toolbar>(Android.Resource.Id.toolbar);
|
||||||
|
//if(toolbar != null)
|
||||||
|
//{
|
||||||
|
// toolbar.NavigationContentDescription = AppResources.TapToGoBack;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Bit.App.Droid.Utilities;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android.AppCompat;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomPickerRenderer : PickerRenderer
|
||||||
|
{
|
||||||
|
public CustomPickerRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateBorderColor();
|
||||||
|
if (Control != null && e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||||
|
Control.PaddingBottom + 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == Picker.TextColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateBorderColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBorderColor()
|
||||||
|
{
|
||||||
|
if (Control != null)
|
||||||
|
{
|
||||||
|
var states = new[]
|
||||||
|
{
|
||||||
|
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||||
|
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||||
|
};
|
||||||
|
var colors = new int[]
|
||||||
|
{
|
||||||
|
ThemeHelpers.PrimaryColor,
|
||||||
|
ThemeHelpers.MutedColor
|
||||||
|
};
|
||||||
|
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using Android.Views.InputMethods;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomSearchBarRenderer : SearchBarRenderer
|
||||||
|
{
|
||||||
|
public CustomSearchBarRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
if (Control != null && e.NewElement != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var magId = Resources.GetIdentifier("android:id/search_mag_icon", null, null);
|
||||||
|
var magImage = (Android.Widget.ImageView)Control.FindViewById(magId);
|
||||||
|
magImage.LayoutParameters = new Android.Widget.LinearLayout.LayoutParams(0, 0);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
// TODO: [MAUI-Migration] [Check]
|
||||||
|
Control.ImeOptions = Control.ImeOptions | (int)ImeFlags.NoPersonalizedLearning |
|
||||||
|
(int)ImeFlags.NoExtractUi;
|
||||||
|
//Control.SetImeOptions(Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||||
|
// (ImeAction)ImeFlags.NoExtractUi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
using Android.OS;
|
||||||
|
using AndroidX.Core.Content.Resources;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Bit.App.Droid.Utilities;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android.AppCompat;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomSwitchRenderer : SwitchRenderer
|
||||||
|
{
|
||||||
|
public CustomSwitchRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == Switch.OnColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateColors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateColors()
|
||||||
|
{
|
||||||
|
if (Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
|
||||||
|
{
|
||||||
|
// Android 5.x doesn't support ThumbTintList, and using SwitchCompat on every version after 5.x
|
||||||
|
// doesn't apply tinting the way we want. Let 5.x to do its own thing here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Control != null)
|
||||||
|
{
|
||||||
|
Control.SetHintTextColor(ThemeHelpers.MutedColor);
|
||||||
|
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.switch_thumb, null);
|
||||||
|
if (t is GradientDrawable thumb)
|
||||||
|
{
|
||||||
|
Control.ThumbDrawable = thumb;
|
||||||
|
}
|
||||||
|
var thumbStates = new[]
|
||||||
|
{
|
||||||
|
new[] { Android.Resource.Attribute.StateChecked }, // checked
|
||||||
|
new[] { -Android.Resource.Attribute.StateChecked }, // unchecked
|
||||||
|
};
|
||||||
|
var thumbColors = new int[]
|
||||||
|
{
|
||||||
|
ThemeHelpers.SwitchOnColor,
|
||||||
|
ThemeHelpers.SwitchThumbColor
|
||||||
|
};
|
||||||
|
Control.ThumbTintList = new ColorStateList(thumbStates, thumbColors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using Android.Views;
|
||||||
|
using Bit.App.Pages;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Google.Android.Material.BottomNavigation;
|
||||||
|
using Google.Android.Material.Navigation;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android.AppCompat;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
|
||||||
|
{
|
||||||
|
private TabbedPage _page;
|
||||||
|
|
||||||
|
public CustomTabbedRenderer(Context context) : base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
if (e.NewElement != null)
|
||||||
|
{
|
||||||
|
_page = e.NewElement;
|
||||||
|
GetBottomNavigationView()?.SetOnItemReselectedListener(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_page = e.OldElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BottomNavigationView GetBottomNavigationView()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < ChildCount; i++)
|
||||||
|
{
|
||||||
|
var childView = GetChildAt(i);
|
||||||
|
if (childView is ViewGroup viewGroup)
|
||||||
|
{
|
||||||
|
for (var j = 0; j < viewGroup.ChildCount; j++)
|
||||||
|
{
|
||||||
|
var childRelativeLayoutView = viewGroup.GetChildAt(j);
|
||||||
|
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
|
||||||
|
{
|
||||||
|
return bottomNavigationView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNavigationItemReselected(IMenuItem item)
|
||||||
|
{
|
||||||
|
if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
|
||||||
|
{
|
||||||
|
if (_page is TabsPage tabsPage)
|
||||||
|
{
|
||||||
|
tabsPage.OnPageReselected();
|
||||||
|
}
|
||||||
|
Device.BeginInvokeOnMainThread(async () => await _page.CurrentPage.Navigation.PopToRootAsync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Views;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedDatePickerRenderer : DatePickerRenderer
|
||||||
|
{
|
||||||
|
public ExtendedDatePickerRenderer(Context context)
|
||||||
|
: base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
if (Control != null && Element is ExtendedDatePicker element)
|
||||||
|
{
|
||||||
|
// center text
|
||||||
|
Control.Gravity = GravityFlags.CenterHorizontal;
|
||||||
|
|
||||||
|
// use placeholder until NullableDate set
|
||||||
|
if (!element.NullableDate.HasValue)
|
||||||
|
{
|
||||||
|
Control.Text = element.PlaceHolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == DatePicker.DateProperty.PropertyName ||
|
||||||
|
e.PropertyName == DatePicker.FormatProperty.PropertyName)
|
||||||
|
{
|
||||||
|
if (Control != null && Element is ExtendedDatePicker element)
|
||||||
|
{
|
||||||
|
if (Element.Format == element.PlaceHolder)
|
||||||
|
{
|
||||||
|
Control.Text = element.PlaceHolder;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedGridRenderer : ViewRenderer
|
||||||
|
{
|
||||||
|
public ExtendedGridRenderer(Context context) : base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(elementChangedEvent);
|
||||||
|
if (elementChangedEvent.NewElement != null)
|
||||||
|
{
|
||||||
|
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
using AndroidX.Core.Content.Resources;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedSliderRenderer : SliderRenderer
|
||||||
|
{
|
||||||
|
public ExtendedSliderRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == ExtendedSlider.ThumbBorderColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateColor()
|
||||||
|
{
|
||||||
|
if (Control != null && Element is ExtendedSlider view)
|
||||||
|
{
|
||||||
|
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.slider_thumb, null);
|
||||||
|
if (t is GradientDrawable thumb)
|
||||||
|
{
|
||||||
|
// TODO: [MAUI-Migration]
|
||||||
|
//if (view.ThumbColor == Colors.Default)
|
||||||
|
//{
|
||||||
|
// thumb.SetColor(Colors.White.ToAndroid());
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
thumb.SetColor(view.ThumbColor.ToAndroid());
|
||||||
|
//}
|
||||||
|
thumb.SetStroke(3, view.ThumbBorderColor.ToAndroid());
|
||||||
|
Control.SetThumb(thumb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Bit.App.Droid.Renderers;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedStackLayoutRenderer : ViewRenderer
|
||||||
|
{
|
||||||
|
public ExtendedStackLayoutRenderer(Context context) : base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(elementChangedEvent);
|
||||||
|
if (elementChangedEvent.NewElement != null)
|
||||||
|
{
|
||||||
|
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Graphics;
|
||||||
|
using Android.OS;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedStepperRenderer : StepperRenderer
|
||||||
|
{
|
||||||
|
public ExtendedStepperRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
UpdateBgColor();
|
||||||
|
UpdateFgColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
|
||||||
|
if (e.PropertyName == ExtendedStepper.StepperBackgroundColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateBgColor();
|
||||||
|
}
|
||||||
|
else if (e.PropertyName == ExtendedStepper.StepperForegroundColorProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateFgColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateBgColor()
|
||||||
|
{
|
||||||
|
if (Control != null && Element is ExtendedStepper view)
|
||||||
|
{
|
||||||
|
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
|
||||||
|
{
|
||||||
|
Control.GetChildAt(0)?.Background?.SetColorFilter(
|
||||||
|
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), Android.Graphics.BlendMode.Multiply));
|
||||||
|
Control.GetChildAt(1)?.Background?.SetColorFilter(
|
||||||
|
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), Android.Graphics.BlendMode.Multiply));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Control.GetChildAt(0)?.Background?.SetColorFilter(
|
||||||
|
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
|
||||||
|
Control.GetChildAt(1)?.Background?.SetColorFilter(
|
||||||
|
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFgColor()
|
||||||
|
{
|
||||||
|
if (Control != null && Element is ExtendedStepper view)
|
||||||
|
{
|
||||||
|
var btn0 = Control.GetChildAt(0) as Android.Widget.Button;
|
||||||
|
btn0?.SetTextColor(view.StepperForegroundColor.ToAndroid());
|
||||||
|
var btn1 = Control.GetChildAt(1) as Android.Widget.Button;
|
||||||
|
btn1?.SetTextColor(view.StepperForegroundColor.ToAndroid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Views;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class ExtendedTimePickerRenderer : TimePickerRenderer
|
||||||
|
{
|
||||||
|
public ExtendedTimePickerRenderer(Context context)
|
||||||
|
: base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
if (Control != null && Element is ExtendedTimePicker element)
|
||||||
|
{
|
||||||
|
// center text
|
||||||
|
Control.Gravity = GravityFlags.CenterHorizontal;
|
||||||
|
|
||||||
|
// use placeholder until NullableTime set
|
||||||
|
if (!element.NullableTime.HasValue)
|
||||||
|
{
|
||||||
|
Control.Text = element.PlaceHolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == TimePicker.TimeProperty.PropertyName ||
|
||||||
|
e.PropertyName == TimePicker.FormatProperty.PropertyName)
|
||||||
|
{
|
||||||
|
if (Control != null && Element is ExtendedTimePicker element)
|
||||||
|
{
|
||||||
|
if (Element.Format == element.PlaceHolder)
|
||||||
|
{
|
||||||
|
Control.Text = element.PlaceHolder;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Webkit;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Java.Interop;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
using AWebkit = Android.Webkit;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, AWebkit.WebView>
|
||||||
|
{
|
||||||
|
private const string JSFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
|
||||||
|
|
||||||
|
private readonly Context _context;
|
||||||
|
|
||||||
|
public HybridWebViewRenderer(Context context)
|
||||||
|
: base(context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (Control == null)
|
||||||
|
{
|
||||||
|
var webView = new AWebkit.WebView(_context);
|
||||||
|
webView.Settings.JavaScriptEnabled = true;
|
||||||
|
webView.SetWebViewClient(new JSWebViewClient(string.Format("javascript: {0}", JSFunction)));
|
||||||
|
SetNativeControl(webView);
|
||||||
|
}
|
||||||
|
if (e.OldElement != null)
|
||||||
|
{
|
||||||
|
Control.RemoveJavascriptInterface("jsBridge");
|
||||||
|
var hybridWebView = e.OldElement as HybridWebView;
|
||||||
|
hybridWebView.Cleanup();
|
||||||
|
}
|
||||||
|
if (e.NewElement != null)
|
||||||
|
{
|
||||||
|
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
|
||||||
|
Control.LoadUrl(Element.Uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnElementPropertyChanged(sender, e);
|
||||||
|
if (e.PropertyName == HybridWebView.UriProperty.PropertyName)
|
||||||
|
{
|
||||||
|
Control.LoadUrl(Element.Uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JSBridge : Java.Lang.Object
|
||||||
|
{
|
||||||
|
private readonly WeakReference<HybridWebViewRenderer> _hybridWebViewRenderer;
|
||||||
|
|
||||||
|
public JSBridge(HybridWebViewRenderer hybridRenderer)
|
||||||
|
{
|
||||||
|
_hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JavascriptInterface]
|
||||||
|
[Export("invokeAction")]
|
||||||
|
public void InvokeAction(string data)
|
||||||
|
{
|
||||||
|
if (_hybridWebViewRenderer != null &&
|
||||||
|
_hybridWebViewRenderer.TryGetTarget(out HybridWebViewRenderer hybridRenderer))
|
||||||
|
{
|
||||||
|
hybridRenderer.Element.InvokeAction(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JSWebViewClient : WebViewClient
|
||||||
|
{
|
||||||
|
private readonly string _javascript;
|
||||||
|
|
||||||
|
public JSWebViewClient(string javascript)
|
||||||
|
{
|
||||||
|
_javascript = javascript;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnPageFinished(AWebkit.WebView view, string url)
|
||||||
|
{
|
||||||
|
base.OnPageFinished(view, url);
|
||||||
|
view.EvaluateJavascript(_javascript, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using Android.Content;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
|
||||||
|
using Microsoft.Maui.Controls.Platform;
|
||||||
|
|
||||||
|
namespace Bit.App.Droid.Renderers
|
||||||
|
{
|
||||||
|
public class SelectableLabelRenderer : LabelRenderer
|
||||||
|
{
|
||||||
|
public SelectableLabelRenderer(Context context) : base(context) { }
|
||||||
|
|
||||||
|
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||||
|
{
|
||||||
|
base.OnElementChanged(e);
|
||||||
|
|
||||||
|
if (Control != null)
|
||||||
|
{
|
||||||
|
Control.SetTextIsSelectable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/Maui/Bitwarden/Resources/Fonts/MaterialIcons_Regular.ttf
Normal file
BIN
src/Maui/Bitwarden/Resources/Fonts/MaterialIcons_Regular.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/Maui/Bitwarden/Resources/Fonts/RobotoMono_Regular.ttf
Normal file
BIN
src/Maui/Bitwarden/Resources/Fonts/RobotoMono_Regular.ttf
Normal file
Binary file not shown.
BIN
src/Maui/Bitwarden/Resources/Fonts/bwi-font.ttf
Normal file
BIN
src/Maui/Bitwarden/Resources/Fonts/bwi-font.ttf
Normal file
Binary file not shown.
@@ -59,11 +59,12 @@
|
|||||||
<Setter Property="FontAttributes"
|
<Setter Property="FontAttributes"
|
||||||
Value="Bold" />
|
Value="Bold" />
|
||||||
</Style>
|
</Style>
|
||||||
|
<!--[MAUI-Migration][Color-default]-->
|
||||||
<Style TargetType="Label"
|
<Style TargetType="Label"
|
||||||
Class="text-html"
|
Class="text-html"
|
||||||
ApplyToDerivedTypes="True">
|
ApplyToDerivedTypes="True">
|
||||||
<Setter Property="TextColor"
|
<Setter Property="TextColor"
|
||||||
Value="Default" />
|
Value="#ffffff" />
|
||||||
<Setter Property="TextType"
|
<Setter Property="TextType"
|
||||||
Value="Html" />
|
Value="Html" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="Bit.App.Styles.Light">
|
x:Class="Bit.App.Styles.Light">
|
||||||
@@ -35,7 +35,8 @@
|
|||||||
<Color x:Key="ListHeaderTextColor">#175DDC</Color>
|
<Color x:Key="ListHeaderTextColor">#175DDC</Color>
|
||||||
<Color x:Key="ListHeaderBackgroundColor">#efeff4</Color>
|
<Color x:Key="ListHeaderBackgroundColor">#efeff4</Color>
|
||||||
|
|
||||||
<Color x:Key="SliderThumbColor">Default</Color>
|
<!--[MAUI-Migration][Color-default]-->
|
||||||
|
<Color x:Key="SliderThumbColor">#ffffff</Color>
|
||||||
<Color x:Key="SliderThumbBorderColor">#b5b5b5</Color>
|
<Color x:Key="SliderThumbBorderColor">#b5b5b5</Color>
|
||||||
<Color x:Key="SliderTrackMinColor">#175DDC</Color>
|
<Color x:Key="SliderTrackMinColor">#175DDC</Color>
|
||||||
<Color x:Key="SliderTrackMaxColor">#dddddd</Color>
|
<Color x:Key="SliderTrackMaxColor">#dddddd</Color>
|
||||||
|
|||||||
Reference in New Issue
Block a user