From a0e65fa75e3bbc15fbbbf7202d25415b5d45af0e Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 9 May 2019 11:44:27 -0400 Subject: [PATCH] custom field name prompt --- src/Android/Services/DeviceActionService.cs | 46 ++++++++++++++++++++ src/App/Abstractions/IDeviceActionService.cs | 2 + src/App/Pages/Vault/AddEditPageViewModel.cs | 10 ++--- src/iOS/Services/DeviceActionService.cs | 29 +++++++++++- 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index cd5aa51a3..49b74f50d 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -6,7 +6,9 @@ using Android.Content; using Android.Content.PM; using Android.Support.V4.Content; using Android.Webkit; +using Android.Widget; using Bit.App.Abstractions; +using Bit.App.Resources; using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Enums; @@ -147,6 +149,50 @@ namespace Bit.Droid.Services catch(Exception) { } } + public Task DisplayPromptAync(string title = null, string description = null, + string text = null, string okButtonText = null, string cancelButtonText = null) + { + var activity = (MainActivity)CrossCurrentActivity.Current.Activity; + if(activity == null) + { + return Task.FromResult(null); + } + + var alertBuilder = new AlertDialog.Builder(activity); + alertBuilder.SetTitle(title); + alertBuilder.SetMessage(description); + var input = new EditText(activity) + { + InputType = Android.Text.InputTypes.ClassText + }; + if(text == null) + { + text = string.Empty; + } + + input.Text = text; + input.SetSelection(text.Length); + var container = new FrameLayout(activity); + var lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, + LinearLayout.LayoutParams.MatchParent); + lp.SetMargins(25, 0, 25, 0); + input.LayoutParameters = lp; + container.AddView(input); + alertBuilder.SetView(container); + + okButtonText = okButtonText ?? AppResources.Ok; + cancelButtonText = cancelButtonText ?? AppResources.Cancel; + var result = new TaskCompletionSource(); + alertBuilder.SetPositiveButton(okButtonText, + (sender, args) => result.TrySetResult(input.Text ?? string.Empty)); + alertBuilder.SetNegativeButton(cancelButtonText, (sender, args) => result.TrySetResult(null)); + + var alert = alertBuilder.Create(); + alert.Window.SetSoftInputMode(Android.Views.SoftInput.StateVisible); + alert.Show(); + return result.Task; + } + private bool DeleteDir(Java.IO.File dir) { if(dir != null && dir.IsDirectory) diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index 201225a4b..8df346c4b 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -13,5 +13,7 @@ namespace Bit.App.Abstractions bool OpenFile(byte[] fileData, string id, string fileName); bool CanOpenFile(string fileName); Task ClearCacheAsync(); + Task DisplayPromptAync(string title = null, string description = null, string text = null, + string okButtonText = null, string cancelButtonText = null); } } \ No newline at end of file diff --git a/src/App/Pages/Vault/AddEditPageViewModel.cs b/src/App/Pages/Vault/AddEditPageViewModel.cs index a3189b06f..9158c623e 100644 --- a/src/App/Pages/Vault/AddEditPageViewModel.cs +++ b/src/App/Pages/Vault/AddEditPageViewModel.cs @@ -394,9 +394,9 @@ namespace Bit.App.Pages } else if(selection == AppResources.Edit) { - var name = "new name"; - // TODO: prompt for name - field.Field.Name = name; + var name = await _deviceActionService.DisplayPromptAync(AppResources.CustomFieldName, + null, field.Field.Name); + field.Field.Name = name ?? field.Field.Name; field.TriggerFieldChanged(); } else if(selection == AppResources.MoveUp) @@ -423,9 +423,7 @@ namespace Bit.App.Pages _fieldTypeOptions.Select(f => f.Value).ToArray()); if(typeSelection != null && typeSelection != AppResources.Cancel) { - var name = "new field name"; - // TODO: prompt for name - + var name = await _deviceActionService.DisplayPromptAync(AppResources.CustomFieldName); if(Fields == null) { Fields = new ExtendedObservableCollection(); diff --git a/src/iOS/Services/DeviceActionService.cs b/src/iOS/Services/DeviceActionService.cs index 33bbf6367..c01166393 100644 --- a/src/iOS/Services/DeviceActionService.cs +++ b/src/iOS/Services/DeviceActionService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Bit.App.Abstractions; +using Bit.App.Resources; using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Enums; @@ -125,6 +126,32 @@ namespace Bit.iOS.Services await _storageService.SaveAsync(Constants.LastFileCacheClearKey, DateTime.UtcNow); } + public Task DisplayPromptAync(string title = null, string description = null, + string text = null, string okButtonText = null, string cancelButtonText = null) + { + var result = new TaskCompletionSource(); + var alert = UIAlertController.Create(title ?? string.Empty, description, UIAlertControllerStyle.Alert); + UITextField input = null; + okButtonText = okButtonText ?? AppResources.Ok; + cancelButtonText = cancelButtonText ?? AppResources.Cancel; + alert.AddAction(UIAlertAction.Create(cancelButtonText, UIAlertActionStyle.Cancel, x => + { + result.TrySetResult(null); + })); + alert.AddAction(UIAlertAction.Create(okButtonText, UIAlertActionStyle.Default, x => + { + result.TrySetResult(input.Text ?? string.Empty); + })); + alert.AddTextField(x => + { + input = x; + input.Text = text ?? string.Empty; + }); + var vc = GetPresentedViewController(); + vc?.PresentViewController(alert, true, null); + return result.Task; + } + private UIViewController GetVisibleViewController(UIViewController controller = null) { controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController; @@ -160,7 +187,7 @@ namespace Bit.iOS.Services return vc != null && (vc is UITabBarController || (vc.ChildViewControllers?.Any(c => c is UITabBarController) ?? false)); } - + // ref: //https://developer.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system/ public string GetTempPath() {