Skip to content

Instantly share code, notes, and snippets.

@pictos
Created August 3, 2022 00:58
Show Gist options
  • Save pictos/2df3ced9b4d78c58c5c5133940715a5b to your computer and use it in GitHub Desktop.
Save pictos/2df3ced9b4d78c58c5c5133940715a5b to your computer and use it in GitHub Desktop.
public class GravatarImageSource : ImageSource
{
/// <summary>The backing store for the <see cref="Email" /> bindable property.</summary>
public static readonly BindableProperty? EmailProperty = BindableProperty.Create(nameof(Email), typeof(string), typeof(GravatarImageSource), defaultValue: GravatarImageSourceDefaults.DefaultEmail, propertyChanged: OnEmailPropertyChanged);
/// <summary>The backing store for the <see cref="Image" /> bindable property.</summary>
public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(DefaultImage), typeof(GravatarImageSource), defaultValue: GravatarImageSourceDefaults.Defaultimage, propertyChanged: OnDefaultImagePropertyChanged);
/// <summary>Gets or sets the email address.</summary>
public string? Email
{
get => (string)GetValue(EmailProperty);
set => SetValue(EmailProperty, value);
}
/// <summary>Gets or sets the default image.</summary>
public DefaultImage Image
{
get => (DefaultImage)GetValue(ImageProperty);
set => SetValue(ImageProperty, value);
}
static void OnDefaultImagePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var gravatarImageSource = (GravatarImageSource)bindable;
gravatarImageSource.HandleDefaultImageChanged((DefaultImage)newValue);
}
static void OnEmailPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var gravatarImageSource = (GravatarImageSource)bindable;
gravatarImageSource.HandleEmailChanged((string?)newValue);
}
const int gravatarSize = 100;
void HandleDefaultImageChanged(DefaultImage newValue)
{
var uri = new Uri($"https://www.gravatar.com/avatar/{GetMd5Hash(Email)}?s={gravatarSize}&d={DefaultGravatarName(newValue)}");
// Can we assume that Parent always will be an `Image`?
(this.Parent as Image)!.Source = uri;
}
void HandleEmailChanged(string? newValue)
{
var uri = new Uri($"https://www.gravatar.com/avatar/{GetMd5Hash(newValue)}?s={gravatarSize}&d={DefaultGravatarName(Image)}");
// Can we assume that Parent always will be an `Image`?
(this.Parent as Image)!.Source = uri;
}
static string GetMd5Hash(ReadOnlySpan<char> str)
{
if (str.Length is 0)
{
str = "MCT";
}
using var md5 = MD5.Create();
Span<byte> hash = md5.ComputeHash(Encoding.UTF8.GetBytes(str.ToArray()));
return BitConverter.ToString(hash.ToArray(), 0, hash.Length).Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase).ToLowerInvariant();
}
static string DefaultGravatarName(DefaultImage defaultGravatar)
=> defaultGravatar switch
{
DefaultImage.FileNotFound => "404",
DefaultImage.MysteryPerson => "mp",
_ => $"{defaultGravatar}".ToLower(),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment