mirror of
https://github.com/bitwarden/mobile
synced 2026-01-06 10:34:07 +00:00
Merge branch 'feature/maui-migration' of https://github.com/bitwarden/mobile into feature/maui-migration
This commit is contained in:
@@ -18,15 +18,16 @@
|
||||
<StackLayout HorizontalOptions="FillAndExpand">
|
||||
<Label
|
||||
StyleClass="text-md"
|
||||
Text="{u:I18n RememberThisDevice}"/>
|
||||
Text="{u:I18n RememberThisDevice}" />
|
||||
<Label
|
||||
StyleClass="box-sub-label"
|
||||
Text="{u:I18n TurnOffUsingPublicDevice}"/>
|
||||
Text="{u:I18n TurnOffUsingPublicDevice}" />
|
||||
</StackLayout>
|
||||
<Switch
|
||||
Scale="0.8"
|
||||
IsToggled="{Binding RememberThisDevice}"
|
||||
VerticalOptions="Center"/>
|
||||
AutomationId="RememberThisDeviceSwitch"
|
||||
VerticalOptions="Center" />
|
||||
</StackLayout>
|
||||
<StackLayout Margin="0, 20, 0, 0">
|
||||
<Button
|
||||
@@ -34,31 +35,34 @@
|
||||
Text="{u:I18n Continue}"
|
||||
StyleClass="btn-primary"
|
||||
Command="{Binding ContinueCommand}"
|
||||
IsVisible="{Binding IsNewUser}"/>
|
||||
IsVisible="{Binding IsNewUser}"
|
||||
AutomationId="ContinueButton" />
|
||||
<Button
|
||||
x:Name="_approveWithMyOtherDevice"
|
||||
Text="{u:I18n ApproveWithMyOtherDevice}"
|
||||
StyleClass="btn-primary"
|
||||
Command="{Binding ApproveWithMyOtherDeviceCommand}"
|
||||
IsVisible="{Binding ApproveWithMyOtherDeviceEnabled}"/>
|
||||
IsVisible="{Binding ApproveWithMyOtherDeviceEnabled}"
|
||||
AutomationId="ApproveWithMyOtherDeviceButton" />
|
||||
<Button
|
||||
x:Name="_requestAdminApproval"
|
||||
Text="{u:I18n RequestAdminApproval}"
|
||||
StyleClass="box-button-row"
|
||||
Command="{Binding RequestAdminApprovalCommand}"
|
||||
IsVisible="{Binding RequestAdminApprovalEnabled}"/>
|
||||
IsVisible="{Binding RequestAdminApprovalEnabled}"
|
||||
AutomationId="RequestAdminApprovalButton" />
|
||||
<Button
|
||||
x:Name="_approveWithMasterPassword"
|
||||
Text="{u:I18n ApproveWithMasterPassword}"
|
||||
StyleClass="box-button-row"
|
||||
Command="{Binding ApproveWithMasterPasswordCommand}"
|
||||
IsVisible="{Binding ApproveWithMasterPasswordEnabled}"/>
|
||||
IsVisible="{Binding ApproveWithMasterPasswordEnabled}"
|
||||
AutomationId="ApproveWithMasterPasswordButton" />
|
||||
<Label
|
||||
Text="{Binding LoggingInAsText}"
|
||||
StyleClass="text-sm"
|
||||
Margin="0,40,0,0"
|
||||
AutomationId="LoggingInAsLabel"
|
||||
/>
|
||||
AutomationId="LoggingInAsLabel" />
|
||||
<Label
|
||||
Text="{u:I18n NotYou}"
|
||||
StyleClass="text-md"
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
</Label>
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
<StackLayout Padding="10, 10">
|
||||
<StackLayout Padding="10, 10" Spacing="6">
|
||||
<Button x:Name="_loginWithMasterPassword"
|
||||
Text="{u:I18n LogInWithMasterPassword}"
|
||||
StyleClass="btn-primary"
|
||||
@@ -128,11 +128,9 @@
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Icon="{Binding Source={x:Static core:BitwardenIcons.Suitcase}}"
|
||||
Label="{u:I18n LogInSso}"
|
||||
AutomationId="LogInWithSsoButton">
|
||||
<controls:IconLabelButton.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="LogInSSO_Clicked" />
|
||||
</controls:IconLabelButton.GestureRecognizers>
|
||||
</controls:IconLabelButton>
|
||||
AutomationId="LogInWithSsoButton"
|
||||
Tapped="LogInSSO_Clicked"
|
||||
/>
|
||||
<Label
|
||||
Text="{Binding LoggingInAsText}"
|
||||
StyleClass="text-sm"
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class LoginPage : BaseContentPage
|
||||
@@ -30,11 +24,11 @@ namespace Bit.App.Pages
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
|
||||
_vm = BindingContext as LoginPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
||||
_vm.StartTwoFactorAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.LogInSuccessAction = () => MainThread.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
||||
_vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget();
|
||||
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
||||
_vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.StartSsoLoginAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
||||
_vm.UpdateTempPasswordAction = () => MainThread.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.CloseAction = async () =>
|
||||
{
|
||||
await _accountListOverlay.HideAsync();
|
||||
@@ -50,8 +44,7 @@ namespace Bit.App.Pages
|
||||
_vm.Email = email;
|
||||
MasterPasswordEntry = _masterPassword;
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||
{
|
||||
ToolbarItems.Add(_moreItem);
|
||||
}
|
||||
@@ -73,14 +66,19 @@ namespace Bit.App.Pages
|
||||
|
||||
public Entry MasterPasswordEntry { get; set; }
|
||||
|
||||
protected override async void OnAppearing()
|
||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
base.OnAppearing();
|
||||
base.OnNavigatedTo(args);
|
||||
|
||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues because of OnNavigatedTo being called twice.
|
||||
if (HasInitialized) { return; }
|
||||
HasInitialized = true;
|
||||
|
||||
_broadcasterService.Subscribe(nameof(LoginPage), message =>
|
||||
{
|
||||
if (message.Command == Constants.ClearSensitiveFields)
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(_vm.ResetPasswordField);
|
||||
MainThread.BeginInvokeOnMainThread(_vm.ResetPasswordField);
|
||||
}
|
||||
});
|
||||
_mainContent.Content = _mainLayout;
|
||||
@@ -96,13 +94,20 @@ namespace Bit.App.Pages
|
||||
RequestFocus(_masterPassword);
|
||||
_inputFocused = true;
|
||||
}
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.Android && !_vm.CanRemoveAccount)
|
||||
if (DeviceInfo.Platform == DevicePlatform.Android && !_vm.CanRemoveAccount)
|
||||
{
|
||||
ToolbarItems.Add(_removeAccount);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
|
||||
{
|
||||
base.OnNavigatedFrom(args);
|
||||
|
||||
_accountAvatar?.OnDisappearing();
|
||||
_broadcasterService.Unsubscribe(nameof(LoginPage));
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
if (_accountListOverlay.IsVisible)
|
||||
@@ -113,14 +118,6 @@ namespace Bit.App.Pages
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
_accountAvatar?.OnDisappearing();
|
||||
_broadcasterService.Unsubscribe(nameof(LoginPage));
|
||||
}
|
||||
|
||||
private async void LogIn_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
|
||||
@@ -155,8 +155,6 @@ namespace Bit.App.Pages
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: [MAUI-Migration] added delay or the modal navigation doesn't happen because of modal-loading is shown
|
||||
await Task.Delay(1000);
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
|
||||
await _stateService.SetPreLoginEmailAsync(Email);
|
||||
await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem"/>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
@@ -29,15 +29,17 @@
|
||||
<Label
|
||||
Text="{Binding SubTitle}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,10"/>
|
||||
Margin="0,0,0,10"
|
||||
AutomationId="SubTitleLabel" />
|
||||
<Label
|
||||
Text="{Binding Description}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,24"/>
|
||||
Margin="0,0,0,24"
|
||||
AutomationId="DescriptionLabel" />
|
||||
<Label
|
||||
Text="{u:I18n FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
FontAttributes="Bold" />
|
||||
<controls:MonoLabel
|
||||
FormattedText="{Binding FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
@@ -62,7 +64,7 @@
|
||||
Color="{DynamicResource DisabledIconColor}" />
|
||||
<Label
|
||||
Text="{Binding OtherOptions}"
|
||||
FontSize="Small"/>
|
||||
FontSize="Small" />
|
||||
<Label
|
||||
Text="{u:I18n ViewAllLoginOptions}"
|
||||
StyleClass="text-sm"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<StackLayout StyleClass="box">
|
||||
<Label Text="{u:I18n LogInSsoSummary}"
|
||||
StyleClass="text-md"
|
||||
HorizontalTextAlignment="Start"></Label>
|
||||
HorizontalTextAlignment="Start" />
|
||||
<StackLayout StyleClass="box-row">
|
||||
<Label
|
||||
Text="{u:I18n OrgIdentifier}"
|
||||
@@ -33,13 +33,15 @@
|
||||
Keyboard="Default"
|
||||
StyleClass="box-value"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding LogInCommand}" />
|
||||
ReturnCommand="{Binding LogInCommand}"
|
||||
AutomationId="OrgIdentifierEntry" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout Padding="10, 0">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked"></Button>
|
||||
Clicked="LogIn_Clicked"
|
||||
AutomationId="LogInButton" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -24,28 +20,44 @@ namespace Bit.App.Pages
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as LoginSsoPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.StartTwoFactorAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.StartSetPasswordAction = () =>
|
||||
Device.BeginInvokeOnMainThread(async () => await StartSetPasswordAsync());
|
||||
_vm.SsoAuthSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await SsoAuthSuccessAsync());
|
||||
MainThread.BeginInvokeOnMainThread(async () => await StartSetPasswordAsync());
|
||||
_vm.SsoAuthSuccessAction = () => MainThread.BeginInvokeOnMainThread(async () => await SsoAuthSuccessAsync());
|
||||
_vm.UpdateTempPasswordAction =
|
||||
() => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
() => MainThread.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.StartDeviceApprovalOptionsAction =
|
||||
() => Device.BeginInvokeOnMainThread(async () => await StartDeviceApprovalOptionsAsync());
|
||||
() => MainThread.BeginInvokeOnMainThread(async () => await StartDeviceApprovalOptionsAsync());
|
||||
_vm.CloseAction = async () =>
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
};
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
|
||||
if (DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async void OnAppearing()
|
||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
base.OnAppearing();
|
||||
base.OnNavigatedTo(args);
|
||||
|
||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues because of OnNavigatedTo being called twice.
|
||||
if (HasInitialized) { return; }
|
||||
HasInitialized = true;
|
||||
|
||||
await _vm.InitAsync();
|
||||
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
|
||||
{
|
||||
RequestFocus(_orgIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async void OnNavigatedFrom(NavigatedFromEventArgs args)
|
||||
{
|
||||
base.OnNavigatedFrom(args);
|
||||
|
||||
await _vm.InitAsync();
|
||||
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
|
||||
{
|
||||
|
||||
@@ -25,13 +25,16 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
//IsInitialized is used as a workaround to avoid duplicate initialization issues for some pages where OnNavigatedTo is called twice.
|
||||
protected bool HasInitialized { get; set; }
|
||||
|
||||
public DateTime? LastPageAction { get; set; }
|
||||
|
||||
public bool IsThemeDirty { get; set; }
|
||||
|
||||
protected override async void OnAppearing()
|
||||
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
|
||||
{
|
||||
base.OnAppearing();
|
||||
base.OnNavigatedTo(args);
|
||||
|
||||
if (IsThemeDirty)
|
||||
{
|
||||
|
||||
@@ -279,6 +279,15 @@
|
||||
Text="{Binding AddyIoDomainName}"
|
||||
StyleClass="box-value"
|
||||
AutomationId="AnonAddyDomainNameEntry" />
|
||||
<Label IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.ForwardEmail}}"
|
||||
Text="{u:I18n DomainNameRequiredParenthesis}"
|
||||
StyleClass="box-label"
|
||||
Margin="0,10,0,0"/>
|
||||
<Entry IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.ForwardEmail}}"
|
||||
x:Name="_forwardEmailDomainNameEntry"
|
||||
Text="{Binding ForwardEmailDomainName}"
|
||||
StyleClass="box-value"
|
||||
AutomationId="ForwardEmailDomainNameEntry" />
|
||||
</StackLayout>
|
||||
<!--RANDOM WORD OPTIONS-->
|
||||
<Grid IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}">
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Bit.App.Pages
|
||||
ForwardedEmailServiceType.DuckDuckGo,
|
||||
ForwardedEmailServiceType.Fastmail,
|
||||
ForwardedEmailServiceType.FirefoxRelay,
|
||||
ForwardedEmailServiceType.ForwardEmail,
|
||||
ForwardedEmailServiceType.SimpleLogin
|
||||
};
|
||||
|
||||
@@ -464,6 +465,8 @@ namespace Bit.App.Pages
|
||||
return _usernameOptions.FirefoxRelayApiAccessToken;
|
||||
case ForwardedEmailServiceType.SimpleLogin:
|
||||
return _usernameOptions.SimpleLoginApiKey;
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
return _usernameOptions.ForwardEmailApiAccessToken;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -513,6 +516,14 @@ namespace Bit.App.Pages
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
if (_usernameOptions.ForwardEmailApiAccessToken != value)
|
||||
{
|
||||
_usernameOptions.ForwardEmailApiAccessToken = value;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -537,6 +548,7 @@ namespace Bit.App.Pages
|
||||
case ForwardedEmailServiceType.DuckDuckGo:
|
||||
case ForwardedEmailServiceType.Fastmail:
|
||||
case ForwardedEmailServiceType.SimpleLogin:
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
return AppResources.APIKeyRequiredParenthesis;
|
||||
default:
|
||||
return null;
|
||||
@@ -567,6 +579,20 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public string ForwardEmailDomainName
|
||||
{
|
||||
get => _usernameOptions?.ForwardEmailDomainName;
|
||||
set
|
||||
{
|
||||
if (_usernameOptions != null && _usernameOptions.ForwardEmailDomainName != value)
|
||||
{
|
||||
_usernameOptions.ForwardEmailDomainName = value;
|
||||
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CapitalizeRandomWordUsername
|
||||
{
|
||||
get => _usernameOptions?.CapitalizeRandomWordUsername == true;
|
||||
@@ -811,6 +837,7 @@ namespace Bit.App.Pages
|
||||
TriggerPropertyChanged(nameof(GeneratorTypeSelected));
|
||||
TriggerPropertyChanged(nameof(UsernameTypeDescriptionLabel));
|
||||
TriggerPropertyChanged(nameof(EmailWebsite));
|
||||
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
|
||||
}
|
||||
|
||||
private void SetOptions()
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
x:DataType="pages:SendAddEditPageViewModel"
|
||||
HideSoftInputOnTapped="True"
|
||||
Unloaded="OnUnloaded"
|
||||
x:Name="_page"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
@@ -310,6 +311,7 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:ExtendedDatePicker
|
||||
x:Name="_deletionExtendedDatePicker"
|
||||
NullableDate="{Binding DeletionDateTimeViewModel.Date, Mode=TwoWay}"
|
||||
Format="d"
|
||||
IsEnabled="{Binding SendEnabled}"
|
||||
@@ -353,6 +355,7 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<controls:ExtendedDatePicker
|
||||
x:Name="_expirationExtendedDatePicker"
|
||||
NullableDate="{Binding ExpirationDateTimeViewModel.Date, Mode=TwoWay}"
|
||||
PlaceHolder="mm/dd/yyyy"
|
||||
Format="d"
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
@@ -9,8 +6,6 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -39,8 +34,7 @@ namespace Bit.App.Pages
|
||||
_vm.SendId = sendId;
|
||||
_vm.Type = appOptions?.CreateSend?.Item1 ?? type;
|
||||
SetActivityIndicator();
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
if (DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
if (_vm.EditMode)
|
||||
{
|
||||
@@ -57,7 +51,7 @@ namespace Bit.App.Pages
|
||||
_btnOptionsDown.WidthRequest = 30;
|
||||
_btnOptionsUp.WidthRequest = 30;
|
||||
}
|
||||
else if (Device.RuntimePlatform == Device.iOS)
|
||||
else if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||
{
|
||||
ToolbarItems.Add(_closeItem);
|
||||
if (_vm.EditMode)
|
||||
@@ -102,7 +96,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (message.Command == "selectFileResult")
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
var data = message.Data as Tuple<byte[], string>;
|
||||
_vm.FileData = data.Item1;
|
||||
@@ -141,8 +135,7 @@ namespace Bit.App.Pages
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
// 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 (_vm.IsAddFromShare && Device.RuntimePlatform == Device.Android)
|
||||
if (_vm.IsAddFromShare && DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
_appOptions.CreateSend = null;
|
||||
}
|
||||
@@ -152,13 +145,18 @@ namespace Bit.App.Pages
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||
{
|
||||
_broadcasterService.Unsubscribe(nameof(SendAddEditPage));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnloaded(object sender, EventArgs e)
|
||||
{
|
||||
_deletionExtendedDatePicker?.DisconnectHandler();
|
||||
_expirationExtendedDatePicker?.DisconnectHandler();
|
||||
}
|
||||
|
||||
private async void TextType_Clicked(object sender, EventArgs eventArgs)
|
||||
{
|
||||
await _vm.TypeChangedAsync(SendType.Text);
|
||||
@@ -310,8 +308,7 @@ namespace Bit.App.Pages
|
||||
private void AdjustToolbar()
|
||||
{
|
||||
_saveItem.IsEnabled = _vm.SendEnabled;
|
||||
// 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 (!_vm.SendEnabled && _vm.EditMode && Device.RuntimePlatform == Device.Android)
|
||||
if (!_vm.SendEnabled && _vm.EditMode && DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
ToolbarItems.Remove(_removePassword);
|
||||
ToolbarItems.Remove(_copyLink);
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
@@ -11,9 +8,6 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.Networking;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -395,8 +389,7 @@ namespace Bit.App.Pages
|
||||
var sendId = await _sendService.SaveWithServerAsync(send, encryptedFileData);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.Android && IsFile)
|
||||
if (DeviceInfo.Platform == DevicePlatform.Android && IsFile)
|
||||
{
|
||||
// Workaround for https://github.com/xamarin/Xamarin.Forms/issues/5418
|
||||
// Exiting and returning (file picker) calls OnAppearing on list page instead of this modal, and
|
||||
@@ -455,8 +448,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (IsAddFromShare)
|
||||
{
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
if (DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
_deviceActionService.CloseMainApp();
|
||||
return;
|
||||
@@ -513,8 +505,7 @@ namespace Bit.App.Pages
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.SendFileEmailVerificationRequired);
|
||||
}
|
||||
|
||||
// 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 (IsAddFromShare && Device.RuntimePlatform == Device.Android)
|
||||
if (IsAddFromShare && DeviceInfo.Platform == DevicePlatform.Android)
|
||||
{
|
||||
_deviceActionService.CloseMainApp();
|
||||
return;
|
||||
@@ -630,7 +621,7 @@ namespace Bit.App.Pages
|
||||
|
||||
internal void TriggerSendTextPropertyChanged()
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(Send)));
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(Send)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,19 +23,21 @@
|
||||
Title="{u:I18n EnableSyncOnRefresh}"
|
||||
IsToggled="{Binding EnableSyncOnRefresh}"
|
||||
Subtitle="{u:I18n EnableSyncOnRefreshDescription}"
|
||||
AutomationId="SubmitCrashLogsSwitch"
|
||||
AutomationId="SyncOnRefreshSwitch"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
|
||||
<StackLayout StyleClass="box" Margin="0,12,0,0">
|
||||
<Button
|
||||
Text="{u:I18n SyncNow}"
|
||||
Command="{Binding SyncCommand}"></Button>
|
||||
Command="{Binding SyncCommand}"
|
||||
AutomationId="SyncNowButton"></Button>
|
||||
<Label
|
||||
Text="{Binding LastSyncDisplay}"
|
||||
StyleClass="text-muted, text-sm"
|
||||
HorizontalTextAlignment="Start"
|
||||
Margin="0,10" />
|
||||
Margin="0,10"
|
||||
AutomationId="LastSyncLabel" />
|
||||
</StackLayout>
|
||||
|
||||
<controls:SettingChooserItemView
|
||||
@@ -51,7 +53,7 @@
|
||||
Title="{u:I18n AllowScreenCapture}"
|
||||
IsToggled="{Binding IsScreenCaptureAllowed}"
|
||||
IsEnabled="{Binding CanToggleeScreenCaptureAllowed}"
|
||||
AutomationId="SubmitCrashLogsSwitch"
|
||||
AutomationId="AllowScreenCaptureSwitch"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
|
||||
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
|
||||
HideSoftInputOnTapped="True"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:appResources="clr-namespace:Bit.Core.Resources.Localization"
|
||||
x:DataType="pages:CipherAddEditPageViewModel"
|
||||
x:Name="_page"
|
||||
Title="{Binding PageTitle}">
|
||||
@@ -29,6 +30,8 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:StringHasValueConverter x:Key="stringHasValue" />
|
||||
<u:IsNotNullConverter x:Key="notNull" />
|
||||
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static appResources:AppResources.CreatedXY}" />
|
||||
|
||||
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
x:Key="closeItem" x:Name="_closeItem" />
|
||||
<ToolbarItem Text="{u:I18n Collections}"
|
||||
@@ -230,7 +233,7 @@
|
||||
Margin="0,10,0,0"
|
||||
IsVisible="{Binding ShowPasskeyInfo}"/>
|
||||
<Entry
|
||||
Text="{Binding CreationDate}"
|
||||
Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
|
||||
IsEnabled="False"
|
||||
StyleClass="box-value,text-muted"
|
||||
IsVisible="{Binding ShowPasskeyInfo}" />
|
||||
|
||||
@@ -312,7 +312,7 @@ namespace Bit.App.Pages
|
||||
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
|
||||
public bool HasTotpValue => IsLogin && !string.IsNullOrEmpty(Cipher?.Login?.Totp);
|
||||
public string SetupTotpText => $"{BitwardenIcons.Camera} {AppResources.SetupTotp}";
|
||||
public bool ShowPasskeyInfo => Cipher?.HasFido2Key == true && !CloneMode;
|
||||
public bool ShowPasskeyInfo => Cipher?.HasFido2Credential == true && !CloneMode;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
@@ -374,7 +374,7 @@ namespace Bit.App.Pages
|
||||
if (Cipher.Type == CipherType.Login)
|
||||
{
|
||||
// passkeys can't be cloned
|
||||
Cipher.Login.Fido2Keys = null;
|
||||
Cipher.Login.Fido2Credentials = null;
|
||||
}
|
||||
}
|
||||
if (appOptions?.OtpData != null && Cipher.Type == CipherType.Login)
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:effects="clr-namespace:Bit.App.Effects"
|
||||
xmlns:views="clr-namespace:Bit.Core.Models.View"
|
||||
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
|
||||
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:localization="clr-namespace:Bit.Core.Resources.Localization"
|
||||
x:DataType="pages:CipherDetailsPageViewModel"
|
||||
HideSoftInputOnTapped="True"
|
||||
x:Name="_page"
|
||||
@@ -24,6 +24,7 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:StringHasValueConverter x:Key="stringHasValue" />
|
||||
<u:IsNotNullConverter x:Key="notNull" />
|
||||
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static localization:AppResources.CreatedXY}" />
|
||||
<ToolbarItem Text="{u:I18n Collections}"
|
||||
x:Key="collectionsItem"
|
||||
x:Name="_collectionsItem"
|
||||
@@ -200,12 +201,12 @@
|
||||
Text="{u:I18n Passkey}"
|
||||
StyleClass="box-label"
|
||||
Margin="0,10,0,0"
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Key, Converter={StaticResource notNull}}"/>
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}}"/>
|
||||
<Entry
|
||||
Text="{Binding CreationDate}"
|
||||
Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
|
||||
IsEnabled="False"
|
||||
StyleClass="box-value,text-muted"
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Key, Converter={StaticResource notNull}}" />
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}, FallbackValue=False}" />
|
||||
<Grid StyleClass="box-row"
|
||||
IsVisible="{Binding ShowTotp}"
|
||||
AutomationId="ItemRow">
|
||||
|
||||
@@ -708,7 +708,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task<bool> CanCloneAsync()
|
||||
{
|
||||
if (!Cipher.HasFido2Key)
|
||||
if (!Cipher.HasFido2Credential)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,24 +126,27 @@ namespace Bit.App.Pages
|
||||
|
||||
await LoadOnAppearedAsync(_mainLayout, false, async () =>
|
||||
{
|
||||
if (!_syncService.SyncInProgress || (await _cipherService.GetAllAsync()).Any())
|
||||
if (_previousPage == null)
|
||||
{
|
||||
try
|
||||
if (!_syncService.SyncInProgress || (await _cipherService.GetAllAsync()).Any())
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
try
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
else
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
if (!_vm.Loaded)
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
await Task.Delay(5000);
|
||||
if (!_vm.Loaded)
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
await ShowPreviousPageAsync();
|
||||
|
||||
@@ -113,15 +113,9 @@ namespace Bit.App.Pages
|
||||
try
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
||||
var error = await _cipherService.ShareWithServerAsync(cipherView, OrganizationId, checkedCollectionIds);
|
||||
await _cipherService.ShareWithServerAsync(cipherView, OrganizationId, checkedCollectionIds);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
|
||||
if (error == ICipherService.ShareWithServerError.DuplicatedPasskeyInOrg)
|
||||
{
|
||||
_platformUtilsService.ShowToast(null, null, AppResources.ThisItemCannotBeSharedWithTheOrganizationBecauseThereIsOneAlreadyWithTheSamePasskey);
|
||||
return false;
|
||||
}
|
||||
|
||||
var movedItemToOrgText = string.Format(AppResources.MovedItemToOrg, cipherView.Name,
|
||||
(await _organizationService.GetAsync(OrganizationId)).Name);
|
||||
_platformUtilsService.ShowToast("success", null, movedItemToOrgText);
|
||||
|
||||
Reference in New Issue
Block a user