diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj index bc82b71de..3ef96d99b 100644 --- a/src/Android/Android.csproj +++ b/src/Android/Android.csproj @@ -920,6 +920,21 @@ + + + + + + + + + + + + + + + diff --git a/src/Android/Resources/Resource.Designer.cs b/src/Android/Resources/Resource.Designer.cs index 7891cb06b..76e05e615 100644 --- a/src/Android/Resources/Resource.Designer.cs +++ b/src/Android/Resources/Resource.Designer.cs @@ -2756,53 +2756,56 @@ namespace Bit.Android // aapt resource value: 0x7f0200e6 public const int notification_sm = 2130837734; - // aapt resource value: 0x7f0200f6 - public const int notification_template_icon_bg = 2130837750; + // aapt resource value: 0x7f0200f7 + public const int notification_template_icon_bg = 2130837751; // aapt resource value: 0x7f0200e7 - public const int plus = 2130837735; + public const int paperclip = 2130837735; // aapt resource value: 0x7f0200e8 - public const int refresh = 2130837736; + public const int plus = 2130837736; // aapt resource value: 0x7f0200e9 - public const int roundedbg = 2130837737; + public const int refresh = 2130837737; // aapt resource value: 0x7f0200ea - public const int roundedbgdark = 2130837738; + public const int roundedbg = 2130837738; // aapt resource value: 0x7f0200eb - public const int search = 2130837739; + public const int roundedbgdark = 2130837739; // aapt resource value: 0x7f0200ec - public const int share = 2130837740; + public const int search = 2130837740; // aapt resource value: 0x7f0200ed - public const int share_tools = 2130837741; + public const int share = 2130837741; // aapt resource value: 0x7f0200ee - public const int splash_screen = 2130837742; + public const int share_tools = 2130837742; // aapt resource value: 0x7f0200ef - public const int star = 2130837743; + public const int splash_screen = 2130837743; // aapt resource value: 0x7f0200f0 - public const int star_selected = 2130837744; + public const int star = 2130837744; // aapt resource value: 0x7f0200f1 - public const int tools = 2130837745; + public const int star_selected = 2130837745; // aapt resource value: 0x7f0200f2 - public const int tools_selected = 2130837746; + public const int tools = 2130837746; // aapt resource value: 0x7f0200f3 - public const int upload = 2130837747; + public const int tools_selected = 2130837747; // aapt resource value: 0x7f0200f4 - public const int user = 2130837748; + public const int upload = 2130837748; // aapt resource value: 0x7f0200f5 - public const int yubikey = 2130837749; + public const int user = 2130837749; + + // aapt resource value: 0x7f0200f6 + public const int yubikey = 2130837750; static Drawable() { diff --git a/src/Android/Resources/drawable-hdpi/paperclip.png b/src/Android/Resources/drawable-hdpi/paperclip.png new file mode 100644 index 000000000..9d87e364a Binary files /dev/null and b/src/Android/Resources/drawable-hdpi/paperclip.png differ diff --git a/src/Android/Resources/drawable-xhdpi/paperclip.png b/src/Android/Resources/drawable-xhdpi/paperclip.png new file mode 100644 index 000000000..825dee100 Binary files /dev/null and b/src/Android/Resources/drawable-xhdpi/paperclip.png differ diff --git a/src/Android/Resources/drawable-xxhdpi/paperclip.png b/src/Android/Resources/drawable-xxhdpi/paperclip.png new file mode 100644 index 000000000..0bb78b189 Binary files /dev/null and b/src/Android/Resources/drawable-xxhdpi/paperclip.png differ diff --git a/src/Android/Resources/drawable-xxxhdpi/paperclip.png b/src/Android/Resources/drawable-xxxhdpi/paperclip.png new file mode 100644 index 000000000..545de466a Binary files /dev/null and b/src/Android/Resources/drawable-xxxhdpi/paperclip.png differ diff --git a/src/Android/Resources/drawable/paperclip.png b/src/Android/Resources/drawable/paperclip.png new file mode 100644 index 000000000..d46ad5ad9 Binary files /dev/null and b/src/Android/Resources/drawable/paperclip.png differ diff --git a/src/App/Controls/LabeledDetailCell.cs b/src/App/Controls/LabeledDetailCell.cs index fd47efff8..7aad3a26f 100644 --- a/src/App/Controls/LabeledDetailCell.cs +++ b/src/App/Controls/LabeledDetailCell.cs @@ -28,6 +28,14 @@ namespace Bit.App.Controls Margin = new Thickness(5, 0, 0, 0) }; + LabelIcon2 = new CachedImage + { + WidthRequest = 16, + HeightRequest = 16, + HorizontalOptions = LayoutOptions.Start, + Margin = new Thickness(5, 0, 0, 0) + }; + Button = new ExtendedButton { WidthRequest = 60 @@ -42,13 +50,15 @@ namespace Bit.App.Controls grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(60, GridUnitType.Absolute) }); grid.Children.Add(Label, 0, 0); grid.Children.Add(Detail, 0, 1); grid.Children.Add(LabelIcon, 1, 0); - grid.Children.Add(Button, 2, 0); - Grid.SetColumnSpan(Detail, 2); + grid.Children.Add(LabelIcon2, 2, 0); + grid.Children.Add(Button, 3, 0); + Grid.SetColumnSpan(Detail, 3); Grid.SetRowSpan(Button, 2); if(Device.RuntimePlatform == Device.Android) @@ -62,6 +72,7 @@ namespace Bit.App.Controls public Label Label { get; private set; } public Label Detail { get; private set; } public CachedImage LabelIcon { get; private set; } + public CachedImage LabelIcon2 { get; private set; } public Button Button { get; private set; } } } diff --git a/src/App/Controls/VaultListViewCell.cs b/src/App/Controls/VaultListViewCell.cs index 04995d8dc..01384ad08 100644 --- a/src/App/Controls/VaultListViewCell.cs +++ b/src/App/Controls/VaultListViewCell.cs @@ -15,12 +15,14 @@ namespace Bit.App.Controls Label.SetBinding(Label.TextProperty, nameof(VaultListPageModel.Login.Name)); Detail.SetBinding(Label.TextProperty, nameof(VaultListPageModel.Login.Username)); LabelIcon.SetBinding(VisualElement.IsVisibleProperty, nameof(VaultListPageModel.Login.Shared)); + LabelIcon2.SetBinding(VisualElement.IsVisibleProperty, nameof(VaultListPageModel.Login.HasAttachments)); Button.Image = "more"; Button.Command = new Command(() => moreClickedAction?.Invoke(LoginParameter)); Button.BackgroundColor = Color.Transparent; LabelIcon.Source = "share"; + LabelIcon2.Source = "paperclip"; BackgroundColor = Color.White; } diff --git a/src/App/Models/Page/VaultListPageModel.cs b/src/App/Models/Page/VaultListPageModel.cs index 5ac43851c..d4c4cb1f4 100644 --- a/src/App/Models/Page/VaultListPageModel.cs +++ b/src/App/Models/Page/VaultListPageModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Bit.App.Resources; +using System.Linq; namespace Bit.App.Models.Page { @@ -12,6 +13,7 @@ namespace Bit.App.Models.Page { Id = login.Id; Shared = !string.IsNullOrWhiteSpace(login.OrganizationId); + HasAttachments = login.Attachments?.Any() ?? false; FolderId = login.FolderId; Name = login.Name?.Decrypt(login.OrganizationId); Username = login.Username?.Decrypt(login.OrganizationId) ?? " "; @@ -22,6 +24,7 @@ namespace Bit.App.Models.Page public string Id { get; set; } public bool Shared { get; set; } + public bool HasAttachments { get; set; } public string FolderId { get; set; } public string Name { get; set; } public string Username { get; set; } diff --git a/src/App/Services/LoginService.cs b/src/App/Services/LoginService.cs index fe6a2f91a..086e38ded 100644 --- a/src/App/Services/LoginService.cs +++ b/src/App/Services/LoginService.cs @@ -54,15 +54,19 @@ namespace Bit.App.Services public async Task> GetAllAsync() { + var attachmentData = await _attachmentRepository.GetAllByUserIdAsync(_authService.UserId); + var attachmentDict = attachmentData.GroupBy(a => a.LoginId).ToDictionary(g => g.Key, g => g.ToList()); var data = await _loginRepository.GetAllByUserIdAsync(_authService.UserId); - var logins = data.Select(f => new Login(f)); + var logins = data.Select(f => new Login(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null)); return logins; } public async Task> GetAllAsync(bool favorites) { + var attachmentData = await _attachmentRepository.GetAllByUserIdAsync(_authService.UserId); + var attachmentDict = attachmentData.GroupBy(a => a.LoginId).ToDictionary(g => g.Key, g => g.ToList()); var data = await _loginRepository.GetAllByUserIdAsync(_authService.UserId, favorites); - var logins = data.Select(f => new Login(f)); + var logins = data.Select(f => new Login(f, attachmentDict.ContainsKey(f.Id) ? attachmentDict[f.Id] : null)); return logins; } diff --git a/src/iOS/Resources/paperclip.png b/src/iOS/Resources/paperclip.png new file mode 100644 index 000000000..d46ad5ad9 Binary files /dev/null and b/src/iOS/Resources/paperclip.png differ diff --git a/src/iOS/Resources/paperclip@2x.png b/src/iOS/Resources/paperclip@2x.png new file mode 100644 index 000000000..825dee100 Binary files /dev/null and b/src/iOS/Resources/paperclip@2x.png differ diff --git a/src/iOS/Resources/paperclip@3x.png b/src/iOS/Resources/paperclip@3x.png new file mode 100644 index 000000000..0bb78b189 Binary files /dev/null and b/src/iOS/Resources/paperclip@3x.png differ diff --git a/src/iOS/iOS.csproj b/src/iOS/iOS.csproj index 88686510a..694a9fe3c 100644 --- a/src/iOS/iOS.csproj +++ b/src/iOS/iOS.csproj @@ -767,6 +767,15 @@ + + + + + + + + +