mirror of
https://github.com/bitwarden/mobile
synced 2025-12-24 04:04:34 +00:00
Dynamic theme switching and visual tweaks (#1556)
* Dynamic theme switching and visual tweaks * update action runner to use macos-11 for iOS 15 support * additional tweaks * refinements * refinements * formatting and tweaks
This commit is contained in:
@@ -9,7 +9,7 @@ using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Droid.Accessibility
|
||||
{
|
||||
[Activity(Theme = "@style/LightTheme.Splash", WindowSoftInputMode = SoftInput.StateHidden)]
|
||||
[Activity(Theme = "@style/BaseTheme", WindowSoftInputMode = SoftInput.StateHidden)]
|
||||
public class AccessibilityActivity : Activity
|
||||
{
|
||||
private DateTime? _lastLaunch = null;
|
||||
|
||||
@@ -76,11 +76,11 @@
|
||||
<PackageReference Include="Portable.BouncyCastle">
|
||||
<Version>1.8.10</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.7" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.9" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.8" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.5" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.3" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.9" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.11" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.10" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.5.2" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Migration" Version="1.0.8" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.7.0</Version>
|
||||
@@ -88,7 +88,7 @@
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>122.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.4.0.2" />
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.4.0.4" />
|
||||
<PackageReference Include="Xamarin.Google.Dagger" Version="2.37.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
|
||||
<Version>117.0.1</Version>
|
||||
@@ -122,6 +122,8 @@
|
||||
<Compile Include="Renderers\ExtendedDatePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStackLayoutRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStepperRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSwitchRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedTimePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEditorRenderer.cs" />
|
||||
@@ -144,6 +146,7 @@
|
||||
<Compile Include="Tiles\MyVaultTileService.cs" />
|
||||
<Compile Include="Utilities\AndroidHelpers.cs" />
|
||||
<Compile Include="Utilities\AppCenterHelper.cs" />
|
||||
<Compile Include="Utilities\ThemeHelpers.cs" />
|
||||
<Compile Include="WebAuthCallbackActivity.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -171,8 +174,6 @@
|
||||
<AndroidResource Include="Resources\drawable\id.xml" />
|
||||
<AndroidResource Include="Resources\drawable\info.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg_dark.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg_nord.xml" />
|
||||
<AndroidResource Include="Resources\drawable\lock.xml" />
|
||||
<AndroidResource Include="Resources\drawable\login.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo.xml" />
|
||||
@@ -185,6 +186,7 @@
|
||||
<AndroidResource Include="Resources\drawable\shield.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
|
||||
<AndroidResource Include="Resources\drawable\switch_thumb.xml" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Effects;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Bit.Droid.Effects
|
||||
if (Control is Android.Widget.Button button)
|
||||
{
|
||||
var gd = new GradientDrawable();
|
||||
gd.SetColor(ThemeManager.GetResourceColor("FabColor").ToAndroid());
|
||||
gd.SetColor(ThemeHelpers.FabColor);
|
||||
gd.SetCornerRadius(100);
|
||||
|
||||
button.SetBackground(gd);
|
||||
|
||||
@@ -15,9 +15,9 @@ using Bit.Droid.Receivers;
|
||||
using Bit.App.Models;
|
||||
using Bit.Core.Enums;
|
||||
using Android.Nfc;
|
||||
using Bit.App.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
using AndroidX.Core.Content;
|
||||
using Bit.App.Utilities;
|
||||
using ZXing.Net.Mobile.Android;
|
||||
|
||||
namespace Bit.Droid
|
||||
@@ -30,7 +30,7 @@ namespace Bit.Droid
|
||||
LaunchMode = LaunchMode.SingleTask,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation |
|
||||
ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden |
|
||||
ConfigChanges.Navigation)]
|
||||
ConfigChanges.Navigation | ConfigChanges.UiMode)]
|
||||
[IntentFilter(
|
||||
new[] { Intent.ActionSend },
|
||||
Categories = new[] { Intent.CategoryDefault },
|
||||
@@ -81,7 +81,6 @@ namespace Bit.Droid
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
UpdateTheme(ThemeManager.GetTheme(true));
|
||||
base.OnCreate(savedInstanceState);
|
||||
if (!CoreHelpers.InDebugMode())
|
||||
{
|
||||
@@ -118,7 +117,7 @@ namespace Bit.Droid
|
||||
}
|
||||
else if (message.Command == "updatedTheme")
|
||||
{
|
||||
RestartApp();
|
||||
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => AppearanceAdjustments());
|
||||
}
|
||||
else if (message.Command == "exit")
|
||||
{
|
||||
@@ -141,6 +140,7 @@ namespace Bit.Droid
|
||||
{
|
||||
base.OnResume();
|
||||
Xamarin.Essentials.Platform.OnResume();
|
||||
AppearanceAdjustments();
|
||||
if (_deviceActionService.SupportsNfc())
|
||||
{
|
||||
try
|
||||
@@ -382,45 +382,10 @@ namespace Bit.Droid
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTheme(string theme)
|
||||
private void AppearanceAdjustments()
|
||||
{
|
||||
if (theme == "light")
|
||||
{
|
||||
SetTheme(Resource.Style.LightTheme);
|
||||
}
|
||||
else if (theme == "dark")
|
||||
{
|
||||
SetTheme(Resource.Style.DarkTheme);
|
||||
}
|
||||
else if (theme == "black")
|
||||
{
|
||||
SetTheme(Resource.Style.BlackTheme);
|
||||
}
|
||||
else if (theme == "nord")
|
||||
{
|
||||
SetTheme(Resource.Style.NordTheme);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_deviceActionService.UsingDarkTheme())
|
||||
{
|
||||
SetTheme(Resource.Style.DarkTheme);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTheme(Resource.Style.LightTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RestartApp()
|
||||
{
|
||||
var intent = new Intent(this, typeof(MainActivity));
|
||||
var pendingIntent = PendingIntent.GetActivity(this, 5923650, intent, PendingIntentFlags.CancelCurrent);
|
||||
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
|
||||
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + 500;
|
||||
alarmManager.Set(AlarmType.Rtc, triggerMs, pendingIntent);
|
||||
Java.Lang.JavaSystem.Exit(0);
|
||||
Window?.SetStatusBarColor(ThemeHelpers.NavBarBackgroundColor);
|
||||
ThemeHelpers.SetAppearance(ThemeManager.GetTheme(true), ThemeManager.OsDarkModeEnabled());
|
||||
}
|
||||
|
||||
private void ExitApp()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using Android.Content;
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
@@ -25,6 +28,7 @@ namespace Bit.Droid.Renderers
|
||||
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,
|
||||
@@ -33,5 +37,33 @@ namespace Bit.Droid.Renderers
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
@@ -20,6 +22,7 @@ namespace Bit.Droid.Renderers
|
||||
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,
|
||||
@@ -68,6 +71,28 @@ namespace Bit.Droid.Renderers
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Android.Content;
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
@@ -15,11 +18,40 @@ namespace Bit.Droid.Renderers
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
59
src/Android/Renderers/CustomSwitchRenderer.cs
Normal file
59
src/Android/Renderers/CustomSwitchRenderer.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics.Drawables;
|
||||
using AndroidX.Core.Content.Resources;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]
|
||||
namespace Bit.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 (Control != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
@@ -10,8 +9,6 @@ namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedGridRenderer : ViewRenderer
|
||||
{
|
||||
private static int? _bgResId;
|
||||
|
||||
public ExtendedGridRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
@@ -19,25 +16,8 @@ namespace Bit.Droid.Renderers
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(GetBgResId());
|
||||
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetBgResId()
|
||||
{
|
||||
if (_bgResId == null)
|
||||
{
|
||||
if (ThemeManager.GetTheme(true) == "nord")
|
||||
{
|
||||
_bgResId = Resource.Drawable.list_item_bg_nord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgResId ??= ThemeManager.UsingLightTheme ? Resource.Drawable.list_item_bg :
|
||||
Resource.Drawable.list_item_bg_dark;
|
||||
}
|
||||
}
|
||||
return _bgResId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Android.Content;
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Graphics.Drawables;
|
||||
using AndroidX.Core.Content.Resources;
|
||||
using Bit.App.Controls;
|
||||
@@ -18,6 +19,21 @@ namespace Bit.Droid.Renderers
|
||||
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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
@@ -10,8 +9,6 @@ namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedStackLayoutRenderer : ViewRenderer
|
||||
{
|
||||
private static int? _bgResId;
|
||||
|
||||
public ExtendedStackLayoutRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
|
||||
@@ -19,25 +16,8 @@ namespace Bit.Droid.Renderers
|
||||
base.OnElementChanged(elementChangedEvent);
|
||||
if (elementChangedEvent.NewElement != null)
|
||||
{
|
||||
SetBackgroundResource(GetBgResId());
|
||||
SetBackgroundResource(Resource.Drawable.list_item_bg);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetBgResId()
|
||||
{
|
||||
if (_bgResId == null)
|
||||
{
|
||||
if (ThemeManager.GetTheme(true) == "nord")
|
||||
{
|
||||
_bgResId = Resource.Drawable.list_item_bg_nord;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgResId ??= ThemeManager.UsingLightTheme ? Resource.Drawable.list_item_bg :
|
||||
Resource.Drawable.list_item_bg_dark;
|
||||
}
|
||||
}
|
||||
return _bgResId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
72
src/Android/Renderers/ExtendedStepperRenderer.cs
Normal file
72
src/Android/Renderers/ExtendedStepperRenderer.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Graphics;
|
||||
using Android.OS;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedStepper), typeof(ExtendedStepperRenderer))]
|
||||
namespace Bit.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(), BlendMode.Multiply));
|
||||
Control.GetChildAt(1)?.Background?.SetColorFilter(
|
||||
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ TODO: When API 23 becomes our new minimum, replace 'splash_screen.xml' in 'drawa
|
||||
-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="@color/lightgray"/>
|
||||
<color android:color="@color/white"/>
|
||||
</item>
|
||||
<item
|
||||
android:drawable="@drawable/logo"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/itemPressed">
|
||||
android:color="#8E8E93">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/dark_primary">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
</ripple>
|
||||
@@ -1,7 +0,0 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/nord_primary">
|
||||
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@android:color/white" />
|
||||
</ripple>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="@color/lightgray"/>
|
||||
<color android:color="@color/white"/>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:src="@drawable/logo_legacy" android:tileMode="disabled" android:gravity="center"/>
|
||||
|
||||
5
src/Android/Resources/drawable/switch_thumb.xml
Normal file
5
src/Android/Resources/drawable/switch_thumb.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/white"/>
|
||||
<size android:width="20dp" android:height="20dp"/>
|
||||
</shape>
|
||||
@@ -1,8 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources>
|
||||
<!-- Launch theme (for auto dark/light based on system) -->
|
||||
<style name="LaunchTheme" parent="DarkTheme.Base">
|
||||
<style name="LaunchTheme" parent="BaseTheme">
|
||||
<item name="android:windowBackground">@drawable/splash_screen_dark</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="BaseTheme" parent="Theme.AppCompat">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="colorPrimaryDark">@color/dark_notificationBar</item>
|
||||
<item name="colorAccent">@color/dark_primary</item>
|
||||
<item name="colorControlNormal">@color/dark_border</item>
|
||||
<item name="android:navigationBarColor">@color/dark_navigationBarBackground</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="android:colorActivatedHighlight">@android:color/transparent</item>
|
||||
<item name="android:textCursorDrawable">@null</item>
|
||||
<item name="popupTheme">@style/ThemeOverlay.AppCompat</item>
|
||||
<item name="buttonStyle">@style/ButtonStyle</item>
|
||||
</style>
|
||||
|
||||
<style name="ButtonStyle" parent="Widget.AppCompat.Button">
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -1,38 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Light theme -->
|
||||
<!-- Light System -->
|
||||
<color name="colorPrimary">#175DDC</color>
|
||||
<color name="colorPrimaryDark">#1A3B66</color>
|
||||
<color name="primary">#175DDC</color>
|
||||
<color name="notificationBar">#1452BC</color>
|
||||
<color name="border">#dddddd</color>
|
||||
<color name="itemPressed">#bbbbbb</color>
|
||||
|
||||
<!-- Dark theme -->
|
||||
<!-- Dark System -->
|
||||
<color name="dark_primary">#52bdfb</color>
|
||||
<color name="dark_notificationBar">#191919</color>
|
||||
<color name="dark_border">#191919</color>
|
||||
<color name="dark_border">#666666</color>
|
||||
<color name="dark_navigationBarBackground">#191919</color>
|
||||
|
||||
<!-- Black theme -->
|
||||
<color name="black_border">#282828</color>
|
||||
|
||||
<!-- Nord theme -->
|
||||
<color name="nord_background">#3b4252</color>
|
||||
<color name="nord_text">#e5e9f0</color>
|
||||
<color name="nord_primary">#81a1c1</color>
|
||||
<color name="nord_actionBar">#2e3440</color>
|
||||
<color name="nord_actionBarText">#e5e9f0</color>
|
||||
<color name="nord_notificationBar">#20242D</color>
|
||||
<color name="nord_dialogBackground">#3b4252</color>
|
||||
<color name="nord_border">#2e3440</color>
|
||||
<color name="nord_popupBackground">#4c566a</color>
|
||||
<color name="nord_popupText">#e5e9f0</color>
|
||||
<color name="nord_buttonBackground">#4c566a</color>
|
||||
<color name="nord_navigationBarBackground">#20242D</color>
|
||||
|
||||
<!-- Other -->
|
||||
<color name="launcher_background">#FFFFFF</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000000</color>
|
||||
<color name="darkgray">#333333</color>
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<resources>
|
||||
<!-- Launch theme (for auto dark/light based on system) -->
|
||||
<style name="LaunchTheme" parent="LightTheme.Base">
|
||||
<style name="LaunchTheme" parent="BaseTheme">
|
||||
<item name="android:windowBackground">@drawable/splash_screen</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Light theme -->
|
||||
<style name="LightTheme" parent="LightTheme.Base">
|
||||
</style>
|
||||
|
||||
<style name="LightTheme.Splash" parent="LightTheme.Base">
|
||||
<item name="android:windowBackground">@drawable/splash_screen</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="LightTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<style name="BaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
@@ -27,70 +18,10 @@
|
||||
<item name="android:colorActivatedHighlight">@android:color/transparent</item>
|
||||
<item name="android:textCursorDrawable">@null</item>
|
||||
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
|
||||
<item name="buttonStyle">@style/ButtonStyle</item>
|
||||
</style>
|
||||
|
||||
<!-- Dark theme -->
|
||||
<style name="DarkTheme" parent="DarkTheme.Base">
|
||||
</style>
|
||||
|
||||
<style name="DarkTheme.Splash" parent="DarkTheme.Base">
|
||||
<item name="android:windowBackground">@drawable/splash_screen_dark</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="DarkTheme.Base" parent="Theme.AppCompat">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="colorPrimaryDark">@color/dark_notificationBar</item>
|
||||
<item name="colorAccent">@color/dark_primary</item>
|
||||
<item name="colorControlNormal">@color/dark_border</item>
|
||||
<item name="android:navigationBarColor">@color/dark_navigationBarBackground</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="android:colorActivatedHighlight">@android:color/transparent</item>
|
||||
<item name="android:textCursorDrawable">@null</item>
|
||||
<item name="popupTheme">@style/ThemeOverlay.AppCompat</item>
|
||||
</style>
|
||||
|
||||
<!-- Black theme -->
|
||||
<style name="BlackTheme" parent="BlackTheme.Base">
|
||||
</style>
|
||||
|
||||
<style name="BlackTheme.Splash" parent="DarkTheme.Splash">
|
||||
</style>
|
||||
|
||||
<style name="BlackTheme.Base" parent="DarkTheme.Base">
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
<item name="colorPrimary">@android:color/black</item>
|
||||
<item name="colorPrimaryDark">@android:color/black</item>
|
||||
<item name="colorControlNormal">@color/black_border</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<!-- Nord theme -->
|
||||
<style name="NordTheme" parent="NordTheme.Base">
|
||||
</style>
|
||||
|
||||
<style name="NordTheme.Splash" parent="DarkTheme.Splash">
|
||||
</style>
|
||||
|
||||
<style name="NordTheme.Base" parent="DarkTheme.Base">
|
||||
<item name="android:windowBackground">@color/nord_background</item>
|
||||
<item name="android:actionMenuTextColor">@color/nord_actionBarText</item>
|
||||
<item name="android:textColor">@color/nord_text</item>
|
||||
<item name="colorAccent">@color/nord_primary</item>
|
||||
<item name="colorPrimary">@color/nord_actionBar</item>
|
||||
<item name="colorPrimaryDark">@color/nord_notificationBar</item>
|
||||
<item name="colorControlNormal">@color/nord_border</item>
|
||||
<item name="android:navigationBarColor">@color/nord_navigationBarBackground</item>
|
||||
<item name="colorBackgroundFloating">@color/nord_dialogBackground</item>
|
||||
<item name="android:colorBackgroundFloating" tools:targetApi="23">@color/nord_dialogBackground</item>
|
||||
<item name="popupTheme">@style/NordTheme.Popup</item>
|
||||
<item name="colorButtonNormal">@color/nord_buttonBackground</item>
|
||||
<item name="android:colorButtonNormal">@color/nord_buttonBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="NordTheme.Popup" parent="ThemeOverlay.AppCompat">
|
||||
<item name="android:colorBackground">@color/nord_popupBackground</item>
|
||||
<item name="android:textColor">@color/nord_popupText</item>
|
||||
</style>
|
||||
<style name="ButtonStyle" parent="Widget.AppCompat.Button">
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -8,7 +8,6 @@ using Android.App;
|
||||
using Android.App.Assist;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Content.Res;
|
||||
using Android.Nfc;
|
||||
using Android.OS;
|
||||
using Android.Provider;
|
||||
@@ -641,18 +640,11 @@ namespace Bit.Droid.Services
|
||||
|
||||
public bool AutofillAccessibilityServiceRunning()
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var manager = activity.GetSystemService(Context.ActivityService) as ActivityManager;
|
||||
var services = manager.GetRunningServices(int.MaxValue);
|
||||
return services.Any(s => s.Process.ToLowerInvariant().Contains("bitwarden") &&
|
||||
s.Service.ClassName.ToLowerInvariant().Contains("accessibilityservice"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var enabledServices = Settings.Secure.GetString(activity.ContentResolver,
|
||||
Settings.Secure.EnabledAccessibilityServices);
|
||||
return Application.Context.PackageName != null &&
|
||||
(enabledServices?.Contains(Application.Context.PackageName) ?? false);
|
||||
}
|
||||
|
||||
public bool AutofillAccessibilityOverlayPermitted()
|
||||
@@ -741,21 +733,6 @@ namespace Bit.Droid.Services
|
||||
}
|
||||
}
|
||||
|
||||
public bool UsingDarkTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
|
||||
{
|
||||
var app = CrossCurrentActivity.Current.AppContext;
|
||||
var uiModeFlags = app.Resources.Configuration.UiMode & UiMode.NightMask;
|
||||
return uiModeFlags == UiMode.NightYes;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
public long GetActiveTime()
|
||||
{
|
||||
// Returns milliseconds since the system was booted, and includes deep sleep. This clock is guaranteed to
|
||||
|
||||
67
src/Android/Utilities/ThemeHelpers.cs
Normal file
67
src/Android/Utilities/ThemeHelpers.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Android.Graphics;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
namespace Bit.Droid.Utilities
|
||||
{
|
||||
public class ThemeHelpers
|
||||
{
|
||||
public static bool LightTheme = true;
|
||||
|
||||
public static Color PrimaryColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("PrimaryColor").ToAndroid();
|
||||
}
|
||||
public static Color MutedColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("MutedColor").ToAndroid();
|
||||
}
|
||||
public static Color NavBarBackgroundColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("NavigationBarBackgroundColor").ToAndroid();
|
||||
}
|
||||
public static Color FabColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("FabColor").ToAndroid();
|
||||
}
|
||||
public static Color SwitchOnColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("SwitchOnColor").ToAndroid();
|
||||
}
|
||||
public static Color SwitchThumbColor
|
||||
{
|
||||
get => ThemeManager.GetResourceColor("SwitchThumbColor").ToAndroid();
|
||||
}
|
||||
|
||||
public static void SetAppearance(string theme, bool osDarkModeEnabled)
|
||||
{
|
||||
SetThemeVariables(theme, osDarkModeEnabled);
|
||||
}
|
||||
|
||||
public static int GetDialogTheme()
|
||||
{
|
||||
if (LightTheme)
|
||||
{
|
||||
return Android.Resource.Style.ThemeMaterialLightDialog;
|
||||
}
|
||||
return Android.Resource.Style.ThemeMaterialDialog;
|
||||
}
|
||||
|
||||
private static void SetThemeVariables(string theme, bool osDarkModeEnabled)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(theme) && osDarkModeEnabled)
|
||||
{
|
||||
theme = "dark";
|
||||
}
|
||||
|
||||
if (theme == "dark" || theme == "black" || theme == "nord")
|
||||
{
|
||||
LightTheme = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightTheme = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user