mirror of
https://github.com/bitwarden/mobile
synced 2025-12-26 21:23:46 +00:00
reset for v2
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class AddCipherToolBarItem : ExtendedToolbarItem
|
||||
{
|
||||
public AddCipherToolBarItem(Page page, string folderId)
|
||||
: base(() => Helpers.AddCipher(page, folderId))
|
||||
{
|
||||
Text = AppResources.Add;
|
||||
Icon = "plus.png";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class DismissModalToolBarItem : ExtendedToolbarItem, IDisposable
|
||||
{
|
||||
private readonly ContentPage _page;
|
||||
|
||||
public DismissModalToolBarItem(ContentPage page, string text = null, Action cancelClickedAction = null)
|
||||
: base(cancelClickedAction)
|
||||
{
|
||||
_page = page;
|
||||
// TODO: init and dispose events from pages
|
||||
InitEvents();
|
||||
Text = text ?? AppResources.Close;
|
||||
Icon = Helpers.ToolbarImage("ion_chevron_left.png");
|
||||
Priority = -1;
|
||||
}
|
||||
|
||||
protected async override void ClickedItem(object sender, EventArgs e)
|
||||
{
|
||||
base.ClickedItem(sender, e);
|
||||
await _page.Navigation.PopForDeviceAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Bit.App.Enums;
|
||||
using Bit.App.Utilities;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedButton : Button
|
||||
{
|
||||
public static readonly BindableProperty PaddingProperty =
|
||||
BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(ExtendedButton), default(Thickness));
|
||||
public static readonly BindableProperty UppercaseProperty =
|
||||
BindableProperty.Create(nameof(Uppercase), typeof(bool), typeof(ExtendedButton),
|
||||
Helpers.OnPlatform(iOS: false, Android: true, Windows: false));
|
||||
|
||||
public Thickness Padding
|
||||
{
|
||||
get { return (Thickness)GetValue(PaddingProperty); }
|
||||
set { SetValue(PaddingProperty, value); }
|
||||
}
|
||||
|
||||
public bool Uppercase
|
||||
{
|
||||
get { return (bool)GetValue(UppercaseProperty); }
|
||||
set { SetValue(UppercaseProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Pages;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedContentPage : ContentPage
|
||||
{
|
||||
private ISyncService _syncService;
|
||||
private IGoogleAnalyticsService _googleAnalyticsService;
|
||||
private ILockService _lockService;
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IAuthService _authService;
|
||||
private bool _syncIndicator;
|
||||
private bool _updateActivity;
|
||||
private bool _requireAuth;
|
||||
|
||||
public ExtendedContentPage(bool syncIndicator = false, bool updateActivity = true, bool requireAuth = true)
|
||||
{
|
||||
_syncIndicator = syncIndicator;
|
||||
_updateActivity = updateActivity;
|
||||
_requireAuth = requireAuth;
|
||||
_syncService = Resolver.Resolve<ISyncService>();
|
||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||
_lockService = Resolver.Resolve<ILockService>();
|
||||
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||
_authService = Resolver.Resolve<IAuthService>();
|
||||
|
||||
BackgroundColor = Color.FromHex("efeff4");
|
||||
}
|
||||
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if(_requireAuth && !_authService.IsAuthenticated)
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(
|
||||
() => Application.Current.MainPage = new ExtendedNavigationPage(new HomePage()));
|
||||
}
|
||||
|
||||
if(_syncIndicator)
|
||||
{
|
||||
MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted",
|
||||
(sender, success) => Device.BeginInvokeOnMainThread(() => IsBusy = _syncService.SyncInProgress));
|
||||
MessagingCenter.Subscribe<ISyncService>(Application.Current, "SyncStarted",
|
||||
(sender) => Device.BeginInvokeOnMainThread(() => IsBusy = _syncService.SyncInProgress));
|
||||
}
|
||||
|
||||
if(_syncIndicator)
|
||||
{
|
||||
IsBusy = _syncService.SyncInProgress;
|
||||
}
|
||||
|
||||
_googleAnalyticsService.TrackPage(GetType().Name);
|
||||
await _lockService.CheckLockAsync(false, true);
|
||||
base.OnAppearing();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
if(_syncIndicator)
|
||||
{
|
||||
MessagingCenter.Unsubscribe<Application, bool>(Application.Current, "SyncCompleted");
|
||||
MessagingCenter.Unsubscribe<Application>(Application.Current, "SyncStarted");
|
||||
}
|
||||
|
||||
if(_syncIndicator)
|
||||
{
|
||||
IsBusy = false;
|
||||
}
|
||||
|
||||
if(_updateActivity)
|
||||
{
|
||||
_lockService.UpdateLastActivity();
|
||||
}
|
||||
|
||||
base.OnDisappearing();
|
||||
_deviceActionService.DismissKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedEditor : Editor
|
||||
{
|
||||
public static readonly BindableProperty HasBorderProperty =
|
||||
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEditor), true);
|
||||
|
||||
public bool HasBorder
|
||||
{
|
||||
get { return (bool)GetValue(HasBorderProperty); }
|
||||
set { SetValue(HasBorderProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
using Bit.App.Enums;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedEntry : Entry
|
||||
{
|
||||
public ExtendedEntry()
|
||||
{
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
PlaceholderColor = Color.FromHex("c7c7cd");
|
||||
}
|
||||
|
||||
IsPasswordFromToggled = IsPassword;
|
||||
}
|
||||
|
||||
public static readonly BindableProperty HasBorderProperty =
|
||||
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEntry), true);
|
||||
|
||||
public static readonly BindableProperty HasOnlyBottomBorderProperty =
|
||||
BindableProperty.Create(nameof(HasOnlyBottomBorder), typeof(bool), typeof(ExtendedEntry), false);
|
||||
|
||||
public static readonly BindableProperty BottomBorderColorProperty =
|
||||
BindableProperty.Create(nameof(BottomBorderColor), typeof(Color), typeof(ExtendedEntry), Color.Default);
|
||||
|
||||
public static readonly BindableProperty TargetMaxLengthProperty =
|
||||
BindableProperty.Create(nameof(TargetMaxLength), typeof(int), typeof(ExtendedEntry), int.MaxValue);
|
||||
|
||||
public bool HasBorder
|
||||
{
|
||||
get { return (bool)GetValue(HasBorderProperty); }
|
||||
set { SetValue(HasBorderProperty, value); }
|
||||
}
|
||||
|
||||
public bool HasOnlyBottomBorder
|
||||
{
|
||||
get { return (bool)GetValue(HasOnlyBottomBorderProperty); }
|
||||
set { SetValue(HasOnlyBottomBorderProperty, value); }
|
||||
}
|
||||
|
||||
public Color BottomBorderColor
|
||||
{
|
||||
get { return (Color)GetValue(BottomBorderColorProperty); }
|
||||
set { SetValue(BottomBorderColorProperty, value); }
|
||||
}
|
||||
|
||||
public int TargetMaxLength
|
||||
{
|
||||
get { return (int)GetValue(TargetMaxLengthProperty); }
|
||||
set { SetValue(TargetMaxLengthProperty, value); }
|
||||
}
|
||||
|
||||
public Enums.ReturnType? TargetReturnType { get; set; }
|
||||
public bool? Autocorrect { get; set; }
|
||||
public bool DisableAutocapitalize { get; set; }
|
||||
public bool AllowClear { get; set; }
|
||||
public bool HideCursor { get; set; }
|
||||
public bool NumbersOnly { get; set; }
|
||||
|
||||
// Need to overwrite default handler because we cant Invoke otherwise
|
||||
public new event EventHandler Completed;
|
||||
|
||||
public void InvokeCompleted()
|
||||
{
|
||||
Completed?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public virtual void InvokeToggleIsPassword()
|
||||
{
|
||||
if(ToggleIsPassword == null)
|
||||
{
|
||||
IsPassword = IsPasswordFromToggled = !IsPassword;
|
||||
Focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleIsPassword.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler ToggleIsPassword;
|
||||
public bool IsPasswordFromToggled { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedListView : ListView
|
||||
{
|
||||
public static readonly BindableProperty BottomPaddingProperty =
|
||||
BindableProperty.Create(nameof(BottomPadding), typeof(int), typeof(ExtendedTableView), 0);
|
||||
|
||||
public ExtendedListView() { }
|
||||
public ExtendedListView(ListViewCachingStrategy cachingStrategy)
|
||||
: base(cachingStrategy) { }
|
||||
|
||||
public int BottomPadding { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedNavigationPage : NavigationPage
|
||||
{
|
||||
public ExtendedNavigationPage()
|
||||
: base()
|
||||
{
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
public ExtendedNavigationPage(Page root)
|
||||
: base(root)
|
||||
{
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
private void SetDefaults()
|
||||
{
|
||||
// default colors for our app
|
||||
BarBackgroundColor = Color.FromHex("3c8dbc");
|
||||
BarTextColor = Color.White;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedPicker : Picker
|
||||
{
|
||||
// TODO: text color
|
||||
|
||||
public static readonly BindableProperty HasBorderProperty =
|
||||
BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(ExtendedEntry), true);
|
||||
|
||||
public bool HasBorder
|
||||
{
|
||||
get { return (bool)GetValue(HasBorderProperty); }
|
||||
set { SetValue(HasBorderProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedSwitchCell : SwitchCell
|
||||
{
|
||||
public static readonly BindableProperty BackgroundColorProperty =
|
||||
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedSwitchCell), Color.White);
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get { return (Color)GetValue(BackgroundColorProperty); }
|
||||
set { SetValue(BackgroundColorProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedTabbedPage : TabbedPage
|
||||
{
|
||||
public ExtendedTabbedPage()
|
||||
{
|
||||
BackgroundColor = Color.FromHex("efeff4");
|
||||
}
|
||||
|
||||
public static readonly BindableProperty TintColorProperty =
|
||||
BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(ExtendedTabbedPage), Color.White);
|
||||
|
||||
public Color TintColor
|
||||
{
|
||||
get { return (Color)GetValue(TintColorProperty); }
|
||||
set { SetValue(TintColorProperty, value); }
|
||||
}
|
||||
|
||||
public bool NoBorder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedTableView : TableView
|
||||
{
|
||||
public static readonly BindableProperty EnableScrollingProperty =
|
||||
BindableProperty.Create(nameof(EnableScrolling), typeof(bool), typeof(ExtendedTableView), true);
|
||||
|
||||
public static readonly BindableProperty EnableSelectionProperty =
|
||||
BindableProperty.Create(nameof(EnableSelection), typeof(bool), typeof(ExtendedTableView), true);
|
||||
|
||||
public static readonly BindableProperty SeparatorColorProperty =
|
||||
BindableProperty.Create(nameof(SeparatorColor), typeof(Color), typeof(ExtendedTableView), Color.FromHex("d2d6de"));
|
||||
|
||||
public static readonly BindableProperty BottomPaddingProperty =
|
||||
BindableProperty.Create(nameof(BottomPadding), typeof(int), typeof(ExtendedTableView), 0);
|
||||
|
||||
public bool EnableScrolling
|
||||
{
|
||||
get { return (bool)GetValue(EnableScrollingProperty); }
|
||||
set { SetValue(EnableScrollingProperty, value); }
|
||||
}
|
||||
|
||||
public bool EnableSelection
|
||||
{
|
||||
get { return (bool)GetValue(EnableSelectionProperty); }
|
||||
set { SetValue(EnableSelectionProperty, value); }
|
||||
}
|
||||
|
||||
public Color SeparatorColor
|
||||
{
|
||||
get { return (Color)GetValue(SeparatorColorProperty); }
|
||||
set { SetValue(SeparatorColorProperty, value); }
|
||||
}
|
||||
|
||||
public int EstimatedRowHeight { get; set; }
|
||||
public bool NoHeader { get; set; }
|
||||
public bool NoFooter { get; set; }
|
||||
public int BottomPadding { get; set; }
|
||||
public Func<RedrawableStackLayout> WrappingStackLayout { get; set; }
|
||||
|
||||
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
|
||||
{
|
||||
if(!VerticalOptions.Expands && Device.RuntimePlatform != Device.UWP)
|
||||
{
|
||||
var baseOnSizeRequest = GetVisualElementOnSizeRequest();
|
||||
return baseOnSizeRequest(widthConstraint, heightConstraint);
|
||||
}
|
||||
|
||||
return base.OnSizeRequest(widthConstraint, heightConstraint);
|
||||
}
|
||||
|
||||
private Func<double, double, SizeRequest> GetVisualElementOnSizeRequest()
|
||||
{
|
||||
var handle = typeof(VisualElement).GetMethod(
|
||||
"OnSizeRequest",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic,
|
||||
null,
|
||||
new Type[] { typeof(double), typeof(double) },
|
||||
null)?.MethodHandle;
|
||||
|
||||
if(!handle.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException("handle could not be found.");
|
||||
}
|
||||
|
||||
var pointer = handle.Value.GetFunctionPointer();
|
||||
if(pointer == null)
|
||||
{
|
||||
throw new ArgumentNullException("pointer could not be found.");
|
||||
}
|
||||
|
||||
return (Func<double, double, SizeRequest>)Activator.CreateInstance(
|
||||
typeof(Func<double, double, SizeRequest>), this, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedTextCell : TextCell
|
||||
{
|
||||
public ExtendedTextCell()
|
||||
{
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
TextColor = Color.Black;
|
||||
}
|
||||
|
||||
DetailColor = Color.FromHex("777777");
|
||||
}
|
||||
|
||||
public static readonly BindableProperty BackgroundColorProperty =
|
||||
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedTextCell), Color.White);
|
||||
|
||||
public static readonly BindableProperty ShowDisclousureProperty =
|
||||
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedTextCell), false);
|
||||
|
||||
public static readonly BindableProperty DisclousureImageProperty =
|
||||
BindableProperty.Create(nameof(DisclousureImage), typeof(string), typeof(ExtendedTextCell), string.Empty);
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get { return (Color)GetValue(BackgroundColorProperty); }
|
||||
set { SetValue(BackgroundColorProperty, value); }
|
||||
}
|
||||
|
||||
public bool ShowDisclousure
|
||||
{
|
||||
get { return (bool)GetValue(ShowDisclousureProperty); }
|
||||
set { SetValue(ShowDisclousureProperty, value); }
|
||||
}
|
||||
|
||||
public string DisclousureImage
|
||||
{
|
||||
get { return (string)GetValue(DisclousureImageProperty); }
|
||||
set { SetValue(DisclousureImageProperty, value); }
|
||||
}
|
||||
|
||||
public LineBreakMode DetailLineBreakMode { get; set; } = LineBreakMode.TailTruncation;
|
||||
|
||||
public event EventHandler DisclousureTapped;
|
||||
|
||||
public void OnDisclousureTapped()
|
||||
{
|
||||
if(DisclousureTapped == null)
|
||||
{
|
||||
OnTapped();
|
||||
return;
|
||||
}
|
||||
|
||||
DisclousureTapped.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedToolbarItem : ToolbarItem, IDisposable
|
||||
{
|
||||
public ExtendedToolbarItem(Action clickAction = null)
|
||||
{
|
||||
ClickAction = clickAction;
|
||||
}
|
||||
|
||||
public Action ClickAction { get; set; }
|
||||
|
||||
protected virtual void ClickedItem(object sender, EventArgs e)
|
||||
{
|
||||
ClickAction?.Invoke();
|
||||
}
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
Clicked += ClickedItem;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Clicked -= ClickedItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class ExtendedViewCell : ViewCell
|
||||
{
|
||||
public static readonly BindableProperty BackgroundColorProperty =
|
||||
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedViewCell), Color.White);
|
||||
|
||||
public static readonly BindableProperty ShowDisclousureProperty =
|
||||
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedViewCell), false);
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get { return (Color)GetValue(BackgroundColorProperty); }
|
||||
set { SetValue(BackgroundColorProperty, value); }
|
||||
}
|
||||
|
||||
public bool ShowDisclousure
|
||||
{
|
||||
get { return (bool)GetValue(ShowDisclousureProperty); }
|
||||
set { SetValue(ShowDisclousureProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Refractored.FabControl;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class Fab : FloatingActionButtonView
|
||||
{
|
||||
public Fab(FabLayout fabLayout, string icon, Action<object, EventArgs> clickedAction)
|
||||
{
|
||||
ImageName = icon;
|
||||
ColorNormal = Color.FromHex("3c8dbc");
|
||||
ColorPressed = Color.FromHex("3883af");
|
||||
ColorRipple = Color.FromHex("3883af");
|
||||
Clicked = clickedAction;
|
||||
|
||||
AbsoluteLayout.SetLayoutFlags(this, AbsoluteLayoutFlags.PositionProportional);
|
||||
AbsoluteLayout.SetLayoutBounds(this, new Rectangle(1, 1, AbsoluteLayout.AutoSize,
|
||||
AbsoluteLayout.AutoSize));
|
||||
|
||||
fabLayout.Children.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class FabLayout : AbsoluteLayout
|
||||
{
|
||||
public FabLayout(View mainView)
|
||||
{
|
||||
VerticalOptions = LayoutOptions.FillAndExpand;
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand;
|
||||
SetLayoutFlags(mainView, AbsoluteLayoutFlags.All);
|
||||
SetLayoutBounds(mainView, new Rectangle(0, 0, 1, 1));
|
||||
Children.Add(mainView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class FormEditorCell : ExtendedViewCell, IDisposable
|
||||
{
|
||||
public FormEditorCell(Keyboard entryKeyboard = null, double? height = null)
|
||||
{
|
||||
Editor = new ExtendedEditor
|
||||
{
|
||||
Keyboard = entryKeyboard,
|
||||
HasBorder = false,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Editor))
|
||||
};
|
||||
|
||||
if(height.HasValue)
|
||||
{
|
||||
Editor.HeightRequest = height.Value;
|
||||
}
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(15, 10)
|
||||
};
|
||||
|
||||
stackLayout.Children.Add(Editor);
|
||||
|
||||
Editor.AdjustMarginsForDevice();
|
||||
stackLayout.AdjustPaddingForDevice();
|
||||
|
||||
View = stackLayout;
|
||||
}
|
||||
|
||||
public ExtendedEditor Editor { get; private set; }
|
||||
|
||||
private void FormEditorCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Editor.Focus();
|
||||
}
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
Tapped += FormEditorCell_Tapped;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Tapped -= FormEditorCell_Tapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
using Bit.App.Abstractions;
|
||||
using FFImageLoading.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class FormEntryCell : ExtendedViewCell, IDisposable
|
||||
{
|
||||
private VisualElement _nextElement;
|
||||
private TapGestureRecognizer _tgr;
|
||||
private StackLayout _buttonStackLayout = null;
|
||||
|
||||
public FormEntryCell(
|
||||
string labelText,
|
||||
Keyboard entryKeyboard = null,
|
||||
bool isPassword = false,
|
||||
VisualElement nextElement = null,
|
||||
bool useLabelAsPlaceholder = false,
|
||||
string imageSource = null,
|
||||
Thickness? containerPadding = null,
|
||||
string button1 = null,
|
||||
string button2 = null)
|
||||
{
|
||||
if(!useLabelAsPlaceholder)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
Text = labelText,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand
|
||||
};
|
||||
}
|
||||
|
||||
Entry = new ExtendedEntry
|
||||
{
|
||||
Keyboard = entryKeyboard,
|
||||
HasBorder = false,
|
||||
IsPassword = isPassword,
|
||||
AllowClear = true,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
WidthRequest = 1,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Entry))
|
||||
};
|
||||
|
||||
if(useLabelAsPlaceholder)
|
||||
{
|
||||
Entry.Placeholder = labelText;
|
||||
}
|
||||
|
||||
NextElement = nextElement;
|
||||
|
||||
var imageStackLayout = new StackLayout
|
||||
{
|
||||
Padding = containerPadding ?? new Thickness(15, 10),
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
Spacing = 10,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
VerticalOptions = LayoutOptions.FillAndExpand
|
||||
};
|
||||
|
||||
if(imageSource != null)
|
||||
{
|
||||
_tgr = new TapGestureRecognizer();
|
||||
|
||||
var theImage = new CachedImage
|
||||
{
|
||||
Source = imageSource,
|
||||
HorizontalOptions = LayoutOptions.Start,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
WidthRequest = 18,
|
||||
HeightRequest = 18
|
||||
};
|
||||
theImage.GestureRecognizers.Add(_tgr);
|
||||
|
||||
imageStackLayout.Children.Add(theImage);
|
||||
}
|
||||
|
||||
var formStackLayout = new StackLayout
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand
|
||||
};
|
||||
|
||||
if(!useLabelAsPlaceholder)
|
||||
{
|
||||
formStackLayout.Children.Add(Label);
|
||||
}
|
||||
|
||||
formStackLayout.Children.Add(Entry);
|
||||
imageStackLayout.Children.Add(formStackLayout);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(button1) || !string.IsNullOrWhiteSpace(button2))
|
||||
{
|
||||
_buttonStackLayout = new StackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
Spacing = 5
|
||||
};
|
||||
imageStackLayout.Children.Add(_buttonStackLayout);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(button1))
|
||||
{
|
||||
Button1 = new ExtendedButton { Image = button1 };
|
||||
_buttonStackLayout.Children.Add(Button1);
|
||||
Button1.Padding = new Thickness(0);
|
||||
Button1.BackgroundColor = Color.Transparent;
|
||||
Button1.WidthRequest = 40;
|
||||
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(button2))
|
||||
{
|
||||
Button2 = new ExtendedButton { Image = button2 };
|
||||
_buttonStackLayout.Children.Add(Button2);
|
||||
Button2.Padding = new Thickness(0);
|
||||
Button2.BackgroundColor = Color.Transparent;
|
||||
Button2.WidthRequest = 40;
|
||||
Button2.VerticalOptions = LayoutOptions.FillAndExpand;
|
||||
}
|
||||
}
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
var deviceInfo = Resolver.Resolve<IDeviceInfoService>();
|
||||
if(useLabelAsPlaceholder)
|
||||
{
|
||||
if(deviceInfo.Version < 21)
|
||||
{
|
||||
Entry.Margin = new Thickness(-9, 1, -9, 0);
|
||||
}
|
||||
else if(deviceInfo.Version == 21)
|
||||
{
|
||||
Entry.Margin = new Thickness(0, 4, 0, -4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry.AdjustMarginsForDevice();
|
||||
}
|
||||
|
||||
if(containerPadding == null)
|
||||
{
|
||||
imageStackLayout.AdjustPaddingForDevice();
|
||||
}
|
||||
}
|
||||
else if(Device.RuntimePlatform == Device.UWP)
|
||||
{
|
||||
if(_buttonStackLayout != null)
|
||||
{
|
||||
_buttonStackLayout.Spacing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
View = imageStackLayout;
|
||||
}
|
||||
|
||||
public Label Label { get; private set; }
|
||||
public ExtendedEntry Entry { get; private set; }
|
||||
public ExtendedButton Button1 { get; private set; }
|
||||
public ExtendedButton Button2 { get; private set; }
|
||||
public VisualElement NextElement
|
||||
{
|
||||
get => _nextElement;
|
||||
set
|
||||
{
|
||||
_nextElement = value;
|
||||
if(_nextElement != null && Entry != null)
|
||||
{
|
||||
Entry.TargetReturnType = Enums.ReturnType.Next;
|
||||
}
|
||||
else if(Entry != null)
|
||||
{
|
||||
Entry.TargetReturnType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Dictionary<string, object> MetaData { get; set; }
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
if(_nextElement != null)
|
||||
{
|
||||
Entry.Completed += Entry_Completed;
|
||||
}
|
||||
|
||||
if(_tgr != null)
|
||||
{
|
||||
_tgr.Tapped += Tgr_Tapped;
|
||||
}
|
||||
|
||||
Tapped += FormEntryCell_Tapped;
|
||||
}
|
||||
|
||||
private void Tgr_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Entry.Focus();
|
||||
}
|
||||
|
||||
private void FormEntryCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Entry.Focus();
|
||||
}
|
||||
|
||||
private void Entry_Completed(object sender, EventArgs e)
|
||||
{
|
||||
_nextElement?.Focus();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if(_tgr != null)
|
||||
{
|
||||
_tgr.Tapped -= Tgr_Tapped;
|
||||
}
|
||||
|
||||
Tapped -= FormEntryCell_Tapped;
|
||||
Entry.Completed -= Entry_Completed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class FormPickerCell : ExtendedViewCell
|
||||
{
|
||||
public FormPickerCell(string labelText, string[] pickerItems)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
Text = labelText,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
TextColor = Color.FromHex("777777")
|
||||
};
|
||||
|
||||
Picker = new ExtendedPicker
|
||||
{
|
||||
HasBorder = false
|
||||
};
|
||||
|
||||
foreach(var item in pickerItems)
|
||||
{
|
||||
Picker.Items.Add(item);
|
||||
}
|
||||
Picker.SelectedIndex = 0;
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(15, 10),
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand
|
||||
};
|
||||
|
||||
stackLayout.Children.Add(Label);
|
||||
stackLayout.Children.Add(Picker);
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
stackLayout.Spacing = 0;
|
||||
}
|
||||
Picker.AdjustMarginsForDevice();
|
||||
stackLayout.AdjustPaddingForDevice();
|
||||
|
||||
View = stackLayout;
|
||||
}
|
||||
|
||||
public Label Label { get; private set; }
|
||||
public ExtendedPicker Picker { get; private set; }
|
||||
|
||||
private void FormPickerCell_Tapped(object sender, EventArgs e)
|
||||
{
|
||||
Picker.Focus();
|
||||
}
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
Tapped += FormPickerCell_Tapped;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Tapped -= FormPickerCell_Tapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class FormSwitchCell : ExtendedViewCell
|
||||
{
|
||||
public FormSwitchCell(string labelText, string button1 = null)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
Text = labelText,
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
VerticalTextAlignment = TextAlignment.Center,
|
||||
TextColor = Color.Black,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||
};
|
||||
Switch = new Switch
|
||||
{
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(15, 5),
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
Children = { Label, Switch }
|
||||
};
|
||||
stackLayout.AdjustPaddingForDevice();
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(button1))
|
||||
{
|
||||
Button1 = new ExtendedButton { Image = button1 };
|
||||
stackLayout.Children.Add(Button1);
|
||||
Button1.BackgroundColor = Color.Transparent;
|
||||
Button1.Padding = new Thickness(0);
|
||||
Button1.WidthRequest = 40;
|
||||
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
|
||||
}
|
||||
|
||||
View = stackLayout;
|
||||
}
|
||||
|
||||
public Switch Switch { get; private set; }
|
||||
public Label Label { get; set; }
|
||||
public ExtendedButton Button1 { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class HybridWebView : View
|
||||
{
|
||||
private Action<string> _func;
|
||||
|
||||
public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: nameof(Uri),
|
||||
returnType: typeof(string), declaringType: typeof(HybridWebView), defaultValue: default(string));
|
||||
|
||||
public string Uri
|
||||
{
|
||||
get { return (string)GetValue(UriProperty); }
|
||||
set { SetValue(UriProperty, value); }
|
||||
}
|
||||
|
||||
public void RegisterAction(Action<string> callback)
|
||||
{
|
||||
_func = callback;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
_func = null;
|
||||
}
|
||||
|
||||
public void InvokeAction(string data)
|
||||
{
|
||||
_func?.Invoke(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
using FFImageLoading.Forms;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class LabeledDetailCell : ExtendedViewCell
|
||||
{
|
||||
public LabeledDetailCell()
|
||||
{
|
||||
Icon = new CachedImage
|
||||
{
|
||||
WidthRequest = 20,
|
||||
HeightRequest = 20,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
ErrorPlaceholder = "login.png",
|
||||
CacheDuration = TimeSpan.FromDays(30),
|
||||
BitmapOptimizations = true
|
||||
};
|
||||
|
||||
Label = new Label
|
||||
{
|
||||
LineBreakMode = LineBreakMode.TailTruncation,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
|
||||
};
|
||||
|
||||
Detail = new Label
|
||||
{
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
LineBreakMode = LineBreakMode.TailTruncation,
|
||||
Style = (Style)Application.Current.Resources["text-muted"]
|
||||
};
|
||||
|
||||
LabelIcon = new CachedImage
|
||||
{
|
||||
WidthRequest = 16,
|
||||
HeightRequest = 16,
|
||||
HorizontalOptions = LayoutOptions.Start,
|
||||
Margin = new Thickness(5, 0, 0, 0)
|
||||
};
|
||||
|
||||
LabelIcon2 = new CachedImage
|
||||
{
|
||||
WidthRequest = 16,
|
||||
HeightRequest = 16,
|
||||
HorizontalOptions = LayoutOptions.Start,
|
||||
Margin = new Thickness(5, 0, 0, 0)
|
||||
};
|
||||
|
||||
Button = new ExtendedButton
|
||||
{
|
||||
WidthRequest = 60
|
||||
};
|
||||
|
||||
var grid = new Grid
|
||||
{
|
||||
ColumnSpacing = 0,
|
||||
RowSpacing = 0,
|
||||
Padding = new Thickness(3, 3, 0, 3)
|
||||
};
|
||||
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
|
||||
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40, GridUnitType.Absolute) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(60, GridUnitType.Absolute) });
|
||||
grid.Children.Add(Icon, 0, 0);
|
||||
grid.Children.Add(Label, 1, 0);
|
||||
grid.Children.Add(Detail, 1, 1);
|
||||
grid.Children.Add(LabelIcon, 2, 0);
|
||||
grid.Children.Add(LabelIcon2, 3, 0);
|
||||
grid.Children.Add(Button, 4, 0);
|
||||
Grid.SetRowSpan(Icon, 2);
|
||||
Grid.SetRowSpan(Button, 2);
|
||||
Grid.SetColumnSpan(Detail, 3);
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Label.TextColor = Color.Black;
|
||||
}
|
||||
|
||||
View = grid;
|
||||
}
|
||||
|
||||
public CachedImage Icon { get; private set; }
|
||||
public Label Label { get; private set; }
|
||||
public Label Detail { get; private set; }
|
||||
public CachedImage LabelIcon { get; private set; }
|
||||
public CachedImage LabelIcon2 { get; private set; }
|
||||
public Button Button { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using FFImageLoading.Forms;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class LabeledRightDetailCell : ExtendedViewCell
|
||||
{
|
||||
public LabeledRightDetailCell(bool showIcon = true)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
LineBreakMode = LineBreakMode.TailTruncation,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand,
|
||||
};
|
||||
|
||||
Detail = new Label
|
||||
{
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
StackLayout = new StackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
Padding = new Thickness(15, 10),
|
||||
Children = { Label, Detail }
|
||||
};
|
||||
|
||||
if(showIcon)
|
||||
{
|
||||
Icon = new CachedImage
|
||||
{
|
||||
WidthRequest = 16,
|
||||
HeightRequest = 16,
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Margin = new Thickness(5, 0, 0, 0)
|
||||
};
|
||||
|
||||
StackLayout.Children.Add(Icon);
|
||||
}
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Label.TextColor = Color.Black;
|
||||
}
|
||||
|
||||
View = StackLayout;
|
||||
}
|
||||
|
||||
public Label Label { get; private set; }
|
||||
public Label Detail { get; private set; }
|
||||
public CachedImage Icon { get; private set; }
|
||||
public StackLayout StackLayout { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class LabeledValueCell : ExtendedViewCell
|
||||
{
|
||||
public LabeledValueCell(
|
||||
string labelText = null,
|
||||
string valueText = null,
|
||||
string button1Image = null,
|
||||
string button2Image = null,
|
||||
string subText = null)
|
||||
{
|
||||
var containerStackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(15, 10),
|
||||
Orientation = StackOrientation.Horizontal
|
||||
};
|
||||
|
||||
var labelValueStackLayout = new StackLayout
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand
|
||||
};
|
||||
|
||||
if(labelText != null)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
Text = labelText,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"]
|
||||
};
|
||||
|
||||
labelValueStackLayout.Children.Add(Label);
|
||||
}
|
||||
|
||||
Value = new Label
|
||||
{
|
||||
Text = valueText,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||
LineBreakMode = LineBreakMode.TailTruncation
|
||||
};
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Value.TextColor = Color.Black;
|
||||
}
|
||||
|
||||
labelValueStackLayout.Children.Add(Value);
|
||||
|
||||
containerStackLayout.Children.Add(labelValueStackLayout);
|
||||
|
||||
var buttonStackLayout = new StackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
Spacing = 5
|
||||
};
|
||||
|
||||
if(subText != null)
|
||||
{
|
||||
Sub = new Label
|
||||
{
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
buttonStackLayout.Children.Add(Sub);
|
||||
}
|
||||
|
||||
if(button1Image != null)
|
||||
{
|
||||
Button1 = new ExtendedButton
|
||||
{
|
||||
Image = button1Image,
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||
Margin = new Thickness(0),
|
||||
Padding = new Thickness(0),
|
||||
BackgroundColor = Color.Transparent,
|
||||
WidthRequest = 40
|
||||
};
|
||||
|
||||
buttonStackLayout.Children.Add(Button1);
|
||||
}
|
||||
|
||||
if(button2Image != null)
|
||||
{
|
||||
Button2 = new ExtendedButton
|
||||
{
|
||||
Image = button2Image,
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.FillAndExpand,
|
||||
Margin = new Thickness(0),
|
||||
Padding = new Thickness(0),
|
||||
BackgroundColor = Color.Transparent,
|
||||
WidthRequest = 40
|
||||
};
|
||||
|
||||
buttonStackLayout.Children.Add(Button2);
|
||||
}
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
containerStackLayout.AdjustPaddingForDevice();
|
||||
}
|
||||
else if(Device.RuntimePlatform == Device.UWP)
|
||||
{
|
||||
buttonStackLayout.Spacing = 0;
|
||||
|
||||
if(Button1 != null)
|
||||
{
|
||||
Button1.BackgroundColor = Color.Transparent;
|
||||
}
|
||||
if(Button2 != null)
|
||||
{
|
||||
Button2.BackgroundColor = Color.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
if(Sub != null && Button1 != null)
|
||||
{
|
||||
Sub.Margin = new Thickness(0, 0, 10, 0);
|
||||
}
|
||||
|
||||
containerStackLayout.Children.Add(buttonStackLayout);
|
||||
View = containerStackLayout;
|
||||
}
|
||||
|
||||
public Label Label { get; private set; }
|
||||
public Label Value { get; private set; }
|
||||
public Label Sub { get; private set; }
|
||||
public ExtendedButton Button1 { get; private set; }
|
||||
public ExtendedButton Button2 { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using Bit.App.Utilities;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class PinControl
|
||||
{
|
||||
public EventHandler OnPinEntered;
|
||||
|
||||
public PinControl()
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
HorizontalTextAlignment = TextAlignment.Center,
|
||||
FontSize = 35,
|
||||
FontFamily = Helpers.OnPlatform(iOS: "Menlo-Regular", Android: "monospace", Windows: "Courier")
|
||||
};
|
||||
|
||||
Entry = new ExtendedEntry
|
||||
{
|
||||
Keyboard = Keyboard.Numeric,
|
||||
TargetMaxLength = 4,
|
||||
HideCursor = true,
|
||||
NumbersOnly = true
|
||||
};
|
||||
|
||||
Entry.BackgroundColor = Entry.TextColor = Color.Transparent;
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Label.TextColor = Color.Black;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry.Margin = new Thickness(0, int.MaxValue, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Label Label { get; set; }
|
||||
public ExtendedEntry Entry { get; set; }
|
||||
|
||||
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if(e.NewTextValue.Length >= 4)
|
||||
{
|
||||
OnPinEntered.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
Entry.TextChanged += Entry_TextChanged;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Entry.TextChanged -= Entry_TextChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class RedrawableStackLayout : StackLayout
|
||||
{
|
||||
private DateTime _lastRedraw = DateTime.MinValue;
|
||||
private TimeSpan _redrawThreshold = TimeSpan.FromMilliseconds(1000);
|
||||
|
||||
public async Task RedrawIfNeededAsync(int delay = 0, bool force = false)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if(Device.RuntimePlatform == Device.iOS && (force || (now - _lastRedraw) > _redrawThreshold))
|
||||
{
|
||||
_lastRedraw = now;
|
||||
if(delay > 0)
|
||||
{
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class SectionHeaderViewCell : ExtendedViewCell
|
||||
{
|
||||
public SectionHeaderViewCell(string bindingName, string countBindingName = null, Thickness? padding = null)
|
||||
{
|
||||
var label = new Label
|
||||
{
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
VerticalTextAlignment = TextAlignment.Center,
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand
|
||||
};
|
||||
|
||||
label.SetBinding(Label.TextProperty, bindingName);
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = padding ?? new Thickness(16, 8),
|
||||
Children = { label },
|
||||
Orientation = StackOrientation.Horizontal
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(countBindingName))
|
||||
{
|
||||
var countLabel = new Label
|
||||
{
|
||||
LineBreakMode = LineBreakMode.NoWrap,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalTextAlignment = TextAlignment.Center
|
||||
};
|
||||
countLabel.SetBinding(Label.TextProperty, countBindingName);
|
||||
stackLayout.Children.Add(countLabel);
|
||||
}
|
||||
|
||||
View = stackLayout;
|
||||
BackgroundColor = Color.FromHex("efeff4");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
using Bit.App.Utilities;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class StepperCell : ExtendedViewCell
|
||||
{
|
||||
private Action _changedAction;
|
||||
|
||||
public StepperCell(string labelText, double value, double min, double max, double increment, Action changed = null)
|
||||
{
|
||||
_changedAction = changed;
|
||||
|
||||
Label = new Label
|
||||
{
|
||||
Text = labelText,
|
||||
HorizontalOptions = LayoutOptions.Start,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
|
||||
};
|
||||
|
||||
StepperValueLabel = new Label
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.FillAndExpand,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
HorizontalTextAlignment = TextAlignment.Start,
|
||||
Text = value.ToString(),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
|
||||
};
|
||||
|
||||
Stepper = new Stepper
|
||||
{
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
Minimum = min,
|
||||
Maximum = max,
|
||||
Increment = increment,
|
||||
Value = value
|
||||
};
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
Children = { Label, StepperValueLabel, Stepper },
|
||||
Spacing = 15,
|
||||
Padding = Helpers.OnPlatform(
|
||||
iOS: new Thickness(15, 8),
|
||||
Android: new Thickness(15, 2),
|
||||
Windows: new Thickness(15, 8))
|
||||
};
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Label.TextColor = Color.Black;
|
||||
}
|
||||
stackLayout.AdjustPaddingForDevice();
|
||||
|
||||
View = stackLayout;
|
||||
}
|
||||
|
||||
public Label Label { get; private set; }
|
||||
public Label StepperValueLabel { get; private set; }
|
||||
public Stepper Stepper { get; private set; }
|
||||
|
||||
private void Stepper_ValueChanged(object sender, ValueChangedEventArgs e)
|
||||
{
|
||||
StepperValueLabel.Text = e.NewValue.ToString();
|
||||
_changedAction?.Invoke();
|
||||
}
|
||||
|
||||
public void InitEvents()
|
||||
{
|
||||
Stepper.ValueChanged += Stepper_ValueChanged;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stepper.ValueChanged -= Stepper_ValueChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Bit.App.Models.Page;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class VaultAttachmentsViewCell : LabeledRightDetailCell
|
||||
{
|
||||
public VaultAttachmentsViewCell()
|
||||
{
|
||||
Label.SetBinding(Label.TextProperty, nameof(VaultAttachmentsPageModel.Attachment.Name));
|
||||
Detail.SetBinding(Label.TextProperty, nameof(VaultAttachmentsPageModel.Attachment.SizeName));
|
||||
Icon.Source = "trash";
|
||||
Detail.MinimumWidthRequest = 100;
|
||||
BackgroundColor = Color.White;
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
StackLayout.BackgroundColor = Color.White;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using Bit.App.Models.Page;
|
||||
using FFImageLoading.Forms;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class VaultGroupingViewCell : ExtendedViewCell
|
||||
{
|
||||
public VaultGroupingViewCell()
|
||||
{
|
||||
Icon = new CachedImage
|
||||
{
|
||||
WidthRequest = 20,
|
||||
HeightRequest = 20,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
VerticalOptions = LayoutOptions.Center,
|
||||
Source = "folder.png",
|
||||
Margin = new Thickness(0, 0, 10, 0)
|
||||
};
|
||||
|
||||
Label = new Label
|
||||
{
|
||||
LineBreakMode = LineBreakMode.TailTruncation,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand
|
||||
};
|
||||
Label.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
|
||||
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Name)));
|
||||
|
||||
CountLabel = new Label
|
||||
{
|
||||
LineBreakMode = LineBreakMode.NoWrap,
|
||||
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
|
||||
Style = (Style)Application.Current.Resources["text-muted"],
|
||||
HorizontalOptions = LayoutOptions.End
|
||||
};
|
||||
CountLabel.SetBinding(Label.TextProperty, string.Format("{0}.Node.{1}",
|
||||
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.Count)));
|
||||
CountLabel.SetBinding(VisualElement.IsVisibleProperty, string.Format("{0}.Node.{1}",
|
||||
nameof(VaultListPageModel.GroupingOrCipher.Grouping), nameof(VaultListPageModel.Grouping.ShowCount)));
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Spacing = 0,
|
||||
Padding = new Thickness(16, 10),
|
||||
Children = { Icon, Label, CountLabel },
|
||||
Orientation = StackOrientation.Horizontal
|
||||
};
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
Label.TextColor = Color.Black;
|
||||
}
|
||||
|
||||
View = stackLayout;
|
||||
BackgroundColor = Color.White;
|
||||
}
|
||||
|
||||
public CachedImage Icon { get; private set; }
|
||||
public Label Label { get; private set; }
|
||||
public Label CountLabel { get; private set; }
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
if(BindingContext is VaultListPageModel.GroupingOrCipher model)
|
||||
{
|
||||
Icon.Source = model.Grouping.Node.Folder ?
|
||||
$"folder{(model.Grouping.Node.Id == null ? "_o" : string.Empty)}.png" : "cube.png";
|
||||
}
|
||||
|
||||
base.OnBindingContextChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using Bit.App.Models.Page;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class VaultListViewCell : LabeledDetailCell
|
||||
{
|
||||
public static readonly BindableProperty CipherParameterProperty = BindableProperty.Create(nameof(CipherParameter),
|
||||
typeof(VaultListPageModel.Cipher), typeof(VaultListViewCell), null);
|
||||
public static readonly BindableProperty GroupingOrCipherParameterProperty =
|
||||
BindableProperty.Create(nameof(GroupingOrCipherParameter), typeof(VaultListPageModel.GroupingOrCipher),
|
||||
typeof(VaultListViewCell), null);
|
||||
|
||||
public VaultListViewCell(Action<VaultListPageModel.Cipher> moreClickedAction, bool groupingOrCipherBinding = false)
|
||||
{
|
||||
string bindingPrefix = null;
|
||||
if(groupingOrCipherBinding)
|
||||
{
|
||||
SetBinding(GroupingOrCipherParameterProperty, new Binding("."));
|
||||
bindingPrefix = string.Concat(nameof(VaultListPageModel.GroupingOrCipher.Cipher), ".");
|
||||
Button.Command = new Command(() => moreClickedAction?.Invoke(GroupingOrCipherParameter?.Cipher));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBinding(CipherParameterProperty, new Binding("."));
|
||||
Button.Command = new Command(() => moreClickedAction?.Invoke(CipherParameter));
|
||||
}
|
||||
|
||||
Label.SetBinding(Label.TextProperty, bindingPrefix + nameof(VaultListPageModel.Cipher.Name));
|
||||
Detail.SetBinding(Label.TextProperty, bindingPrefix + nameof(VaultListPageModel.Cipher.Subtitle));
|
||||
LabelIcon.SetBinding(VisualElement.IsVisibleProperty,
|
||||
bindingPrefix + nameof(VaultListPageModel.Cipher.Shared));
|
||||
LabelIcon2.SetBinding(VisualElement.IsVisibleProperty,
|
||||
bindingPrefix + nameof(VaultListPageModel.Cipher.HasAttachments));
|
||||
|
||||
Button.Image = "more.png";
|
||||
Button.BackgroundColor = Color.Transparent;
|
||||
|
||||
LabelIcon.Source = "share.png";
|
||||
LabelIcon2.Source = "paperclip.png";
|
||||
|
||||
BackgroundColor = Color.White;
|
||||
}
|
||||
|
||||
public VaultListPageModel.Cipher CipherParameter
|
||||
{
|
||||
get { return GetValue(CipherParameterProperty) as VaultListPageModel.Cipher; }
|
||||
set { SetValue(CipherParameterProperty, value); }
|
||||
}
|
||||
|
||||
public VaultListPageModel.GroupingOrCipher GroupingOrCipherParameter
|
||||
{
|
||||
get { return GetValue(GroupingOrCipherParameterProperty) as VaultListPageModel.GroupingOrCipher; }
|
||||
set { SetValue(GroupingOrCipherParameterProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
Icon.Source = null;
|
||||
|
||||
VaultListPageModel.Cipher cipher = null;
|
||||
if(BindingContext is VaultListPageModel.Cipher item)
|
||||
{
|
||||
cipher = item;
|
||||
}
|
||||
else if(BindingContext is VaultListPageModel.GroupingOrCipher groupingOrCipherItem)
|
||||
{
|
||||
cipher = groupingOrCipherItem.Cipher;
|
||||
}
|
||||
|
||||
if(cipher != null)
|
||||
{
|
||||
if(cipher.Type == Enums.CipherType.Login)
|
||||
{
|
||||
Icon.LoadingPlaceholder = "login.png";
|
||||
}
|
||||
Icon.Source = cipher.Icon;
|
||||
}
|
||||
|
||||
base.OnBindingContextChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user