mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
feature<Avatar>: add context menu to manually re-fetch avatar
This commit is contained in:
parent
e4c350f189
commit
738daddbc7
1 changed files with 59 additions and 42 deletions
|
@ -71,7 +71,9 @@ namespace SourceGit.Views.Controls {
|
||||||
set { SetValue(FallbackLabelProperty, value); }
|
set { SetValue(FallbackLabelProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, List<Avatar>> requesting = new Dictionary<string, List<Avatar>>();
|
private static event Action<string> RefetchRequested;
|
||||||
|
private static event Action<string> FetchCompleted;
|
||||||
|
|
||||||
private static Dictionary<string, BitmapImage> loaded = new Dictionary<string, BitmapImage>();
|
private static Dictionary<string, BitmapImage> loaded = new Dictionary<string, BitmapImage>();
|
||||||
private static Task loader = null;
|
private static Task loader = null;
|
||||||
|
|
||||||
|
@ -79,23 +81,45 @@ namespace SourceGit.Views.Controls {
|
||||||
private FormattedText label = null;
|
private FormattedText label = null;
|
||||||
|
|
||||||
public Avatar() {
|
public Avatar() {
|
||||||
|
RefetchRequested += email => {
|
||||||
|
if (email == Email) {
|
||||||
|
Source = null;
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FetchCompleted += email => {
|
||||||
|
if (email == Email) {
|
||||||
|
Source = loaded[Email];
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
SetValue(RenderOptions.BitmapScalingModeProperty, BitmapScalingMode.HighQuality);
|
SetValue(RenderOptions.BitmapScalingModeProperty, BitmapScalingMode.HighQuality);
|
||||||
SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Auto);
|
SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Auto);
|
||||||
Unloaded += (o, e) => Cancel(Email);
|
|
||||||
|
var refetch = new MenuItem();
|
||||||
|
refetch.Header = App.Text("Dashboard.Refresh");
|
||||||
|
refetch.Click += (o, e) => Refetch();
|
||||||
|
|
||||||
|
ContextMenu = new ContextMenu();
|
||||||
|
ContextMenu.Items.Add(refetch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取消一个下载任务
|
/// 手动刷新
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="email"></param>
|
private void Refetch() {
|
||||||
private void Cancel(string email) {
|
byte[] hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(Email.ToLower().Trim()));
|
||||||
if (!string.IsNullOrEmpty(email) && requesting.ContainsKey(email)) {
|
string md5 = "";
|
||||||
if (requesting[email].Count <= 1) {
|
for (int i = 0; i < hash.Length; i++) md5 += hash[i].ToString("x2");
|
||||||
requesting.Remove(email);
|
md5 = md5.ToLower();
|
||||||
} else {
|
string filePath = Path.Combine(CACHE_PATH, md5);
|
||||||
requesting[email].Remove(this);
|
if (File.Exists(filePath)) File.Delete(filePath);
|
||||||
}
|
|
||||||
}
|
RefetchRequested?.Invoke(Email);
|
||||||
|
if (loaded.ContainsKey(Email)) loaded.Remove(Email);
|
||||||
|
OnEmailChanged(this, new DependencyPropertyChangedEventArgs(EmailProperty, null, Email));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -146,6 +170,7 @@ namespace SourceGit.Views.Controls {
|
||||||
var chars = placeholder.ToCharArray();
|
var chars = placeholder.ToCharArray();
|
||||||
foreach (var ch in chars) a.colorIdx += Math.Abs(ch);
|
foreach (var ch in chars) a.colorIdx += Math.Abs(ch);
|
||||||
a.colorIdx = a.colorIdx % BACKGROUND_BRUSHES.Length;
|
a.colorIdx = a.colorIdx % BACKGROUND_BRUSHES.Length;
|
||||||
|
if (a.Source == null) a.InvalidateVisual();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -157,9 +182,10 @@ namespace SourceGit.Views.Controls {
|
||||||
Avatar a = d as Avatar;
|
Avatar a = d as Avatar;
|
||||||
if (a == null) return;
|
if (a == null) return;
|
||||||
|
|
||||||
a.Cancel(e.OldValue as string);
|
if (a.Source != null) {
|
||||||
a.Source = null;
|
a.Source = null;
|
||||||
a.InvalidateVisual();
|
a.InvalidateVisual();
|
||||||
|
}
|
||||||
|
|
||||||
var email = e.NewValue as string;
|
var email = e.NewValue as string;
|
||||||
if (string.IsNullOrEmpty(email)) return;
|
if (string.IsNullOrEmpty(email)) return;
|
||||||
|
@ -169,11 +195,6 @@ namespace SourceGit.Views.Controls {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requesting.ContainsKey(email)) {
|
|
||||||
requesting[email].Add(a);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(email.ToLower().Trim()));
|
byte[] hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(email.ToLower().Trim()));
|
||||||
string md5 = "";
|
string md5 = "";
|
||||||
for (int i = 0; i < hash.Length; i++) md5 += hash[i].ToString("x2");
|
for (int i = 0; i < hash.Length; i++) md5 += hash[i].ToString("x2");
|
||||||
|
@ -181,18 +202,15 @@ namespace SourceGit.Views.Controls {
|
||||||
|
|
||||||
string filePath = Path.Combine(CACHE_PATH, md5);
|
string filePath = Path.Combine(CACHE_PATH, md5);
|
||||||
if (File.Exists(filePath)) {
|
if (File.Exists(filePath)) {
|
||||||
var img = new BitmapImage(new Uri(filePath));
|
var img = LoadFromFile(filePath);
|
||||||
loaded.Add(email, img);
|
loaded.Add(email, img);
|
||||||
a.Source = img;
|
a.Source = img;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
requesting.Add(email, new List<Avatar>());
|
loaded.Add(email, null);
|
||||||
requesting[email].Add(a);
|
|
||||||
|
|
||||||
Action job = () => {
|
Action job = () => {
|
||||||
if (!requesting.ContainsKey(email)) return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var req = WebRequest.CreateHttp($"https://cravatar.cn/avatar/{md5}?d=404");
|
var req = WebRequest.CreateHttp($"https://cravatar.cn/avatar/{md5}?d=404");
|
||||||
req.Timeout = 2000;
|
req.Timeout = 2000;
|
||||||
|
@ -200,27 +218,18 @@ namespace SourceGit.Views.Controls {
|
||||||
|
|
||||||
var rsp = req.GetResponse() as HttpWebResponse;
|
var rsp = req.GetResponse() as HttpWebResponse;
|
||||||
if (rsp != null && rsp.StatusCode == HttpStatusCode.OK) {
|
if (rsp != null && rsp.StatusCode == HttpStatusCode.OK) {
|
||||||
using (var reader = rsp.GetResponseStream())
|
using (var reader = rsp.GetResponseStream()) {
|
||||||
using (var writer = File.OpenWrite(filePath)) {
|
using (var writer = File.OpenWrite(filePath)) {
|
||||||
reader.CopyTo(writer);
|
reader.CopyTo(writer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a.Dispatcher.Invoke(() => {
|
a.Dispatcher.Invoke(() => {
|
||||||
var img = new BitmapImage(new Uri(filePath));
|
loaded[email] = LoadFromFile(filePath);
|
||||||
loaded.Add(email, img);
|
FetchCompleted?.Invoke(email);
|
||||||
|
|
||||||
if (requesting.ContainsKey(email)) {
|
|
||||||
foreach (var one in requesting[email]) one.Source = img;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
if (!loaded.ContainsKey(email)) loaded.Add(email, null);
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {}
|
||||||
if (!loaded.ContainsKey(email)) loaded.Add(email, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
requesting.Remove(email);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loader != null && !loader.IsCompleted) {
|
if (loader != null && !loader.IsCompleted) {
|
||||||
|
@ -229,5 +238,13 @@ namespace SourceGit.Views.Controls {
|
||||||
loader = Task.Run(job);
|
loader = Task.Run(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BitmapImage LoadFromFile(string file) {
|
||||||
|
var img = new BitmapImage();
|
||||||
|
img.BeginInit();
|
||||||
|
img.StreamSource = new MemoryStream(File.ReadAllBytes(file));
|
||||||
|
img.EndInit();
|
||||||
|
return img;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue