diff --git a/src/Android/Resources/Resource.Designer.cs b/src/Android/Resources/Resource.Designer.cs index 8677cf1ee..cfc2115d4 100644 --- a/src/Android/Resources/Resource.Designer.cs +++ b/src/Android/Resources/Resource.Designer.cs @@ -4375,17 +4375,17 @@ namespace Bit.Android // aapt resource value: 0x7f090051 public const int ApplicationName = 2131296337; - // aapt resource value: 0x7f0900ab - public const int AutoFillServiceDescription = 2131296427; + // aapt resource value: 0x7f0900b2 + public const int AutoFillServiceDescription = 2131296434; - // aapt resource value: 0x7f0900aa - public const int AutoFillServiceSummary = 2131296426; + // aapt resource value: 0x7f0900b1 + public const int AutoFillServiceSummary = 2131296433; // aapt resource value: 0x7f090050 public const int Hello = 2131296336; - // aapt resource value: 0x7f0900ac - public const int MyVault = 2131296428; + // aapt resource value: 0x7f0900b3 + public const int MyVault = 2131296435; // aapt resource value: 0x7f090027 public const int abc_action_bar_home_description = 2131296295; @@ -4540,6 +4540,27 @@ namespace Bit.Android // aapt resource value: 0x7f09000f public const int common_signin_button_text_long = 2131296271; + // aapt resource value: 0x7f0900ac + public const int default_web_client_id = 2131296428; + + // aapt resource value: 0x7f0900ad + public const int firebase_database_url = 2131296429; + + // aapt resource value: 0x7f0900aa + public const int gcm_defaultSenderId = 2131296426; + + // aapt resource value: 0x7f0900ae + public const int google_api_key = 2131296430; + + // aapt resource value: 0x7f0900ab + public const int google_app_id = 2131296427; + + // aapt resource value: 0x7f0900af + public const int google_crash_reporting_api_key = 2131296431; + + // aapt resource value: 0x7f0900b0 + public const int google_storage_bucket = 2131296432; + // aapt resource value: 0x7f090052 public const int hockeyapp_crash_dialog_app_name_fallback = 2131296338; diff --git a/src/iOS.Core/Views/Toast.cs b/src/iOS.Core/Views/Toast.cs new file mode 100644 index 000000000..f3f33f3da --- /dev/null +++ b/src/iOS.Core/Views/Toast.cs @@ -0,0 +1,135 @@ +using Foundation; +using System; +using UIKit; + +namespace Bit.iOS.Core.Views +{ + public class Toast : UIView + { + // Timer to dismiss the snack bar. + private NSTimer _dismissTimer; + + // Constraints. + private NSLayoutConstraint _heightConstraint; + private NSLayoutConstraint _leftMarginConstraint; + private NSLayoutConstraint _rightMarginConstraint; + private NSLayoutConstraint _topMarginConstraint; + private NSLayoutConstraint _bottomMarginConstraint; + + public Toast(string text) : base(CoreGraphics.CGRect.FromLTRB(0, 0, 320, 44)) + { + TranslatesAutoresizingMaskIntoConstraints = false; + BackgroundColor = UIColor.DarkGray; + Layer.CornerRadius = 4; + Layer.MasksToBounds = true; + + MessageLabel = new UILabel + { + TranslatesAutoresizingMaskIntoConstraints = false, + TextColor = UIColor.White, + Font = UIFont.SystemFontOfSize(14), + BackgroundColor = UIColor.Clear, + LineBreakMode = UILineBreakMode.WordWrap, + TextAlignment = UITextAlignment.Center, + Lines = 0 + }; + + var hConstraints = NSLayoutConstraint.FromVisualFormat("H:|-5-[messageLabel]-5-|", 0, new NSDictionary(), + NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel }, + new NSObject[] { new NSString("messageLabel") }) + ); + + var vMessageConstraints = NSLayoutConstraint.FromVisualFormat("V:|-0-[messageLabel]-0-|", 0, new NSDictionary(), + NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel }, + new NSObject[] { new NSString("messageLabel") }) + ); + + AddConstraints(hConstraints); + AddConstraints(vMessageConstraints); + AddSubview(MessageLabel); + } + + public TimeSpan Duration { get; set; } = TimeSpan.FromSeconds(3); + public UILabel MessageLabel { get; set; } + public nfloat LeftMargin { get; set; } = 4; + public nfloat RightMargin { get; set; } = 4; + public nfloat BottomMargin { get; set; } = 4; + public nfloat Height { get; set; } = 44; + public nfloat TopMargin { get; set; } = 8; + + public void Show() + { + if(Superview != null) + { + return; + } + + _dismissTimer = NSTimer.CreateScheduledTimer(Duration, x => Dismiss()); + LayoutIfNeeded(); + + var localSuperView = UIApplication.SharedApplication.KeyWindow; + if(localSuperView != null) + { + localSuperView.AddSubview(this); + + _heightConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, + NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, Height); + + _leftMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Left, NSLayoutRelation.Equal, + localSuperView, NSLayoutAttribute.Left, 1, LeftMargin); + + _rightMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Right, NSLayoutRelation.Equal, + localSuperView, NSLayoutAttribute.Right, 1, -RightMargin); + + _bottomMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, + localSuperView, NSLayoutAttribute.Bottom, 1, -BottomMargin); + + // Avoid the "UIView-Encapsulated-Layout-Height" constraint conflicts + // http://stackoverflow.com/questions/25059443/what-is-nslayoutconstraint-uiview-encapsulated-layout-height-and-how-should-i + _leftMarginConstraint.Priority = 999; + _rightMarginConstraint.Priority = 999; + + AddConstraint(_heightConstraint); + localSuperView.AddConstraint(_leftMarginConstraint); + localSuperView.AddConstraint(_rightMarginConstraint); + localSuperView.AddConstraint(_bottomMarginConstraint); + + // Show + ShowWithAnimation(); + } + else + { + Console.WriteLine("Toast needs a keyWindows to display."); + } + } + + public void Dismiss(bool animated = true) + { + _dismissTimer?.Invalidate(); + _dismissTimer = null; + nfloat superViewWidth = 0; + + if(Superview != null) + { + superViewWidth = Superview.Frame.Width; + } + + if(!animated) + { + RemoveFromSuperview(); + return; + } + + SetNeedsLayout(); + Animate(0.3f, 0, UIViewAnimationOptions.CurveEaseIn, () => { Alpha = 0; }, RemoveFromSuperview); + } + + private void ShowWithAnimation() + { + _bottomMarginConstraint.Constant = -BottomMargin; + _leftMarginConstraint.Constant = LeftMargin; + _rightMarginConstraint.Constant = -RightMargin; + AnimateNotify(0.3f, 0, 0.7f, 5f, UIViewAnimationOptions.CurveEaseInOut, () => { Alpha = 0; }, null); + } + } +} diff --git a/src/iOS.Core/iOS.Core.csproj b/src/iOS.Core/iOS.Core.csproj index 9715d1f20..d4beb32b9 100644 --- a/src/iOS.Core/iOS.Core.csproj +++ b/src/iOS.Core/iOS.Core.csproj @@ -63,6 +63,7 @@ + diff --git a/src/iOS/Services/DeviceActionService.cs b/src/iOS/Services/DeviceActionService.cs index f1c592449..c34fb0076 100644 --- a/src/iOS/Services/DeviceActionService.cs +++ b/src/iOS/Services/DeviceActionService.cs @@ -10,6 +10,7 @@ using Photos; using System.Net; using System.Threading.Tasks; using Bit.App.Models.Page; +using Bit.iOS.Core.Views; namespace Bit.iOS.Services { @@ -28,12 +29,10 @@ namespace Bit.iOS.Services public void Toast(string text, bool longDuration = false) { - var snackbar = new TTGSnackBar.TTGSnackbar(text) + new Toast(text) { - Duration = TimeSpan.FromSeconds(longDuration ? 5 : 2), - AnimationType = TTGSnackBar.TTGSnackbarAnimationType.FadeInFadeOut - }; - snackbar.Show(); + Duration = TimeSpan.FromSeconds(longDuration ? 5 : 3) + }.Show(); } public void CopyToClipboard(string text) diff --git a/src/iOS/iOS.csproj b/src/iOS/iOS.csproj index 39fa2d3d3..2d3e70ea8 100644 --- a/src/iOS/iOS.csproj +++ b/src/iOS/iOS.csproj @@ -704,9 +704,6 @@ 4.0.12 - - 1.3.4 - 3.17.0.1