mirror of
https://github.com/bitwarden/mobile
synced 2026-01-16 07:23:29 +00:00
Merge branch 'feature/maui-migration' of https://github.com/bitwarden/mobile into feature/maui-migration
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
Bit.App.Handlers.ToolbarHandlerMappings.Setup();
|
||||
|
||||
handlers.AddHandler(typeof(Bit.App.Pages.TabsPage), typeof(Bit.App.Handlers.CustomTabbedPageHandler));
|
||||
handlers.AddHandler(typeof(Bit.App.Controls.ExtendedDatePicker), typeof(Bit.App.Handlers.ExtendedDatePickerHandler));
|
||||
#else
|
||||
iOS.Core.Utilities.iOSCoreHelpers.ConfigureMAUIHandlers(handlers);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.9.2" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.10.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
|
||||
@@ -3,5 +3,11 @@
|
||||
public static class Constants
|
||||
{
|
||||
public const string PACKAGE_NAME = "com.x8bit.bitwarden";
|
||||
public const string TEMP_CAMERA_IMAGE_NAME = "temp_camera_image.jpg";
|
||||
|
||||
/// <summary>
|
||||
/// This directory must also be declared in filepaths.xml
|
||||
/// </summary>
|
||||
public const string TEMP_CAMERA_IMAGE_DIR = "camera_temp";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace Bit.App.Handlers
|
||||
}
|
||||
});
|
||||
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Date), UpdateTextPlaceholderOnFormatLikePlacholder);
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Date), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Format), UpdateTextPlaceholderOnFormatLikePlacholder);
|
||||
DatePickerHandler.Mapper.AppendToMapping(nameof(IDatePicker.Format), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
}
|
||||
|
||||
private static void UpdateTextPlaceholderOnFormatLikePlacholder(IDatePickerHandler handler, IDatePicker datePicker)
|
||||
private static void UpdateTextPlaceholderOnFormatLikePlaceholder(IDatePickerHandler handler, IDatePicker datePicker)
|
||||
{
|
||||
if (datePicker is ExtendedDatePicker extDatePicker && extDatePicker.Format == extDatePicker.PlaceHolder)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
using Android.App;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
namespace Bit.App.Handlers
|
||||
{
|
||||
// Note: This Handler exists only to allow the ExtendedDatePicker to receive IsFocused events on Android. iOS Already does this with this fix: https://github.com/dotnet/maui/pull/13321
|
||||
// If MAUI eventually implements this behavior we can remove this handler completely. There is another Handler (DatePickerHandlerMappings) for the other DatePicker customizations.
|
||||
public partial class ExtendedDatePickerHandler : DatePickerHandler
|
||||
{
|
||||
|
||||
public static PropertyMapper<IDatePicker, ExtendedDatePickerHandler> PropertyMapper = new (DatePickerHandler.Mapper)
|
||||
{
|
||||
[nameof(IDatePicker.IsFocused)] = MapIsFocused
|
||||
};
|
||||
|
||||
public ExtendedDatePickerHandler() : base(PropertyMapper)
|
||||
{
|
||||
}
|
||||
|
||||
public static void MapIsFocused(ExtendedDatePickerHandler handler, IDatePicker datePicker)
|
||||
{
|
||||
if (handler.PlatformView.IsFocused == datePicker.IsFocused) return;
|
||||
|
||||
if (datePicker.IsFocused)
|
||||
{
|
||||
handler.PlatformView.RequestFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.PlatformView.ClearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private DatePickerDialog? _dialog;
|
||||
|
||||
protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
|
||||
{
|
||||
_dialog = base.CreateDatePickerDialog(year, month, day);
|
||||
return _dialog;
|
||||
}
|
||||
|
||||
protected override void ConnectHandler(MauiDatePicker platformView)
|
||||
{
|
||||
base.ConnectHandler(platformView);
|
||||
if (_dialog != null)
|
||||
{
|
||||
_dialog.ShowEvent += OnDialogShown;
|
||||
_dialog.DismissEvent += OnDialogDismissed;
|
||||
}
|
||||
}
|
||||
|
||||
//Currently the Disconnect Handler needs to be manually called from the App: https://github.com/dotnet/maui/issues/3604
|
||||
protected override void DisconnectHandler(MauiDatePicker platformView)
|
||||
{
|
||||
if (_dialog != null)
|
||||
{
|
||||
_dialog.ShowEvent -= OnDialogShown;
|
||||
_dialog.DismissEvent -= OnDialogDismissed;
|
||||
}
|
||||
base.DisconnectHandler(platformView);
|
||||
|
||||
_dialog = null;
|
||||
}
|
||||
|
||||
private void OnDialogShown(object sender, EventArgs e)
|
||||
{
|
||||
this.VirtualView.IsFocused = true;
|
||||
}
|
||||
|
||||
private void OnDialogDismissed(object sender, EventArgs e)
|
||||
{
|
||||
this.VirtualView.IsFocused = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,19 @@ namespace Bit.App.Handlers
|
||||
handler.PlatformView.Gravity = GravityFlags.CenterHorizontal;
|
||||
|
||||
// use placeholder until NullableTime set
|
||||
if (!extTimePicker.NullableTime.HasValue)
|
||||
if (!extTimePicker.NullableTime.HasValue && !string.IsNullOrWhiteSpace(extTimePicker.PlaceHolder))
|
||||
{
|
||||
handler.PlatformView.Text = extTimePicker.PlaceHolder;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
TimePickerHandler.Mapper.AppendToMapping(nameof(ITimePicker.Time), UpdateTextPlaceholderOnFormatLikePlacholder);
|
||||
TimePickerHandler.Mapper.AppendToMapping(nameof(ITimePicker.Time), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
|
||||
TimePickerHandler.Mapper.AppendToMapping(nameof(ITimePicker.Format), UpdateTextPlaceholderOnFormatLikePlacholder);
|
||||
TimePickerHandler.Mapper.AppendToMapping(nameof(ITimePicker.Format), UpdateTextPlaceholderOnFormatLikePlaceholder);
|
||||
}
|
||||
|
||||
private static void UpdateTextPlaceholderOnFormatLikePlacholder(ITimePickerHandler handler, ITimePicker timePicker)
|
||||
private static void UpdateTextPlaceholderOnFormatLikePlaceholder(ITimePickerHandler handler, ITimePicker timePicker)
|
||||
{
|
||||
if (timePicker is ExtendedTimePicker extDatePicker && extDatePicker.Format == extDatePicker.PlaceHolder)
|
||||
{
|
||||
|
||||
@@ -235,18 +235,22 @@ namespace Bit.Droid
|
||||
string fileName = null;
|
||||
if (data != null && data.Data != null)
|
||||
{
|
||||
uri = data.Data;
|
||||
fileName = AndroidHelpers.GetFileName(ApplicationContext, uri);
|
||||
if (data.Data.ToString()?.Contains(Constants.PACKAGE_NAME) != true)
|
||||
{
|
||||
uri = data.Data;
|
||||
fileName = AndroidHelpers.GetFileName(ApplicationContext, uri);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// camera
|
||||
var file = new Java.IO.File(FilesDir, "temp_camera_photo.jpg");
|
||||
var tmpDir = new Java.IO.File(FilesDir, Constants.TEMP_CAMERA_IMAGE_DIR);
|
||||
var file = new Java.IO.File(tmpDir, Constants.TEMP_CAMERA_IMAGE_NAME);
|
||||
uri = FileProvider.GetUriForFile(this, "com.x8bit.bitwarden.fileprovider", file);
|
||||
fileName = $"photo_{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.jpg";
|
||||
}
|
||||
|
||||
if (uri == null)
|
||||
if (uri == null || fileName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<style name="LaunchTheme" parent="BaseTheme">
|
||||
<item name="android:windowBackground">@drawable/splash_screen</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowSplashScreenBackground">@color/ic_launcher_background</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_screen_round</item>
|
||||
<item name="android:windowSplashScreenBackground">@color/ic_launcher_background</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_screen_round</item>
|
||||
</style>
|
||||
|
||||
<style name="BaseTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
||||
@@ -21,6 +21,7 @@
|
||||
<item name="android:textCursorDrawable">@null</item>
|
||||
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
|
||||
<item name="buttonStyle">@style/ButtonStyle</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<style name="ButtonStyle" parent="Widget.AppCompat.Button">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<cache-path name="cache" path="." />
|
||||
<files-path name="internal" path="." />
|
||||
<files-path name="temp_camera_images" path="camera_temp/" />
|
||||
</paths>
|
||||
|
||||
@@ -191,7 +191,8 @@ namespace Bit.Droid.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = new Java.IO.File(activity.FilesDir, "temp_camera_photo.jpg");
|
||||
var tmpDir = new Java.IO.File(activity.FilesDir, Constants.TEMP_CAMERA_IMAGE_DIR);
|
||||
var file = new Java.IO.File(tmpDir, Constants.TEMP_CAMERA_IMAGE_NAME);
|
||||
if (!file.Exists())
|
||||
{
|
||||
file.ParentFile.Mkdirs();
|
||||
|
||||
Reference in New Issue
Block a user