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