mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-27 12:26:31 +01:00
[SG-912] Modify the mobile app to retrieve the user's avatar color (#2284)
* [SG-912] Modify the mobile app to retrieve the user's avatar color (#2277) * work: baseline * fix: dont use profile for store * fiix: use userid in key * fix: lookup on AccountView list create * fix my own bad advice + tweaks * Autosync the updated translations (#2279) * fix my own bad advice + tweaks * fiix: use userid in key * [PS-1352] Fix ignore diacritics in search (#2044) * Fix ignore diacritics in search This change updates the search function to ignore diacritical marks in search results. Marks are stripped from both the search input and results. * Removed logs, added null or whitespace validation and improved formatting * [PS-2145] add rainsee browser series support (#2272) * fix: lookup on AccountView list create * Autosync the updated translations (#2279) * fix my own bad advice + tweaks * fix: single state grab is cool
This commit is contained in:
parent
4f4953206e
commit
6102a0c115
@ -14,7 +14,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
AccountView = accountView;
|
||||
AvatarImageSource = ServiceContainer.Resolve<IAvatarImageSourcePool>("avatarImageSourcePool")
|
||||
?.GetOrCreateAvatar(AccountView.UserId, AccountView.Name, AccountView.Email);
|
||||
?.GetOrCreateAvatar(AccountView.UserId, AccountView.Name, AccountView.Email, AccountView.AvatarColor);
|
||||
}
|
||||
|
||||
public AccountView AccountView
|
||||
|
@ -13,6 +13,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
private readonly string _color;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
@ -23,7 +24,7 @@ namespace Bit.App.Controls
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._id == _id && avatar._text == _text;
|
||||
return avatar._id == _id && avatar._text == _text && avatar._color == _color;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
@ -31,7 +32,7 @@ namespace Bit.App.Controls
|
||||
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null)
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null, string color = null)
|
||||
{
|
||||
_id = userId;
|
||||
_text = name;
|
||||
@ -39,6 +40,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
_text = email;
|
||||
}
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public override Func<CancellationToken, Task<Stream>> Stream => GetStreamAsync;
|
||||
@ -71,7 +73,7 @@ namespace Bit.App.Controls
|
||||
chars = upperCaseText = _text.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var bgColor = _color ?? CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var textColor = CoreHelpers.TextColorFromBgColor(bgColor);
|
||||
var size = 50;
|
||||
|
||||
|
@ -5,19 +5,19 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public interface IAvatarImageSourcePool
|
||||
{
|
||||
AvatarImageSource GetOrCreateAvatar(string userId, string name, string email);
|
||||
AvatarImageSource GetOrCreateAvatar(string userId, string name, string email, string color);
|
||||
}
|
||||
|
||||
public class AvatarImageSourcePool : IAvatarImageSourcePool
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, AvatarImageSource> _cache = new ConcurrentDictionary<string, AvatarImageSource>();
|
||||
|
||||
public AvatarImageSource GetOrCreateAvatar(string userId, string name, string email)
|
||||
public AvatarImageSource GetOrCreateAvatar(string userId, string name, string email, string color)
|
||||
{
|
||||
var key = $"{userId}{name}{email}";
|
||||
var key = $"{userId}{name}{email}{color}";
|
||||
if (!_cache.TryGetValue(key, out var avatar))
|
||||
{
|
||||
avatar = new AvatarImageSource(userId, name, email);
|
||||
avatar = new AvatarImageSource(userId, name, email, color);
|
||||
if (!_cache.TryAdd(key, avatar)
|
||||
&&
|
||||
!_cache.TryGetValue(key, out avatar)) // If add fails another thread created the avatar in between the first try get and the try add.
|
||||
|
@ -129,8 +129,8 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (useCurrentActiveAccount)
|
||||
{
|
||||
return new AvatarImageSource(await _stateService.GetActiveUserIdAsync(),
|
||||
await _stateService.GetNameAsync(), await _stateService.GetEmailAsync());
|
||||
var user = await _stateService.GetActiveUserCustomDataAsync(a => (a?.Profile?.UserId, a?.Profile?.Name, a?.Profile?.Email, a?.Profile?.AvatarColor));
|
||||
return new AvatarImageSource(user.UserId, user.Name, user.Email, user.AvatarColor);
|
||||
}
|
||||
return new AvatarImageSource();
|
||||
}
|
||||
|
@ -108,6 +108,10 @@ namespace Bit.App.Pages
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
await Task.Delay(500);
|
||||
if (_vm.MainPage)
|
||||
{
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
IsBusy = false;
|
||||
|
@ -163,5 +163,9 @@ namespace Bit.Core.Abstractions
|
||||
Task<bool> GetShouldConnectToWatchAsync(string userId = null);
|
||||
Task SetShouldConnectToWatchAsync(bool shouldConnect, string userId = null);
|
||||
Task<bool> GetLastUserShouldConnectToWatchAsync();
|
||||
Task SetAvatarColorAsync(string value, string userId = null);
|
||||
Task<string> GetAvatarColorAsync(string userId = null);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ namespace Bit.Core.Models.Domain
|
||||
KdfIterations = copy.KdfIterations;
|
||||
EmailVerified = copy.EmailVerified;
|
||||
HasPremiumPersonally = copy.HasPremiumPersonally;
|
||||
AvatarColor = copy.AvatarColor;
|
||||
}
|
||||
|
||||
public string UserId;
|
||||
@ -55,6 +56,7 @@ namespace Bit.Core.Models.Domain
|
||||
public string Name;
|
||||
public string Stamp;
|
||||
public string OrgIdentifier;
|
||||
public string AvatarColor;
|
||||
public KdfType? KdfType;
|
||||
public int? KdfIterations;
|
||||
public bool? EmailVerified;
|
||||
|
@ -19,5 +19,6 @@ namespace Bit.Core.Models.Response
|
||||
public bool ForcePasswordReset { get; set; }
|
||||
public List<ProfileOrganizationResponse> Organizations { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ namespace Bit.Core.Models.View
|
||||
UserId = a.Profile?.UserId;
|
||||
Email = a.Profile?.Email;
|
||||
Name = a.Profile?.Name;
|
||||
AvatarColor = a.Profile?.AvatarColor;
|
||||
if (!string.IsNullOrWhiteSpace(a.Settings?.EnvironmentUrls?.WebVault))
|
||||
{
|
||||
Hostname = CoreHelpers.GetHostname(a.Settings?.EnvironmentUrls?.WebVault);
|
||||
@ -37,5 +38,6 @@ namespace Bit.Core.Models.View
|
||||
public string Email { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1305,6 +1305,23 @@ namespace Bit.Core.Services
|
||||
var key = Constants.PasswordlessLoginNotificationKey;
|
||||
await SetValueAsync(key, value, options);
|
||||
}
|
||||
|
||||
public async Task SetAvatarColorAsync(string value, string userId = null)
|
||||
{
|
||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
||||
await GetDefaultStorageOptionsAsync());
|
||||
var account = await GetAccountAsync(reconciledOptions);
|
||||
account.Profile.AvatarColor = value;
|
||||
await SaveAccountAsync(account, reconciledOptions);
|
||||
}
|
||||
|
||||
public async Task<string> GetAvatarColorAsync(string userId = null)
|
||||
{
|
||||
return (await GetAccountAsync(
|
||||
ReconcileOptions(new StorageOptions { UserId = userId }, await GetDefaultStorageOptionsAsync())
|
||||
))?.Profile?.AvatarColor;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
private async Task<T> GetValueAsync<T>(string key, StorageOptions options)
|
||||
|
@ -335,6 +335,7 @@ namespace Bit.Core.Services
|
||||
await _organizationService.ReplaceAsync(organizations);
|
||||
await _stateService.SetEmailVerifiedAsync(response.EmailVerified);
|
||||
await _stateService.SetNameAsync(response.Name);
|
||||
await _stateService.SetAvatarColorAsync(response.AvatarColor);
|
||||
await _keyConnectorService.SetUsesKeyConnector(response.UsesKeyConnector);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user