diff --git a/src/App/Pages/Settings/OptionsPage.xaml b/src/App/Pages/Settings/OptionsPage.xaml
index f1e5a7874..105ef7dda 100644
--- a/src/App/Pages/Settings/OptionsPage.xaml
+++ b/src/App/Pages/Settings/OptionsPage.xaml
@@ -12,37 +12,84 @@
-
-
-
+
+
+
+
+
+
+
-
+ Text="{u:I18n DefaultUriMatchDetectionDescription}"
+ StyleClass="box-footer-label" />
-
-
-
-
+
+
+
+
+
-
+ Text="{u:I18n ClearClipboardDescription}"
+ StyleClass="box-footer-label" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
diff --git a/src/App/Pages/Settings/OptionsPage.xaml.cs b/src/App/Pages/Settings/OptionsPage.xaml.cs
index 56f1a8b8c..4295aaf1b 100644
--- a/src/App/Pages/Settings/OptionsPage.xaml.cs
+++ b/src/App/Pages/Settings/OptionsPage.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using Xamarin.Forms;
namespace Bit.App.Pages
{
@@ -11,6 +12,9 @@ namespace Bit.App.Pages
InitializeComponent();
_vm = BindingContext as OptionsPageViewModel;
_vm.Page = this;
+ _themePicker.ItemDisplayBinding = new Binding("Value");
+ _uriMatchPicker.ItemDisplayBinding = new Binding("Value");
+ _clearClipboardPicker.ItemDisplayBinding = new Binding("Value");
}
protected async override void OnAppearing()
diff --git a/src/App/Pages/Settings/OptionsPageViewModel.cs b/src/App/Pages/Settings/OptionsPageViewModel.cs
index d9eafc654..1e859f463 100644
--- a/src/App/Pages/Settings/OptionsPageViewModel.cs
+++ b/src/App/Pages/Settings/OptionsPageViewModel.cs
@@ -2,7 +2,9 @@
using Bit.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions;
+using Bit.Core.Enums;
using Bit.Core.Utilities;
+using System.Collections.Generic;
using System.Threading.Tasks;
namespace Bit.App.Pages
@@ -18,6 +20,10 @@ namespace Bit.App.Pages
private bool _disableFavicon;
private bool _disableAutoTotpCopy;
+ private int _clearClipboardSelectedIndex;
+ private int _themeSelectedIndex;
+ private int _uriMatchSelectedIndex;
+
public OptionsPageViewModel()
{
_deviceActionService = ServiceContainer.Resolve("deviceActionService");
@@ -27,6 +33,72 @@ namespace Bit.App.Pages
_stateService = ServiceContainer.Resolve("stateService");
PageTitle = AppResources.Options;
+
+ ClearClipboardOptions = new List>
+ {
+ new KeyValuePair(null, AppResources.Never),
+ new KeyValuePair(10, AppResources.TenSeconds),
+ new KeyValuePair(20, AppResources.TwentySeconds),
+ new KeyValuePair(30, AppResources.ThirtySeconds),
+ new KeyValuePair(60, AppResources.OneMinute),
+ new KeyValuePair(120, AppResources.TwoMinutes),
+ new KeyValuePair(300, AppResources.FiveMinutes),
+ };
+ ThemeOptions = new List>
+ {
+ new KeyValuePair(null, AppResources.Default),
+ new KeyValuePair("light", AppResources.Light),
+ new KeyValuePair("dark", AppResources.Dark),
+ };
+ UriMatchOptions = new List>
+ {
+ new KeyValuePair(UriMatchType.Domain, AppResources.BaseDomain),
+ new KeyValuePair(UriMatchType.Host, AppResources.Host),
+ new KeyValuePair(UriMatchType.StartsWith, AppResources.StartsWith),
+ new KeyValuePair(UriMatchType.RegularExpression, AppResources.RegEx),
+ new KeyValuePair(UriMatchType.Exact, AppResources.Exact),
+ new KeyValuePair(UriMatchType.Never, AppResources.Never),
+ };
+ }
+
+ public List> ClearClipboardOptions { get; set; }
+ public List> ThemeOptions { get; set; }
+ public List> UriMatchOptions { get; set; }
+
+ public int ClearClipboardSelectedIndex
+ {
+ get => _clearClipboardSelectedIndex;
+ set
+ {
+ if(SetProperty(ref _clearClipboardSelectedIndex, value))
+ {
+ var task = SaveClipboardChangedAsync();
+ }
+ }
+ }
+
+ public int ThemeSelectedIndex
+ {
+ get => _themeSelectedIndex;
+ set
+ {
+ if(SetProperty(ref _themeSelectedIndex, value))
+ {
+ var task = SaveThemeAsync();
+ }
+ }
+ }
+
+ public int UriMatchSelectedIndex
+ {
+ get => _uriMatchSelectedIndex;
+ set
+ {
+ if(SetProperty(ref _uriMatchSelectedIndex, value))
+ {
+ var task = SaveDefaultUriAsync();
+ }
+ }
}
public bool DisableFavicon
@@ -57,6 +129,13 @@ namespace Bit.App.Pages
{
DisableAutoTotpCopy = !(await _totpService.IsAutoCopyEnabledAsync());
DisableFavicon = await _storageService.GetAsync(Constants.DisableFaviconKey);
+ var theme = await _storageService.GetAsync(Constants.ThemeKey);
+ ThemeSelectedIndex = ThemeOptions.FindIndex(k => k.Key == theme);
+ var defaultUriMatch = await _storageService.GetAsync(Constants.DefaultUriMatch);
+ UriMatchSelectedIndex = defaultUriMatch == null ? 0 :
+ UriMatchOptions.FindIndex(k => (int?)k.Key == defaultUriMatch);
+ var clearClipboard = await _storageService.GetAsync(Constants.ClearClipboardKey);
+ ClearClipboardSelectedIndex = ClearClipboardOptions.FindIndex(k => k.Key == clearClipboard);
}
private async Task UpdateAutoTotpCopyAsync()
@@ -69,5 +148,31 @@ namespace Bit.App.Pages
await _storageService.SaveAsync(Constants.DisableFaviconKey, DisableFavicon);
await _stateService.SaveAsync(Constants.DisableFaviconKey, DisableFavicon);
}
+
+ private async Task SaveClipboardChangedAsync()
+ {
+ if(ClearClipboardSelectedIndex > -1)
+ {
+ await _storageService.SaveAsync(Constants.ClearClipboardKey,
+ ClearClipboardOptions[ClearClipboardSelectedIndex].Key);
+ }
+ }
+
+ private async Task SaveThemeAsync()
+ {
+ if(ThemeSelectedIndex > -1)
+ {
+ await _storageService.SaveAsync(Constants.ThemeKey, ThemeOptions[ThemeSelectedIndex].Key);
+ // TODO: change theme
+ }
+ }
+
+ private async Task SaveDefaultUriAsync()
+ {
+ if(UriMatchSelectedIndex > -1)
+ {
+ await _storageService.SaveAsync(Constants.DefaultUriMatch, UriMatchOptions[UriMatchSelectedIndex].Key);
+ }
+ }
}
}
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index 253d7d0e0..9fd8a198c 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -879,6 +879,24 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Clear Clipboard.
+ ///
+ public static string ClearClipboard {
+ get {
+ return ResourceManager.GetString("ClearClipboard", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Automatically clear copied values from your clipboard..
+ ///
+ public static string ClearClipboardDescription {
+ get {
+ return ResourceManager.GetString("ClearClipboardDescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Close.
///
@@ -1086,6 +1104,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Dark.
+ ///
+ public static string Dark {
+ get {
+ return ResourceManager.GetString("Dark", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Password Updated.
///
@@ -1122,6 +1149,24 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Default URI Match Detection.
+ ///
+ public static string DefaultUriMatchDetection {
+ get {
+ return ResourceManager.GetString("DefaultUriMatchDetection", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Choose the default way that URI match detection is handled for logins when performing actions such as auto-fill..
+ ///
+ public static string DefaultUriMatchDetectionDescription {
+ get {
+ return ResourceManager.GetString("DefaultUriMatchDetectionDescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Delete.
///
@@ -1644,6 +1689,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to 5 minutes.
+ ///
+ public static string FiveMinutes {
+ get {
+ return ResourceManager.GetString("FiveMinutes", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Folder.
///
@@ -2040,6 +2094,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Light.
+ ///
+ public static string Light {
+ get {
+ return ResourceManager.GetString("Light", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Lock.
///
@@ -2706,6 +2769,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to 1 minute.
+ ///
+ public static string OneMinute {
+ get {
+ return ResourceManager.GetString("OneMinute", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Option defaults are set from the main Bitwarden app's password generator tool..
///
@@ -3381,6 +3453,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to 10 seconds.
+ ///
+ public static string TenSeconds {
+ get {
+ return ResourceManager.GetString("TenSeconds", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Thank You.
///
@@ -3390,6 +3471,33 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Theme.
+ ///
+ public static string Theme {
+ get {
+ return ResourceManager.GetString("Theme", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Change the application's color theme..
+ ///
+ public static string ThemeDescription {
+ get {
+ return ResourceManager.GetString("ThemeDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to 30 seconds.
+ ///
+ public static string ThirtySeconds {
+ get {
+ return ResourceManager.GetString("ThirtySeconds", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Title.
///
@@ -3435,6 +3543,24 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to 20 seconds.
+ ///
+ public static string TwentySeconds {
+ get {
+ return ResourceManager.GetString("TwentySeconds", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to 2 minutes.
+ ///
+ public static string TwoMinutes {
+ get {
+ return ResourceManager.GetString("TwoMinutes", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Two-step Login.
///
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index ac7702d09..ec5d8588d 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -1509,4 +1509,52 @@
Your vault is locked. Verify your PIN code to continue.
+
+ Dark
+ A dark color
+
+
+ Light
+ A light color
+
+
+ 5 minutes
+
+
+ 1 minute
+
+
+ 10 seconds
+
+
+ 30 seconds
+
+
+ 20 seconds
+
+
+ 2 minutes
+
+
+ Clear Clipboard
+ Clipboard is the operating system thing where you copy/paste data to on your device.
+
+
+ Automatically clear copied values from your clipboard.
+ Clipboard is the operating system thing where you copy/paste data to on your device.
+
+
+ Default URI Match Detection
+ Default URI match detection for auto-fill.
+
+
+ Choose the default way that URI match detection is handled for logins when performing actions such as auto-fill.
+
+
+ Theme
+ Color theme
+
+
+ Change the application's color theme.
+
\ No newline at end of file
diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs
index 8211aad70..ffd42e6ed 100644
--- a/src/Core/Constants.cs
+++ b/src/Core/Constants.cs
@@ -20,6 +20,8 @@
public static string PushCurrentTokenKey = "pushCurrentToken";
public static string PushLastRegistrationDateKey = "pushLastRegistrationDate";
public static string PushInitialPromptShownKey = "pushInitialPromptShown";
+ public static string ThemeKey = "theme";
+ public static string ClearClipboardKey = "clearClipboard";
public const int SelectFileRequestCode = 42;
public const int SelectFilePermissionRequestCode = 43;
}