diff --git a/src/App/App.csproj b/src/App/App.csproj
index 7c9929e98..2cb81d816 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -138,6 +138,7 @@
+
diff --git a/src/App/Pages/RegisterPage.cs b/src/App/Pages/RegisterPage.cs
index 62a9e7492..f332e6a00 100644
--- a/src/App/Pages/RegisterPage.cs
+++ b/src/App/Pages/RegisterPage.cs
@@ -123,8 +123,8 @@ namespace Bit.App.Pages
if(Device.OS == TargetPlatform.iOS)
{
- table.RowHeight = table2.RowHeight = table2.RowHeight = -1;
- table.EstimatedRowHeight = table2.EstimatedRowHeight = table2.EstimatedRowHeight = 70;
+ table.RowHeight = table2.RowHeight = -1;
+ table.EstimatedRowHeight = table2.EstimatedRowHeight = 70;
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Cancel, () =>
{
MessagingCenter.Send(Application.Current, "ShowStatusBar", false);
diff --git a/src/App/Pages/Settings/SettingsFeaturesPage.cs b/src/App/Pages/Settings/SettingsFeaturesPage.cs
new file mode 100644
index 000000000..efaaf33fe
--- /dev/null
+++ b/src/App/Pages/Settings/SettingsFeaturesPage.cs
@@ -0,0 +1,134 @@
+using System;
+using Bit.App.Abstractions;
+using Bit.App.Resources;
+using Xamarin.Forms;
+using XLabs.Ioc;
+using Bit.App.Controls;
+using Acr.UserDialogs;
+using Plugin.Settings.Abstractions;
+using Plugin.Fingerprint.Abstractions;
+using PushNotification.Plugin.Abstractions;
+
+namespace Bit.App.Pages
+{
+ public class SettingsFeaturesPage : ExtendedContentPage
+ {
+ private readonly IAuthService _authService;
+ private readonly IUserDialogs _userDialogs;
+ private readonly ISettings _settings;
+ private readonly IFingerprint _fingerprint;
+ private readonly IPushNotification _pushNotification;
+ private readonly IGoogleAnalyticsService _googleAnalyticsService;
+
+ public SettingsFeaturesPage()
+ {
+ _authService = Resolver.Resolve();
+ _userDialogs = Resolver.Resolve();
+ _settings = Resolver.Resolve();
+ _fingerprint = Resolver.Resolve();
+ _pushNotification = Resolver.Resolve();
+ _googleAnalyticsService = Resolver.Resolve();
+
+ Init();
+ }
+
+ private StackLayout StackLayout { get; set; }
+ private ExtendedSwitchCell AnalyticsCell { get; set; }
+ private Label AnalyticsLabel { get; set; }
+
+ private void Init()
+ {
+ AnalyticsCell = new ExtendedSwitchCell
+ {
+ Text = AppResources.DisableGA,
+ On = _settings.GetValueOrDefault(Constants.SettingGaOptOut, false)
+ };
+
+ var analyticsTable = new FormTableView
+ {
+ Root = new TableRoot
+ {
+ new TableSection(" ")
+ {
+ AnalyticsCell
+ }
+ }
+ };
+
+ AnalyticsLabel = new Label
+ {
+ Text = AppResources.DisbaleGADescription,
+ LineBreakMode = LineBreakMode.WordWrap,
+ FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
+ Style = (Style)Application.Current.Resources["text-muted"],
+ Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 25)
+ };
+
+ StackLayout = new StackLayout
+ {
+ Children = { analyticsTable, AnalyticsLabel },
+ Spacing = 0
+ };
+
+ var scrollView = new ScrollView
+ {
+ Content = StackLayout
+ };
+
+ if(Device.OS == TargetPlatform.iOS)
+ {
+ analyticsTable.RowHeight = -1;
+ analyticsTable.EstimatedRowHeight = 70;
+ }
+
+ Title = AppResources.Features;
+ Content = scrollView;
+ }
+
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+
+ AnalyticsCell.OnChanged += AnalyticsCell_Changed;
+ StackLayout.LayoutChanged += Layout_LayoutChanged;
+ }
+
+ protected override void OnDisappearing()
+ {
+ base.OnDisappearing();
+
+ AnalyticsCell.OnChanged -= AnalyticsCell_Changed;
+ StackLayout.LayoutChanged -= Layout_LayoutChanged;
+ }
+
+ private void Layout_LayoutChanged(object sender, EventArgs e)
+ {
+ AnalyticsLabel.WidthRequest = StackLayout.Bounds.Width - AnalyticsLabel.Bounds.Left * 2;
+ }
+
+ private void AnalyticsCell_Changed(object sender, ToggledEventArgs e)
+ {
+ var cell = sender as ExtendedSwitchCell;
+ if(cell == null)
+ {
+ return;
+ }
+
+ _settings.AddOrUpdateValue(Constants.SettingGaOptOut, cell.On);
+ _googleAnalyticsService.SetAppOptOut(cell.On);
+ }
+
+ private class FormTableView : ExtendedTableView
+ {
+ public FormTableView()
+ {
+ Intent = TableIntent.Settings;
+ EnableScrolling = false;
+ HasUnevenRows = true;
+ EnableSelection = true;
+ VerticalOptions = LayoutOptions.Start;
+ NoFooter = true;
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/SettingsPage.cs b/src/App/Pages/Settings/SettingsPage.cs
index 541e93712..a65935491 100644
--- a/src/App/Pages/Settings/SettingsPage.cs
+++ b/src/App/Pages/Settings/SettingsPage.cs
@@ -40,7 +40,6 @@ namespace Bit.App.Pages
private ExtendedTextCell TwoStepCell { get; set; }
private ExtendedTextCell ChangeMasterPasswordCell { get; set; }
private ExtendedTextCell ChangeEmailCell { get; set; }
- private ExtendedSwitchCell AnalyticsCell { get; set; }
private ExtendedTextCell FoldersCell { get; set; }
private ExtendedTextCell SyncCell { get; set; }
private ExtendedTextCell LockCell { get; set; }
@@ -48,6 +47,7 @@ namespace Bit.App.Pages
private ExtendedTextCell AboutCell { get; set; }
private ExtendedTextCell HelpCell { get; set; }
private ExtendedTextCell RateCell { get; set; }
+ private ExtendedTextCell FeaturesCell { get; set; }
private LongDetailViewCell RateCellLong { get; set; }
private ExtendedTableView Table { get; set; }
@@ -104,12 +104,6 @@ namespace Bit.App.Pages
ShowDisclousure = true
};
- AnalyticsCell = new ExtendedSwitchCell
- {
- Text = AppResources.DisableGA,
- On = _settings.GetValueOrDefault(Constants.SettingGaOptOut, false)
- };
-
FoldersCell = new ExtendedTextCell
{
Text = AppResources.Folders,
@@ -144,9 +138,15 @@ namespace Bit.App.Pages
ShowDisclousure = true
};
+ FeaturesCell = new ExtendedTextCell
+ {
+ Text = AppResources.Features,
+ ShowDisclousure = true
+ };
+
var otherSection = new TableSection(AppResources.Other)
{
- AnalyticsCell,
+ FeaturesCell,
AboutCell,
HelpCell
};
@@ -201,7 +201,6 @@ namespace Bit.App.Pages
base.OnAppearing();
PinCell.OnChanged += PinCell_Changed;
- AnalyticsCell.OnChanged += AnalyticsCell_Changed;
LockOptionsCell.Tapped += LockOptionsCell_Tapped;
TwoStepCell.Tapped += TwoStepCell_Tapped;
ChangeMasterPasswordCell.Tapped += ChangeMasterPasswordCell_Tapped;
@@ -216,8 +215,9 @@ namespace Bit.App.Pages
SyncCell.Tapped += SyncCell_Tapped;
LockCell.Tapped += LockCell_Tapped;
LogOutCell.Tapped += LogOutCell_Tapped;
- AboutCell.Tapped += AboutCell_Tapped;
+ AboutCell.Tapped += AboutCell_Tapped;
HelpCell.Tapped += HelpCell_Tapped;
+ FeaturesCell.Tapped += FeaturesCell_Tapped;
if(RateCellLong != null)
{
@@ -235,7 +235,6 @@ namespace Bit.App.Pages
base.OnDisappearing();
PinCell.OnChanged -= PinCell_Changed;
- AnalyticsCell.OnChanged -= AnalyticsCell_Changed;
LockOptionsCell.Tapped -= LockOptionsCell_Tapped;
TwoStepCell.Tapped -= TwoStepCell_Tapped;
ChangeMasterPasswordCell.Tapped -= ChangeMasterPasswordCell_Tapped;
@@ -252,6 +251,7 @@ namespace Bit.App.Pages
LogOutCell.Tapped -= LogOutCell_Tapped;
AboutCell.Tapped -= AboutCell_Tapped;
HelpCell.Tapped -= HelpCell_Tapped;
+ FeaturesCell.Tapped -= FeaturesCell_Tapped;
if(RateCellLong != null)
{
@@ -421,18 +421,6 @@ namespace Bit.App.Pages
}
}
- private void AnalyticsCell_Changed(object sender, ToggledEventArgs e)
- {
- var cell = sender as ExtendedSwitchCell;
- if (cell == null)
- {
- return;
- }
-
- _settings.AddOrUpdateValue(Constants.SettingGaOptOut, cell.On);
- _googleAnalyticsService.SetAppOptOut(cell.On);
- }
-
private void PinEntered(SettingsPinPage page)
{
page.PinControl.Entry.Unfocus();
@@ -450,6 +438,11 @@ namespace Bit.App.Pages
}
}
+ private void FeaturesCell_Tapped(object sender, EventArgs e)
+ {
+ Navigation.PushModalAsync(new ExtendedNavigationPage(new SettingsFeaturesPage()));
+ }
+
private void FoldersCell_Tapped(object sender, EventArgs e)
{
Navigation.PushModalAsync(new ExtendedNavigationPage(new SettingsListFoldersPage()));
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index 12e5ccd99..7799e9b25 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -529,6 +529,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to We use analytics to better learn how the app is being used so that we can make it better. All data collection is completely anonymous..
+ ///
+ public static string DisbaleGADescription {
+ get {
+ return ResourceManager.GetString("DisbaleGADescription", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Do you really want to delete? This cannot be undone..
///
@@ -772,6 +781,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Features.
+ ///
+ public static string Features {
+ get {
+ return ResourceManager.GetString("Features", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to File a Bug Report.
///
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index d789bf572..891a06fc7 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -825,4 +825,10 @@
Create an organization to securely share your logins with other users.
+
+ We use analytics to better learn how the app is being used so that we can make it better. All data collection is completely anonymous.
+
+
+ Features
+
\ No newline at end of file