diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj
index bd6d887f1..38bb0393d 100644
--- a/src/Android/Android.csproj
+++ b/src/Android/Android.csproj
@@ -58,7 +58,7 @@
1.1.0
-
+
diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs
index a64760c3d..c7a6cf1f4 100644
--- a/src/Android/MainApplication.cs
+++ b/src/Android/MainApplication.cs
@@ -39,6 +39,8 @@ namespace Bit.Droid
private void RegisterLocalServices()
{
+ FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true);
+
var preferencesStorage = new PreferencesStorageService(null);
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db"));
diff --git a/src/App/App.csproj b/src/App/App.csproj
index 4207c0b6b..d80d75b04 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -13,7 +13,8 @@
-
+
+
diff --git a/src/App/Controls/CipherViewCell/CipherViewCell.xaml b/src/App/Controls/CipherViewCell/CipherViewCell.xaml
index 120879404..3dc3e0cee 100644
--- a/src/App/Controls/CipherViewCell/CipherViewCell.xaml
+++ b/src/App/Controls/CipherViewCell/CipherViewCell.xaml
@@ -2,21 +2,82 @@
+ xmlns:controls="clr-namespace:Bit.App.Controls"
+ xmlns:ff="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms">
-
-
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Controls/CipherViewCell/CipherViewCell.xaml.cs b/src/App/Controls/CipherViewCell/CipherViewCell.xaml.cs
index 9a77b5ebb..8a0c62949 100644
--- a/src/App/Controls/CipherViewCell/CipherViewCell.xaml.cs
+++ b/src/App/Controls/CipherViewCell/CipherViewCell.xaml.cs
@@ -1,4 +1,9 @@
-using Bit.Core.Models.View;
+using Bit.App.Pages;
+using Bit.Core;
+using Bit.Core.Enums;
+using Bit.Core.Models.View;
+using Bit.Core.Utilities;
+using System;
using Xamarin.Forms;
namespace Bit.App.Controls
@@ -13,7 +18,7 @@ namespace Bit.App.Controls
public CipherViewCell()
{
InitializeComponent();
- _viewModel = _layout.BindingContext as CipherViewCellViewModel;
+ _viewModel = _grid.BindingContext as CipherViewCellViewModel;
}
public CipherView Cipher
@@ -30,5 +35,88 @@ namespace Bit.App.Controls
_viewModel.Cipher = Cipher;
}
}
+
+ protected override void OnBindingContextChanged()
+ {
+ string icon = null;
+ string image = null;
+
+ _image.Source = null;
+ if(BindingContext is GroupingsPageListItem groupingsPageListItem && groupingsPageListItem.Cipher != null)
+ {
+ switch(groupingsPageListItem.Cipher.Type)
+ {
+ case CipherType.Login:
+ var loginIconImage = GetLoginIconImage(groupingsPageListItem.Cipher);
+ icon = loginIconImage.Item1;
+ image = loginIconImage.Item2;
+ break;
+ case CipherType.SecureNote:
+ icon = "";
+ break;
+ case CipherType.Card:
+ icon = "";
+ break;
+ case CipherType.Identity:
+ icon = "";
+ break;
+ default:
+ break;
+ }
+
+ if(image != null)
+ {
+ _image.IsVisible = true;
+ _icon.IsVisible = false;
+ _image.Source = image;
+ _image.LoadingPlaceholder = "login.png";
+ }
+ else
+ {
+ _image.IsVisible = false;
+ _icon.IsVisible = true;
+ _icon.Text = icon;
+ }
+ }
+ base.OnBindingContextChanged();
+ }
+
+ private Tuple GetLoginIconImage(CipherView cipher)
+ {
+ string icon = "";
+ string image = null;
+ var imageEnabled = true;
+ if(cipher.Login.Uri != null)
+ {
+ var hostnameUri = cipher.Login.Uri;
+ var isWebsite = false;
+
+ if(hostnameUri.StartsWith(Constants.AndroidAppProtocol))
+ {
+ icon = "";
+ }
+ else if(hostnameUri.StartsWith(Constants.iOSAppProtocol))
+ {
+ icon = "";
+ }
+ else if(imageEnabled && !hostnameUri.Contains("://") && hostnameUri.Contains("."))
+ {
+ hostnameUri = string.Concat("http://", hostnameUri);
+ isWebsite = true;
+ }
+ else if(imageEnabled)
+ {
+ isWebsite = hostnameUri.StartsWith("http") && hostnameUri.Contains(".");
+ }
+
+ if(imageEnabled && isWebsite)
+ {
+ var hostname = CoreHelpers.GetHostname(hostnameUri);
+ var iconsUrl = "https://icons.bitwarden.net";
+ image = string.Format("{0}/{1}/icon.png", iconsUrl, hostname);
+ }
+ }
+ return new Tuple(icon, image);
+ }
}
}
diff --git a/src/App/Pages/GroupingsPage/GroupingsPage.xaml b/src/App/Pages/GroupingsPage/GroupingsPage.xaml
index 063e96e44..64e894d77 100644
--- a/src/App/Pages/GroupingsPage/GroupingsPage.xaml
+++ b/src/App/Pages/GroupingsPage/GroupingsPage.xaml
@@ -22,8 +22,8 @@
x:DataType="pages:GroupingsPageListItem">
-
+
@@ -40,8 +40,8 @@
x:DataType="pages:GroupingsPageListItem">
-
+
@@ -72,13 +72,13 @@
CachingStrategy="RecycleElement"
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
IsGroupingEnabled="True"
- StyleClass="list">
+ StyleClass="list, list-platform">
+ StyleClass="list-header, list-header-platform" />
diff --git a/src/App/Pages/GroupingsPage/GroupingsPageListItem.cs b/src/App/Pages/GroupingsPage/GroupingsPageListItem.cs
index c0adddcb9..acdba5124 100644
--- a/src/App/Pages/GroupingsPage/GroupingsPageListItem.cs
+++ b/src/App/Pages/GroupingsPage/GroupingsPageListItem.cs
@@ -4,8 +4,29 @@ namespace Bit.App.Pages
{
public class GroupingsPageListItem
{
+ private string _icon;
+
public FolderView Folder { get; set; }
public CollectionView Collection { get; set; }
public CipherView Cipher { get; set; }
+ public string Icon
+ {
+ get
+ {
+ if(_icon != null)
+ {
+ return _icon;
+ }
+ if(Folder != null)
+ {
+ _icon = Folder.Id == null ? "" : "";
+ }
+ else if(Collection != null)
+ {
+ _icon = "";
+ }
+ return _icon;
+ }
+ }
}
}
diff --git a/src/App/Pages/GroupingsPage/GroupingsPageViewModel.cs b/src/App/Pages/GroupingsPage/GroupingsPageViewModel.cs
index 03732a8e6..149f2a625 100644
--- a/src/App/Pages/GroupingsPage/GroupingsPageViewModel.cs
+++ b/src/App/Pages/GroupingsPage/GroupingsPageViewModel.cs
@@ -78,15 +78,18 @@ namespace Bit.App.Pages
var groupedItems = new List();
if(favListItems?.Any() ?? false)
{
- groupedItems.Add(new GroupingsPageListGroup(favListItems, AppResources.Favorites));
+ groupedItems.Add(new GroupingsPageListGroup(favListItems, AppResources.Favorites,
+ Device.RuntimePlatform == Device.iOS));
}
if(folderListItems?.Any() ?? false)
{
- groupedItems.Add(new GroupingsPageListGroup(folderListItems, AppResources.Folders));
+ groupedItems.Add(new GroupingsPageListGroup(folderListItems, AppResources.Folders,
+ Device.RuntimePlatform == Device.iOS));
}
if(collectionListItems?.Any() ?? false)
{
- groupedItems.Add(new GroupingsPageListGroup(collectionListItems, AppResources.Collections));
+ groupedItems.Add(new GroupingsPageListGroup(collectionListItems, AppResources.Collections,
+ Device.RuntimePlatform == Device.iOS));
}
GroupedItems.ResetWithRange(groupedItems);
}
diff --git a/src/App/Styles/Android.xaml b/src/App/Styles/Android.xaml
index 51cef2d7e..661375a15 100644
--- a/src/App/Styles/Android.xaml
+++ b/src/App/Styles/Android.xaml
@@ -2,9 +2,24 @@
+
+
+
diff --git a/src/App/Styles/Base.xaml b/src/App/Styles/Base.xaml
index c60651157..3ba794791 100644
--- a/src/App/Styles/Base.xaml
+++ b/src/App/Styles/Base.xaml
@@ -2,40 +2,64 @@
+
+
+
+
+
+
+
diff --git a/src/App/Styles/Dark.xaml b/src/App/Styles/Dark.xaml
index cb6597405..002c99656 100644
--- a/src/App/Styles/Dark.xaml
+++ b/src/App/Styles/Dark.xaml
@@ -8,4 +8,5 @@
#00a65a
#555555
#bf7e16
+ #777777
diff --git a/src/App/Styles/Light.xaml b/src/App/Styles/Light.xaml
index e59776fe0..f9ee1effb 100644
--- a/src/App/Styles/Light.xaml
+++ b/src/App/Styles/Light.xaml
@@ -8,6 +8,7 @@
#00a65a
#555555
#bf7e16
+ #777777
#3c8dbc
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index 2f216c948..575244ce3 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -21,7 +21,7 @@
-
+
diff --git a/src/Core/Models/View/CipherView.cs b/src/Core/Models/View/CipherView.cs
index d12e68d0e..1ca6c3f90 100644
--- a/src/Core/Models/View/CipherView.cs
+++ b/src/Core/Models/View/CipherView.cs
@@ -66,6 +66,7 @@ namespace Bit.Core.Models.View
}
}
+ public bool Shared => OrganizationId != null;
public bool HasPasswordHistory => PasswordHistory?.Any() ?? false;
public bool HasAttachments => Attachments?.Any() ?? false;
public bool HasOldAttachments
diff --git a/src/iOS.Core/iOS.Core.csproj b/src/iOS.Core/iOS.Core.csproj
index dafb4a06d..ad5651b9d 100644
--- a/src/iOS.Core/iOS.Core.csproj
+++ b/src/iOS.Core/iOS.Core.csproj
@@ -35,7 +35,7 @@
- ..\..\packages\Newtonsoft.Json.12.0.1\lib\netstandard2.0\Newtonsoft.Json.dll
+ ..\..\packages\Newtonsoft.Json.12.0.2\lib\netstandard2.0\Newtonsoft.Json.dll
diff --git a/src/iOS.Core/packages.config b/src/iOS.Core/packages.config
index dabb475f5..c42689034 100644
--- a/src/iOS.Core/packages.config
+++ b/src/iOS.Core/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs
index d7c13bda7..eeec3ecaa 100644
--- a/src/iOS/AppDelegate.cs
+++ b/src/iOS/AppDelegate.cs
@@ -23,6 +23,9 @@ namespace Bit.iOS
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Xamarin.Forms.Forms.Init();
+
+ FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
+
LoadApplication(new App.App());
return base.FinishedLaunching(app, options);
diff --git a/src/iOS/iOS.csproj b/src/iOS/iOS.csproj
index cfbd44397..91bc3a494 100644
--- a/src/iOS/iOS.csproj
+++ b/src/iOS/iOS.csproj
@@ -153,7 +153,7 @@
1.1.0
-
+