diff --git a/src/App/App.csproj b/src/App/App.csproj
index 33f7945b5..b178d6813 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -41,6 +41,9 @@
GeneratorHistoryPage.xaml
+
+ FolderAddEditPage.xaml
+
FoldersPage.xaml
diff --git a/src/App/Pages/Settings/FolderAddEditPage.xaml b/src/App/Pages/Settings/FolderAddEditPage.xaml
new file mode 100644
index 000000000..ac1dfcd4a
--- /dev/null
+++ b/src/App/Pages/Settings/FolderAddEditPage.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Settings/FolderAddEditPage.xaml.cs b/src/App/Pages/Settings/FolderAddEditPage.xaml.cs
new file mode 100644
index 000000000..41a6c47fc
--- /dev/null
+++ b/src/App/Pages/Settings/FolderAddEditPage.xaml.cs
@@ -0,0 +1,51 @@
+namespace Bit.App.Pages
+{
+ public partial class FolderAddEditPage : BaseContentPage
+ {
+ private FolderAddEditPageViewModel _vm;
+
+ public FolderAddEditPage(
+ string folderId = null)
+ {
+ InitializeComponent();
+ _vm = BindingContext as FolderAddEditPageViewModel;
+ _vm.Page = this;
+ _vm.FolderId = folderId;
+ _vm.Init();
+ SetActivityIndicator();
+ if(!_vm.EditMode)
+ {
+ ToolbarItems.Remove(_deleteItem);
+ }
+ }
+
+ protected override async void OnAppearing()
+ {
+ base.OnAppearing();
+ await LoadOnAppearedAsync(_scrollView, true, async () =>
+ {
+ await _vm.LoadAsync();
+ if(!_vm.EditMode)
+ {
+ RequestFocus(_nameEntry);
+ }
+ });
+ }
+
+ private async void Save_Clicked(object sender, System.EventArgs e)
+ {
+ if(DoOnce())
+ {
+ await _vm.SubmitAsync();
+ }
+ }
+
+ private async void Delete_Clicked(object sender, System.EventArgs e)
+ {
+ if(DoOnce())
+ {
+ await _vm.DeleteAsync();
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/FolderAddEditPageViewModel.cs b/src/App/Pages/Settings/FolderAddEditPageViewModel.cs
new file mode 100644
index 000000000..4350a307a
--- /dev/null
+++ b/src/App/Pages/Settings/FolderAddEditPageViewModel.cs
@@ -0,0 +1,109 @@
+using Bit.App.Abstractions;
+using Bit.App.Resources;
+using Bit.Core.Abstractions;
+using Bit.Core.Exceptions;
+using Bit.Core.Models.View;
+using Bit.Core.Utilities;
+using System.Threading.Tasks;
+
+namespace Bit.App.Pages
+{
+ public class FolderAddEditPageViewModel : BaseViewModel
+ {
+ private readonly IDeviceActionService _deviceActionService;
+ private readonly IFolderService _folderService;
+ private readonly IPlatformUtilsService _platformUtilsService;
+ private FolderView _folder;
+
+ public FolderAddEditPageViewModel()
+ {
+ _deviceActionService = ServiceContainer.Resolve("deviceActionService");
+ _folderService = ServiceContainer.Resolve("folderService");
+ _platformUtilsService = ServiceContainer.Resolve("platformUtilsService");
+ }
+
+ public string FolderId { get; set; }
+ public FolderView Folder
+ {
+ get => _folder;
+ set => SetProperty(ref _folder, value);
+ }
+ public bool EditMode => !string.IsNullOrWhiteSpace(FolderId);
+
+ public void Init()
+ {
+ PageTitle = EditMode ? AppResources.EditFolder : AppResources.AddFolder;
+ }
+
+ public async Task LoadAsync()
+ {
+ if(Folder == null)
+ {
+ if(EditMode)
+ {
+ var folder = await _folderService.GetAsync(FolderId);
+ Folder = await folder.DecryptAsync();
+ }
+ else
+ {
+ Folder = new FolderView();
+ }
+ }
+ }
+
+ public async Task SubmitAsync()
+ {
+ if(string.IsNullOrWhiteSpace(Folder.Name))
+ {
+ await Page.DisplayAlert(AppResources.AnErrorHasOccurred,
+ string.Format(AppResources.ValidationFieldRequired, AppResources.Name),
+ AppResources.Ok);
+ return false;
+ }
+
+ var folder = await _folderService.EncryptAsync(Folder);
+ try
+ {
+ await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
+ await _folderService.SaveWithServerAsync(folder);
+ Folder.Id = folder.Id;
+ await _deviceActionService.HideLoadingAsync();
+ _platformUtilsService.ShowToast("success", null,
+ EditMode ? AppResources.FolderUpdated : AppResources.FolderCreated);
+ await Page.Navigation.PopModalAsync();
+ return true;
+ }
+ catch(ApiException e)
+ {
+ await _deviceActionService.HideLoadingAsync();
+ await Page.DisplayAlert(AppResources.AnErrorHasOccurred, e.Error.GetSingleMessage(), AppResources.Ok);
+ }
+ return false;
+ }
+
+ public async Task DeleteAsync()
+ {
+ var confirmed = await _platformUtilsService.ShowDialogAsync(AppResources.DoYouReallyWantToDelete,
+ null, AppResources.Yes, AppResources.No);
+ if(!confirmed)
+ {
+ return false;
+ }
+ try
+ {
+ await _deviceActionService.ShowLoadingAsync(AppResources.Deleting);
+ await _folderService.DeleteWithServerAsync(Folder.Id);
+ await _deviceActionService.HideLoadingAsync();
+ _platformUtilsService.ShowToast("success", null, AppResources.FolderDeleted);
+ await Page.Navigation.PopModalAsync();
+ return true;
+ }
+ catch(ApiException e)
+ {
+ await _deviceActionService.HideLoadingAsync();
+ await Page.DisplayAlert(AppResources.AnErrorHasOccurred, e.Error.GetSingleMessage(), AppResources.Ok);
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/FoldersPage.xaml b/src/App/Pages/Settings/FoldersPage.xaml
index 5af7b1e4c..ff0369474 100644
--- a/src/App/Pages/Settings/FoldersPage.xaml
+++ b/src/App/Pages/Settings/FoldersPage.xaml
@@ -31,7 +31,7 @@
ItemsSource="{Binding Folders}"
VerticalOptions="FillAndExpand"
CachingStrategy="RecycleElement"
- SelectedItem="Row_Selected"
+ ItemSelected="RowSelected"
StyleClass="list, list-platform">
diff --git a/src/App/Pages/Settings/FoldersPage.xaml.cs b/src/App/Pages/Settings/FoldersPage.xaml.cs
index 63e868702..eb3aa7f27 100644
--- a/src/App/Pages/Settings/FoldersPage.xaml.cs
+++ b/src/App/Pages/Settings/FoldersPage.xaml.cs
@@ -1,4 +1,5 @@
-using System;
+using Bit.Core.Models.View;
+using System;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -35,12 +36,23 @@ namespace Bit.App.Pages
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
{
-
+ ((ListView)sender).SelectedItem = null;
+ if(!DoOnce())
+ {
+ return;
+ }
+ if(!(e.SelectedItem is FolderView folder))
+ {
+ return;
+ }
+ var page = new FolderAddEditPage(folder.Id);
+ await Navigation.PushModalAsync(new NavigationPage(page));
}
private async void AddButton_Clicked(object sender, EventArgs e)
{
-
+ var page = new FolderAddEditPage();
+ await Navigation.PushModalAsync(new NavigationPage(page));
}
}
}
diff --git a/src/App/Pages/Vault/AddEditPageViewModel.cs b/src/App/Pages/Vault/AddEditPageViewModel.cs
index ea02bdd40..0ff5807db 100644
--- a/src/App/Pages/Vault/AddEditPageViewModel.cs
+++ b/src/App/Pages/Vault/AddEditPageViewModel.cs
@@ -408,6 +408,7 @@ namespace Bit.App.Pages
await _deviceActionService.HideLoadingAsync();
_platformUtilsService.ShowToast("success", null, AppResources.ItemDeleted);
_messagingService.Send("deletedCipher");
+ await Page.Navigation.PopModalAsync();
return true;
}
catch(ApiException e)