mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-26 12:16:07 +01:00
redraw stack layouts on ios tableviews
This commit is contained in:
parent
fa9e22730a
commit
9456f5dc31
@ -1,6 +1,4 @@
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
@ -42,6 +40,7 @@ namespace Bit.App.Controls
|
||||
public bool NoHeader { get; set; }
|
||||
public bool NoFooter { get; set; }
|
||||
public int BottomPadding { get; set; }
|
||||
public Func<RedrawableStackLayout> WrappingStackLayout { get; set; }
|
||||
|
||||
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
|
||||
{
|
||||
|
27
src/App/Controls/RedrawableStackLayout.cs
Normal file
27
src/App/Controls/RedrawableStackLayout.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class RedrawableStackLayout : StackLayout
|
||||
{
|
||||
private DateTime _lastRedraw = DateTime.MinValue;
|
||||
private TimeSpan _redrawThreshold = TimeSpan.FromMilliseconds(1000);
|
||||
|
||||
public async Task RedrawIfNeededAsync(int delay = 0, bool force = false)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if(Device.RuntimePlatform == Device.iOS && (force || (now - _lastRedraw) > _redrawThreshold))
|
||||
{
|
||||
_lastRedraw = now;
|
||||
if(delay > 0)
|
||||
{
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ namespace Bit.App.Pages
|
||||
public FormEntryCell ApiUrlCell { get; set; }
|
||||
public FormEntryCell IdentityUrlCell { get; set; }
|
||||
public FormEntryCell IconsUrlCell { get; set; }
|
||||
public StackLayout StackLayout { get; set; }
|
||||
public RedrawableStackLayout StackLayout { get; set; }
|
||||
public Label SelfHostLabel { get; set; }
|
||||
public Label CustomLabel { get; set; }
|
||||
|
||||
@ -57,7 +57,7 @@ namespace Bit.App.Pages
|
||||
entryKeyboard: Keyboard.Url);
|
||||
BaseUrlCell.Entry.Text = _appSettings.BaseUrl;
|
||||
|
||||
var table = new FormTableView
|
||||
var table = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -74,10 +74,10 @@ namespace Bit.App.Pages
|
||||
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)
|
||||
Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 5)
|
||||
};
|
||||
|
||||
var table2 = new FormTableView
|
||||
var table2 = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -97,10 +97,10 @@ namespace Bit.App.Pages
|
||||
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)
|
||||
Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 5)
|
||||
};
|
||||
|
||||
StackLayout = new StackLayout
|
||||
StackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { table, SelfHostLabel, table2, CustomLabel },
|
||||
Spacing = 0
|
||||
@ -138,7 +138,6 @@ namespace Bit.App.Pages
|
||||
IdentityUrlCell.InitEvents();
|
||||
ApiUrlCell.InitEvents();
|
||||
WebVaultUrlCell.InitEvents();
|
||||
StackLayout.LayoutChanged += Layout_LayoutChanged;
|
||||
BaseUrlCell.Entry.FocusWithDelay();
|
||||
}
|
||||
protected override void OnDisappearing()
|
||||
@ -149,13 +148,6 @@ namespace Bit.App.Pages
|
||||
IdentityUrlCell.Dispose();
|
||||
ApiUrlCell.Dispose();
|
||||
WebVaultUrlCell.Dispose();
|
||||
StackLayout.LayoutChanged -= Layout_LayoutChanged;
|
||||
}
|
||||
|
||||
private void Layout_LayoutChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelfHostLabel.WidthRequest = StackLayout.Bounds.Width - SelfHostLabel.Bounds.Left * 2;
|
||||
CustomLabel.WidthRequest = StackLayout.Bounds.Width - CustomLabel.Bounds.Left * 2;
|
||||
}
|
||||
|
||||
private async Task SaveAsync()
|
||||
@ -259,7 +251,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private class FormTableView : ExtendedTableView
|
||||
{
|
||||
public FormTableView()
|
||||
public FormTableView(EnvironmentPage page)
|
||||
{
|
||||
Intent = TableIntent.Settings;
|
||||
EnableScrolling = false;
|
||||
@ -267,6 +259,7 @@ namespace Bit.App.Pages
|
||||
EnableSelection = true;
|
||||
VerticalOptions = LayoutOptions.Start;
|
||||
NoFooter = true;
|
||||
WrappingStackLayout = () => page.StackLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,12 +67,14 @@ namespace Bit.App.Pages
|
||||
Uppercase = false
|
||||
};
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
var stackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Spacing = 10,
|
||||
Children = { table, logoutButton }
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => stackLayout;
|
||||
|
||||
var scrollView = new ScrollView { Content = stackLayout };
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
|
@ -71,7 +71,6 @@ namespace Bit.App.Pages
|
||||
HasUnevenRows = true,
|
||||
EnableSelection = true,
|
||||
NoFooter = true,
|
||||
//NoHeader = true,
|
||||
VerticalOptions = LayoutOptions.Start,
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -87,18 +86,20 @@ namespace Bit.App.Pages
|
||||
{
|
||||
Text = AppResources.GetPasswordHint,
|
||||
Style = (Style)Application.Current.Resources["btn-primaryAccent"],
|
||||
Margin = new Thickness(15, 0, 15, 25),
|
||||
Command = new Command(async () => await ForgotPasswordAsync()),
|
||||
VerticalOptions = LayoutOptions.End,
|
||||
Uppercase = false,
|
||||
BackgroundColor = Color.Transparent
|
||||
};
|
||||
|
||||
var layout = new StackLayout
|
||||
var layout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { table, forgotPasswordButton },
|
||||
Spacing = Helpers.OnPlatform(iOS: 0, Android: 10, Windows: 0)
|
||||
Spacing = 10
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => layout;
|
||||
|
||||
var scrollView = new ScrollView { Content = layout };
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
|
@ -135,12 +135,13 @@ namespace Bit.App.Pages
|
||||
RememberCell
|
||||
});
|
||||
|
||||
var layout = new StackLayout
|
||||
var layout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { instruction, table },
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => layout;
|
||||
scrollView.Content = layout;
|
||||
|
||||
switch(_providerType.Value)
|
||||
@ -213,12 +214,13 @@ namespace Bit.App.Pages
|
||||
RememberCell
|
||||
});
|
||||
|
||||
var layout = new StackLayout
|
||||
var layout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { webView, table, anotherMethodButton },
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => layout;
|
||||
scrollView.Content = layout;
|
||||
|
||||
Title = "Duo";
|
||||
@ -244,12 +246,13 @@ namespace Bit.App.Pages
|
||||
RememberCell
|
||||
});
|
||||
|
||||
var layout = new StackLayout
|
||||
var layout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { instruction, image, table, anotherMethodButton },
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => layout;
|
||||
scrollView.Content = layout;
|
||||
|
||||
Title = AppResources.YubiKeyTitle;
|
||||
@ -524,7 +527,7 @@ namespace Bit.App.Pages
|
||||
NoFooter = true;
|
||||
NoHeader = true;
|
||||
VerticalOptions = LayoutOptions.Start;
|
||||
Root = Root = new TableRoot
|
||||
Root = new TableRoot
|
||||
{
|
||||
section
|
||||
};
|
||||
|
@ -64,12 +64,13 @@ namespace Bit.App.Pages
|
||||
Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 25)
|
||||
};
|
||||
|
||||
var layout = new StackLayout
|
||||
var layout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { table, hintLabel },
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => layout;
|
||||
var scrollView = new ScrollView { Content = layout };
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
|
@ -35,7 +35,7 @@ namespace Bit.App.Pages
|
||||
public FormEntryCell PasswordCell { get; set; }
|
||||
public FormEntryCell ConfirmPasswordCell { get; set; }
|
||||
public FormEntryCell PasswordHintCell { get; set; }
|
||||
public StackLayout StackLayout { get; set; }
|
||||
public RedrawableStackLayout StackLayout { get; set; }
|
||||
public Label PasswordLabel { get; set; }
|
||||
public Label HintLabel { get; set; }
|
||||
|
||||
@ -62,7 +62,7 @@ namespace Bit.App.Pages
|
||||
|
||||
PasswordHintCell.Entry.ReturnType = Enums.ReturnType.Done;
|
||||
|
||||
var table = new FormTableView
|
||||
var table = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -83,7 +83,7 @@ namespace Bit.App.Pages
|
||||
Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 25)
|
||||
};
|
||||
|
||||
var table2 = new FormTableView
|
||||
var table2 = new FormTableView(this)
|
||||
{
|
||||
NoHeader = true,
|
||||
Root = new TableRoot
|
||||
@ -105,7 +105,7 @@ namespace Bit.App.Pages
|
||||
Margin = new Thickness(15, (this.IsLandscape() ? 5 : 0), 15, 25)
|
||||
};
|
||||
|
||||
StackLayout = new StackLayout
|
||||
StackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { table, PasswordLabel, table2, HintLabel },
|
||||
Spacing = 0
|
||||
@ -145,7 +145,6 @@ namespace Bit.App.Pages
|
||||
PasswordHintCell.InitEvents();
|
||||
ConfirmPasswordCell.InitEvents();
|
||||
PasswordHintCell.Entry.Completed += Entry_Completed;
|
||||
StackLayout.LayoutChanged += Layout_LayoutChanged;
|
||||
EmailCell.Entry.FocusWithDelay();
|
||||
}
|
||||
protected override void OnDisappearing()
|
||||
@ -156,13 +155,6 @@ namespace Bit.App.Pages
|
||||
PasswordHintCell.Dispose();
|
||||
ConfirmPasswordCell.Dispose();
|
||||
PasswordHintCell.Entry.Completed -= Entry_Completed;
|
||||
StackLayout.LayoutChanged -= Layout_LayoutChanged;
|
||||
}
|
||||
|
||||
private void Layout_LayoutChanged(object sender, EventArgs e)
|
||||
{
|
||||
PasswordLabel.WidthRequest = StackLayout.Bounds.Width - PasswordLabel.Bounds.Left * 2;
|
||||
HintLabel.WidthRequest = StackLayout.Bounds.Width - HintLabel.Bounds.Left * 2;
|
||||
}
|
||||
|
||||
private async void Entry_Completed(object sender, EventArgs e)
|
||||
@ -229,7 +221,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private class FormTableView : ExtendedTableView
|
||||
{
|
||||
public FormTableView()
|
||||
public FormTableView(RegisterPage page)
|
||||
{
|
||||
Intent = TableIntent.Settings;
|
||||
EnableScrolling = false;
|
||||
@ -237,6 +229,7 @@ namespace Bit.App.Pages
|
||||
EnableSelection = true;
|
||||
VerticalOptions = LayoutOptions.Start;
|
||||
NoFooter = true;
|
||||
WrappingStackLayout = () => page.StackLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,12 +73,14 @@ namespace Bit.App.Pages
|
||||
table.EstimatedRowHeight = 44;
|
||||
}
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
var stackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { logoVersionStackLayout, table },
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => stackLayout;
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS || Device.RuntimePlatform == Device.UWP)
|
||||
{
|
||||
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Close));
|
||||
|
@ -50,9 +50,7 @@ namespace Bit.App.Pages
|
||||
var mainTable = new ExtendedTableView
|
||||
{
|
||||
Intent = TableIntent.Settings,
|
||||
EnableScrolling = false,
|
||||
HasUnevenRows = true,
|
||||
VerticalOptions = LayoutOptions.Start,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection(Helpers.GetEmptyTableSectionTitle())
|
||||
|
@ -22,7 +22,7 @@ namespace Bit.App.Pages
|
||||
public ExtendedTextCell EmailCell { get; set; }
|
||||
public ExtendedTextCell WebsiteCell { get; set; }
|
||||
public ExtendedTextCell BugCell { get; set; }
|
||||
public StackLayout StackLayout { get; set; }
|
||||
public RedrawableStackLayout StackLayout { get; set; }
|
||||
private CustomLabel EmailLabel { get; set; }
|
||||
private CustomLabel WebsiteLabel { get; set; }
|
||||
private CustomLabel BugLabel { get; set; }
|
||||
@ -35,7 +35,7 @@ namespace Bit.App.Pages
|
||||
ShowDisclousure = true
|
||||
};
|
||||
|
||||
var emailTable = new CustomTableView
|
||||
var emailTable = new CustomTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace Bit.App.Pages
|
||||
ShowDisclousure = true
|
||||
};
|
||||
|
||||
var websiteTable = new CustomTableView
|
||||
var websiteTable = new CustomTableView(this)
|
||||
{
|
||||
NoHeader = true,
|
||||
Root = new TableRoot
|
||||
@ -80,7 +80,7 @@ namespace Bit.App.Pages
|
||||
ShowDisclousure = true
|
||||
};
|
||||
|
||||
var bugTable = new CustomTableView
|
||||
var bugTable = new CustomTableView(this)
|
||||
{
|
||||
NoHeader = true,
|
||||
Root = new TableRoot
|
||||
@ -97,7 +97,7 @@ namespace Bit.App.Pages
|
||||
Text = AppResources.FileBugReportDescription
|
||||
};
|
||||
|
||||
StackLayout = new StackLayout
|
||||
StackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Children = { emailTable, EmailLabel, websiteTable, WebsiteLabel, bugTable, BugLabel },
|
||||
Spacing = 0
|
||||
@ -118,7 +118,6 @@ namespace Bit.App.Pages
|
||||
EmailCell.Tapped += EmailCell_Tapped;
|
||||
WebsiteCell.Tapped += WebsiteCell_Tapped;
|
||||
BugCell.Tapped += BugCell_Tapped;
|
||||
StackLayout.LayoutChanged += StackLayout_LayoutChanged;
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
@ -127,14 +126,6 @@ namespace Bit.App.Pages
|
||||
EmailCell.Tapped -= EmailCell_Tapped;
|
||||
WebsiteCell.Tapped -= WebsiteCell_Tapped;
|
||||
BugCell.Tapped -= BugCell_Tapped;
|
||||
StackLayout.LayoutChanged -= StackLayout_LayoutChanged;
|
||||
}
|
||||
|
||||
private void StackLayout_LayoutChanged(object sender, EventArgs e)
|
||||
{
|
||||
WebsiteLabel.WidthRequest = StackLayout.Bounds.Width - WebsiteLabel.Bounds.Left * 2;
|
||||
EmailLabel.WidthRequest = StackLayout.Bounds.Width - EmailLabel.Bounds.Left * 2;
|
||||
BugLabel.WidthRequest = StackLayout.Bounds.Width - BugLabel.Bounds.Left * 2;
|
||||
}
|
||||
|
||||
private void EmailCell_Tapped(object sender, EventArgs e)
|
||||
@ -157,7 +148,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private class CustomTableView : ExtendedTableView
|
||||
{
|
||||
public CustomTableView()
|
||||
public CustomTableView(SettingsHelpPage page)
|
||||
{
|
||||
Intent = TableIntent.Settings;
|
||||
EnableScrolling = false;
|
||||
@ -165,6 +156,7 @@ namespace Bit.App.Pages
|
||||
EnableSelection = true;
|
||||
VerticalOptions = LayoutOptions.Start;
|
||||
NoFooter = true;
|
||||
WrappingStackLayout = () => page.StackLayout;
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ namespace Bit.App.Pages
|
||||
Init();
|
||||
}
|
||||
|
||||
private StackLayout StackLayout { get; set; }
|
||||
private RedrawableStackLayout StackLayout { get; set; }
|
||||
private ExtendedSwitchCell CopyTotpCell { get; set; }
|
||||
private Label CopyTotpLabel { get; set; }
|
||||
private ExtendedSwitchCell AnalyticsCell { get; set; }
|
||||
@ -46,7 +46,7 @@ namespace Bit.App.Pages
|
||||
On = _appSettings.DisableWebsiteIcons
|
||||
};
|
||||
|
||||
var websiteIconsTable = new FormTableView(true)
|
||||
var websiteIconsTable = new FormTableView(this, true)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -63,7 +63,7 @@ namespace Bit.App.Pages
|
||||
On = _settings.GetValueOrDefault(Constants.SettingDisableTotpCopy, false)
|
||||
};
|
||||
|
||||
var totpTable = new FormTableView
|
||||
var totpTable = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -80,7 +80,7 @@ namespace Bit.App.Pages
|
||||
On = _settings.GetValueOrDefault(Constants.SettingGaOptOut, false)
|
||||
};
|
||||
|
||||
var analyticsTable = new FormTableView
|
||||
var analyticsTable = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -106,7 +106,7 @@ namespace Bit.App.Pages
|
||||
Text = AppResources.DisableWebsiteIconsDescription
|
||||
};
|
||||
|
||||
StackLayout = new StackLayout
|
||||
StackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Children =
|
||||
{
|
||||
@ -125,7 +125,7 @@ namespace Bit.App.Pages
|
||||
On = !_appSettings.AutofillPersistNotification && !_appSettings.AutofillPasswordField
|
||||
};
|
||||
|
||||
var autofillAlwaysTable = new FormTableView(true)
|
||||
var autofillAlwaysTable = new FormTableView(this, true)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -147,7 +147,7 @@ namespace Bit.App.Pages
|
||||
On = _appSettings.AutofillPersistNotification
|
||||
};
|
||||
|
||||
var autofillPersistNotificationTable = new FormTableView
|
||||
var autofillPersistNotificationTable = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -169,7 +169,7 @@ namespace Bit.App.Pages
|
||||
On = _appSettings.AutofillPasswordField
|
||||
};
|
||||
|
||||
var autofillPasswordFieldTable = new FormTableView
|
||||
var autofillPasswordFieldTable = new FormTableView(this)
|
||||
{
|
||||
Root = new TableRoot
|
||||
{
|
||||
@ -217,7 +217,6 @@ namespace Bit.App.Pages
|
||||
AnalyticsCell.OnChanged += AnalyticsCell_Changed;
|
||||
WebsiteIconsCell.OnChanged += WebsiteIconsCell_Changed;
|
||||
CopyTotpCell.OnChanged += CopyTotpCell_OnChanged;
|
||||
StackLayout.LayoutChanged += Layout_LayoutChanged;
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
@ -234,7 +233,6 @@ namespace Bit.App.Pages
|
||||
AnalyticsCell.OnChanged -= AnalyticsCell_Changed;
|
||||
WebsiteIconsCell.OnChanged -= WebsiteIconsCell_Changed;
|
||||
CopyTotpCell.OnChanged -= CopyTotpCell_OnChanged;
|
||||
StackLayout.LayoutChanged -= Layout_LayoutChanged;
|
||||
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
@ -244,29 +242,6 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private void Layout_LayoutChanged(object sender, EventArgs e)
|
||||
{
|
||||
AnalyticsLabel.WidthRequest = StackLayout.Bounds.Width - AnalyticsLabel.Bounds.Left * 2;
|
||||
WebsiteIconsLabel.WidthRequest = StackLayout.Bounds.Width - WebsiteIconsLabel.Bounds.Left * 2;
|
||||
CopyTotpLabel.WidthRequest = StackLayout.Bounds.Width - CopyTotpLabel.Bounds.Left * 2;
|
||||
|
||||
if(AutofillAlwaysLabel != null)
|
||||
{
|
||||
AutofillAlwaysLabel.WidthRequest = StackLayout.Bounds.Width - AutofillAlwaysLabel.Bounds.Left * 2;
|
||||
}
|
||||
|
||||
if(AutofillPasswordFieldLabel != null)
|
||||
{
|
||||
AutofillPasswordFieldLabel.WidthRequest = StackLayout.Bounds.Width - AutofillPasswordFieldLabel.Bounds.Left * 2;
|
||||
}
|
||||
|
||||
if(AutofillPersistNotificationLabel != null)
|
||||
{
|
||||
AutofillPersistNotificationLabel.WidthRequest =
|
||||
StackLayout.Bounds.Width - AutofillPersistNotificationLabel.Bounds.Left * 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void WebsiteIconsCell_Changed(object sender, ToggledEventArgs e)
|
||||
{
|
||||
var cell = sender as ExtendedSwitchCell;
|
||||
@ -352,7 +327,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private class FormTableView : ExtendedTableView
|
||||
{
|
||||
public FormTableView(bool header = false)
|
||||
public FormTableView(SettingsOptionsPage page, bool header = false)
|
||||
{
|
||||
Intent = TableIntent.Settings;
|
||||
EnableScrolling = false;
|
||||
@ -361,6 +336,7 @@ namespace Bit.App.Pages
|
||||
VerticalOptions = LayoutOptions.Start;
|
||||
NoFooter = true;
|
||||
NoHeader = !header;
|
||||
WrappingStackLayout = () => page.StackLayout;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ namespace Bit.App.Pages
|
||||
table.BottomPadding = 50;
|
||||
}
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
var stackLayout = new RedrawableStackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Vertical,
|
||||
Children = { Password, table },
|
||||
@ -171,6 +171,8 @@ namespace Bit.App.Pages
|
||||
Spacing = 0
|
||||
};
|
||||
|
||||
table.WrappingStackLayout = () => stackLayout;
|
||||
|
||||
var scrollView = new ScrollView
|
||||
{
|
||||
Content = stackLayout,
|
||||
|
@ -44,7 +44,7 @@ namespace Bit.App.Pages
|
||||
public ExtendedObservableCollection<VaultAttachmentsPageModel.Attachment> PresentationAttchments { get; private set; }
|
||||
= new ExtendedObservableCollection<VaultAttachmentsPageModel.Attachment>();
|
||||
public ExtendedListView ListView { get; set; }
|
||||
public StackLayout NoDataStackLayout { get; set; }
|
||||
public RedrawableStackLayout NoDataStackLayout { get; set; }
|
||||
public StackLayout AddNewStackLayout { get; set; }
|
||||
public Label FileLabel { get; set; }
|
||||
public ExtendedTableView NewTable { get; set; }
|
||||
@ -88,6 +88,7 @@ namespace Bit.App.Pages
|
||||
EnableSelection = false,
|
||||
VerticalOptions = LayoutOptions.Start,
|
||||
Margin = new Thickness(0, Helpers.OnPlatform(iOS: 10, Android: 30), 0, 0),
|
||||
WrappingStackLayout = () => NoDataStackLayout,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection(AppResources.AddNewAttachment)
|
||||
@ -122,7 +123,7 @@ namespace Bit.App.Pages
|
||||
Style = (Style)Application.Current.Resources["text-muted"]
|
||||
};
|
||||
|
||||
NoDataStackLayout = new StackLayout
|
||||
NoDataStackLayout = new RedrawableStackLayout
|
||||
{
|
||||
VerticalOptions = LayoutOptions.Start,
|
||||
Spacing = 0,
|
||||
|
@ -36,6 +36,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
public ToolbarItem SaveToolbarItem { get; set; }
|
||||
public ToolbarItem CloseToolbarItem { get; set; }
|
||||
public Label NoDataLabel { get; set; }
|
||||
public TableSection FieldsSection { get; set; }
|
||||
public ExtendedTableView Table { get; set; }
|
||||
@ -131,12 +132,16 @@ namespace Bit.App.Pages
|
||||
await DisplayAlert(null, AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
}
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
ToolbarItems.Add(SaveToolbarItem);
|
||||
|
||||
Title = AppResources.CustomFields;
|
||||
Content = Table;
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
CloseToolbarItem = new DismissModalToolBarItem(this, AppResources.Close);
|
||||
ToolbarItems.Add(CloseToolbarItem);
|
||||
|
||||
Table.RowHeight = -1;
|
||||
Table.EstimatedRowHeight = 44;
|
||||
}
|
||||
@ -157,13 +162,14 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
if(_cipher.Fields != null && _cipher.Fields.Any())
|
||||
var hasFields = _cipher.Fields?.Any() ?? false;
|
||||
|
||||
if(hasFields)
|
||||
{
|
||||
Content = Table;
|
||||
ToolbarItems.Add(SaveToolbarItem);
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
if(CloseToolbarItem != null)
|
||||
{
|
||||
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Cancel));
|
||||
CloseToolbarItem.Text = AppResources.Cancel;
|
||||
}
|
||||
|
||||
foreach(var field in _cipher.Fields)
|
||||
@ -189,7 +195,7 @@ namespace Bit.App.Pages
|
||||
textFieldCell.Button.Command = new Command(() =>
|
||||
{
|
||||
textFieldCell.Entry.InvokeToggleIsPassword();
|
||||
textFieldCell.Button.Image =
|
||||
textFieldCell.Button.Image =
|
||||
"eye" + (!textFieldCell.Entry.IsPasswordFromToggled ? "_slash" : string.Empty) + ".png";
|
||||
});
|
||||
}
|
||||
@ -213,9 +219,9 @@ namespace Bit.App.Pages
|
||||
else
|
||||
{
|
||||
Content = NoDataLabel;
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
if(ToolbarItems.Count > 0)
|
||||
{
|
||||
ToolbarItems.Add(new DismissModalToolBarItem(this, AppResources.Close));
|
||||
ToolbarItems.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace Bit.iOS.Controls
|
||||
private void SetSource()
|
||||
{
|
||||
var view = (ExtendedTableView)Element;
|
||||
if(view.NoFooter || view.NoHeader)
|
||||
if(true || view.NoFooter || view.NoHeader)
|
||||
{
|
||||
Control.Source = new CustomTableViewModelRenderer(view);
|
||||
}
|
||||
@ -116,6 +116,7 @@ namespace Bit.iOS.Controls
|
||||
public class CustomTableViewModelRenderer : UnEvenTableViewModelRenderer
|
||||
{
|
||||
private readonly ExtendedTableView _view;
|
||||
private bool _didRedraw = false;
|
||||
|
||||
public CustomTableViewModelRenderer(ExtendedTableView model)
|
||||
: base(model)
|
||||
@ -123,6 +124,16 @@ namespace Bit.iOS.Controls
|
||||
_view = model;
|
||||
}
|
||||
|
||||
public override async void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
|
||||
{
|
||||
// ref https://stackoverflow.com/a/48076188/1090359
|
||||
if(!_didRedraw && _view.WrappingStackLayout != null)
|
||||
{
|
||||
_didRedraw = true;
|
||||
await _view.WrappingStackLayout()?.RedrawIfNeededAsync(10, false);
|
||||
}
|
||||
}
|
||||
|
||||
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if(_view.HasUnevenRows)
|
||||
@ -143,6 +154,16 @@ namespace Bit.iOS.Controls
|
||||
return base.GetHeightForHeader(tableView, section);
|
||||
}
|
||||
|
||||
public override UIView GetViewForHeader(UITableView tableView, nint section)
|
||||
{
|
||||
if(_view.NoHeader && section == 0)
|
||||
{
|
||||
return new UIView(new CGRect(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override nfloat GetHeightForFooter(UITableView tableView, nint section)
|
||||
{
|
||||
if(_view.NoFooter && (section + 1) == NumberOfSections(tableView))
|
||||
@ -152,6 +173,16 @@ namespace Bit.iOS.Controls
|
||||
|
||||
return 10f;
|
||||
}
|
||||
|
||||
public override UIView GetViewForFooter(UITableView tableView, nint section)
|
||||
{
|
||||
if(_view.NoFooter && (section + 1) == NumberOfSections(tableView))
|
||||
{
|
||||
return new UIView(new CGRect(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user