2016-07-02 09:01:47 +03:00
|
|
|
|
using System;
|
|
|
|
|
using Acr.UserDialogs;
|
|
|
|
|
using Bit.App.Abstractions;
|
|
|
|
|
using Bit.App.Controls;
|
|
|
|
|
using Bit.App.Models.Page;
|
|
|
|
|
using Bit.App.Resources;
|
|
|
|
|
using Plugin.Settings.Abstractions;
|
|
|
|
|
using Xamarin.Forms;
|
|
|
|
|
using XLabs.Ioc;
|
|
|
|
|
|
|
|
|
|
namespace Bit.App.Pages
|
|
|
|
|
{
|
|
|
|
|
public class ToolsPasswordGeneratorPage : ExtendedContentPage
|
|
|
|
|
{
|
|
|
|
|
private readonly IUserDialogs _userDialogs;
|
|
|
|
|
private readonly IPasswordGenerationService _passwordGenerationService;
|
|
|
|
|
private readonly ISettings _settings;
|
|
|
|
|
private readonly IClipboardService _clipboardService;
|
2016-08-04 07:32:37 +03:00
|
|
|
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
2016-07-07 07:27:29 +03:00
|
|
|
|
private readonly Action<string> _passwordValueAction;
|
2016-07-02 09:01:47 +03:00
|
|
|
|
|
2016-07-07 07:27:29 +03:00
|
|
|
|
public ToolsPasswordGeneratorPage(Action<string> passwordValueAction = null)
|
2016-07-02 09:01:47 +03:00
|
|
|
|
{
|
|
|
|
|
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
|
|
|
|
_passwordGenerationService = Resolver.Resolve<IPasswordGenerationService>();
|
|
|
|
|
_settings = Resolver.Resolve<ISettings>();
|
|
|
|
|
_clipboardService = Resolver.Resolve<IClipboardService>();
|
2016-08-04 07:32:37 +03:00
|
|
|
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
2016-07-07 07:27:29 +03:00
|
|
|
|
_passwordValueAction = passwordValueAction;
|
2016-07-02 09:01:47 +03:00
|
|
|
|
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public PasswordGeneratorPageModel Model { get; private set; } = new PasswordGeneratorPageModel();
|
|
|
|
|
public Label Password { get; private set; }
|
|
|
|
|
public SliderViewCell SliderCell { get; private set; }
|
|
|
|
|
|
|
|
|
|
public void Init()
|
|
|
|
|
{
|
|
|
|
|
Password = new Label
|
|
|
|
|
{
|
|
|
|
|
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
|
2016-07-06 02:07:56 +03:00
|
|
|
|
Margin = new Thickness(15, 40, 15, 40),
|
2016-07-02 09:01:47 +03:00
|
|
|
|
HorizontalTextAlignment = TextAlignment.Center,
|
2016-08-17 05:18:45 +03:00
|
|
|
|
FontFamily = Device.OnPlatform(iOS: "Courier", Android: "monospace", WinPhone: "Courier"),
|
2016-07-03 09:57:09 +03:00
|
|
|
|
LineBreakMode = LineBreakMode.TailTruncation,
|
|
|
|
|
VerticalOptions = LayoutOptions.Start
|
2016-07-02 09:01:47 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var tgr = new TapGestureRecognizer();
|
|
|
|
|
tgr.Tapped += Tgr_Tapped;
|
|
|
|
|
Password.GestureRecognizers.Add(tgr);
|
|
|
|
|
Password.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Password);
|
|
|
|
|
|
|
|
|
|
SliderCell = new SliderViewCell(this, _passwordGenerationService, _settings);
|
|
|
|
|
var settingsCell = new ExtendedTextCell { Text = "More Settings", ShowDisclousure = true };
|
|
|
|
|
settingsCell.Tapped += SettingsCell_Tapped;
|
|
|
|
|
|
|
|
|
|
var buttonColor = Color.FromHex("3c8dbc");
|
|
|
|
|
var regenerateCell = new ExtendedTextCell { Text = "Regenerate Password", TextColor = buttonColor };
|
|
|
|
|
regenerateCell.Tapped += RegenerateCell_Tapped; ;
|
|
|
|
|
var copyCell = new ExtendedTextCell { Text = "Copy Password", TextColor = buttonColor };
|
|
|
|
|
copyCell.Tapped += CopyCell_Tapped;
|
|
|
|
|
|
|
|
|
|
var table = new ExtendedTableView
|
|
|
|
|
{
|
2016-07-06 02:07:56 +03:00
|
|
|
|
VerticalOptions = LayoutOptions.Start,
|
2016-07-02 09:01:47 +03:00
|
|
|
|
EnableScrolling = false,
|
2016-07-05 05:31:15 +03:00
|
|
|
|
Intent = TableIntent.Settings,
|
2016-07-02 09:01:47 +03:00
|
|
|
|
HasUnevenRows = true,
|
2016-07-06 02:07:56 +03:00
|
|
|
|
NoHeader = true,
|
2016-07-02 09:01:47 +03:00
|
|
|
|
Root = new TableRoot
|
|
|
|
|
{
|
|
|
|
|
new TableSection
|
|
|
|
|
{
|
|
|
|
|
regenerateCell,
|
|
|
|
|
copyCell
|
2016-07-29 05:07:48 +03:00
|
|
|
|
},
|
|
|
|
|
new TableSection("Options")
|
|
|
|
|
{
|
|
|
|
|
SliderCell,
|
|
|
|
|
settingsCell
|
2016-07-02 09:01:47 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(Device.OS == TargetPlatform.iOS)
|
|
|
|
|
{
|
|
|
|
|
table.RowHeight = -1;
|
|
|
|
|
table.EstimatedRowHeight = 44;
|
2016-07-07 07:27:29 +03:00
|
|
|
|
ToolbarItems.Add(new DismissModalToolBarItem(this, _passwordValueAction == null ? "Close" : "Cancel"));
|
2016-07-02 09:01:47 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var stackLayout = new StackLayout
|
|
|
|
|
{
|
|
|
|
|
Orientation = StackOrientation.Vertical,
|
2016-07-05 05:31:15 +03:00
|
|
|
|
Children = { Password, table },
|
|
|
|
|
VerticalOptions = LayoutOptions.FillAndExpand,
|
|
|
|
|
Spacing = 0
|
2016-07-02 09:01:47 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var scrollView = new ScrollView
|
|
|
|
|
{
|
|
|
|
|
Content = stackLayout,
|
2016-07-05 05:31:15 +03:00
|
|
|
|
Orientation = ScrollOrientation.Vertical,
|
|
|
|
|
VerticalOptions = LayoutOptions.FillAndExpand
|
2016-07-02 09:01:47 +03:00
|
|
|
|
};
|
|
|
|
|
|
2016-07-07 07:35:39 +03:00
|
|
|
|
if(_passwordValueAction != null)
|
2016-07-07 07:27:29 +03:00
|
|
|
|
{
|
2016-07-07 07:35:39 +03:00
|
|
|
|
var selectToolBarItem = new ToolbarItem("Select", null, async () =>
|
|
|
|
|
{
|
2016-08-04 07:44:53 +03:00
|
|
|
|
_googleAnalyticsService.TrackAppEvent("SelectedGeneratedPassword");
|
2016-07-07 07:35:39 +03:00
|
|
|
|
_passwordValueAction(Password.Text);
|
|
|
|
|
await Navigation.PopModalAsync();
|
|
|
|
|
}, ToolbarItemOrder.Default, 0);
|
2016-07-07 07:27:29 +03:00
|
|
|
|
|
2016-07-07 07:35:39 +03:00
|
|
|
|
ToolbarItems.Add(selectToolBarItem);
|
|
|
|
|
}
|
2016-07-07 07:27:29 +03:00
|
|
|
|
|
2016-07-02 09:01:47 +03:00
|
|
|
|
Title = "Generate Password";
|
|
|
|
|
Content = scrollView;
|
|
|
|
|
BindingContext = Model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Tgr_Tapped(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
CopyPassword();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnAppearing()
|
|
|
|
|
{
|
|
|
|
|
base.OnAppearing();
|
2016-08-04 07:50:03 +03:00
|
|
|
|
_googleAnalyticsService.TrackAppEvent("GeneratedPassword");
|
2016-08-04 07:44:53 +03:00
|
|
|
|
Model.Password = _passwordGenerationService.GeneratePassword();
|
2016-08-04 07:32:37 +03:00
|
|
|
|
Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString();
|
2016-07-02 09:01:47 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RegenerateCell_Tapped(object sender, EventArgs e)
|
|
|
|
|
{
|
2016-08-04 07:44:53 +03:00
|
|
|
|
Model.Password = _passwordGenerationService.GeneratePassword();
|
|
|
|
|
_googleAnalyticsService.TrackAppEvent("RegeneratedPassword");
|
2016-07-02 09:01:47 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CopyCell_Tapped(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
CopyPassword();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SettingsCell_Tapped(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Navigation.PushAsync(new ToolsPasswordGeneratorSettingsPage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CopyPassword()
|
|
|
|
|
{
|
2016-08-04 07:32:37 +03:00
|
|
|
|
_googleAnalyticsService.TrackAppEvent("CopiedGeneratedPassword");
|
2016-07-02 09:01:47 +03:00
|
|
|
|
_clipboardService.CopyToClipboard(Password.Text);
|
2016-07-26 07:38:41 +03:00
|
|
|
|
_userDialogs.Toast(string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
2016-07-02 09:01:47 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-07-13 01:59:09 +03:00
|
|
|
|
// TODO: move to standalone reusable control
|
2016-07-02 09:01:47 +03:00
|
|
|
|
public class SliderViewCell : ExtendedViewCell
|
|
|
|
|
{
|
|
|
|
|
private readonly ToolsPasswordGeneratorPage _page;
|
|
|
|
|
private readonly IPasswordGenerationService _passwordGenerationService;
|
|
|
|
|
private readonly ISettings _settings;
|
|
|
|
|
|
|
|
|
|
public Label Value { get; set; }
|
|
|
|
|
public Slider LengthSlider { get; set; }
|
|
|
|
|
|
|
|
|
|
public SliderViewCell(
|
|
|
|
|
ToolsPasswordGeneratorPage page,
|
|
|
|
|
IPasswordGenerationService passwordGenerationService,
|
|
|
|
|
ISettings settings)
|
|
|
|
|
{
|
|
|
|
|
_page = page;
|
|
|
|
|
_passwordGenerationService = passwordGenerationService;
|
|
|
|
|
_settings = settings;
|
|
|
|
|
|
|
|
|
|
var label = new Label
|
|
|
|
|
{
|
2016-08-23 01:59:15 +03:00
|
|
|
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
2016-07-02 09:01:47 +03:00
|
|
|
|
Text = "Length",
|
|
|
|
|
HorizontalOptions = LayoutOptions.Start,
|
|
|
|
|
VerticalOptions = LayoutOptions.CenterAndExpand
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
LengthSlider = new Slider(5, 64, _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10))
|
|
|
|
|
{
|
|
|
|
|
HorizontalOptions = LayoutOptions.FillAndExpand,
|
|
|
|
|
VerticalOptions = LayoutOptions.CenterAndExpand
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Value = new Label
|
|
|
|
|
{
|
2016-08-23 01:59:15 +03:00
|
|
|
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
2016-07-02 09:01:47 +03:00
|
|
|
|
HorizontalOptions = LayoutOptions.End,
|
|
|
|
|
VerticalOptions = LayoutOptions.CenterAndExpand,
|
|
|
|
|
Style = (Style)Application.Current.Resources["text-muted"]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Value.SetBinding<PasswordGeneratorPageModel>(Label.TextProperty, m => m.Length);
|
|
|
|
|
|
|
|
|
|
LengthSlider.ValueChanged += Slider_ValueChanged;
|
|
|
|
|
|
|
|
|
|
var stackLayout = new StackLayout
|
|
|
|
|
{
|
|
|
|
|
Orientation = StackOrientation.Horizontal,
|
|
|
|
|
Spacing = 15,
|
|
|
|
|
Children = { label, LengthSlider, Value },
|
2016-08-23 05:59:42 +03:00
|
|
|
|
Padding = Device.OnPlatform(
|
|
|
|
|
iOS: new Thickness(15, 8),
|
|
|
|
|
Android: new Thickness(16, 10),
|
|
|
|
|
WinPhone: new Thickness(15, 8))
|
2016-07-02 09:01:47 +03:00
|
|
|
|
};
|
|
|
|
|
|
2016-08-23 05:59:42 +03:00
|
|
|
|
if(Device.OS == TargetPlatform.Android)
|
|
|
|
|
{
|
|
|
|
|
label.TextColor = Color.Black;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-02 09:01:47 +03:00
|
|
|
|
View = stackLayout;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Slider_ValueChanged(object sender, ValueChangedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var length = Convert.ToInt32(LengthSlider.Value);
|
|
|
|
|
_settings.AddOrUpdateValue(Constants.PasswordGeneratorLength, length);
|
|
|
|
|
_page.Model.Length = length.ToString();
|
|
|
|
|
_page.Model.Password = _passwordGenerationService.GeneratePassword();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|