avatars: save to buffer instead of file: less blinking of event log, simpler, so fewer bugs

This commit is contained in:
Hylke 2011-08-25 15:36:26 +01:00
parent ee51f685ef
commit 7b87b1f6b9
4 changed files with 104 additions and 91 deletions

View file

@ -92,6 +92,7 @@ namespace SparkleLib {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")"); SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")");
return true; return true;
} else { } else {
// FetchNotes ();TODO
return false; return false;
} }
} }

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
@ -28,7 +28,7 @@ using MonoMac.Growl;
namespace SparkleShare { namespace SparkleShare {
public partial class AppDelegate : NSApplicationDelegate { public partial class AppDelegate : NSApplicationDelegate {
public override void WillBecomeActive (NSNotification notification) public override void WillBecomeActive (NSNotification notification)
{ {
@ -45,22 +45,22 @@ namespace SparkleShare {
{ {
SparkleShare.Controller.Quit (); SparkleShare.Controller.Quit ();
} }
} }
public class SparkleUI : AppDelegate { public class SparkleUI : AppDelegate {
public static SparkleStatusIcon StatusIcon; public static SparkleStatusIcon StatusIcon;
public static SparkleEventLog EventLog; public static SparkleEventLog EventLog;
public static SparkleIntro Intro; public static SparkleIntro Intro;
public static SparkleAbout About; public static SparkleAbout About;
public static NSFont Font; public static NSFont Font;
private NSAlert alert; private NSAlert alert;
public SparkleUI () public SparkleUI ()
{ {
string content_path = Directory.GetParent ( string content_path = Directory.GetParent (
System.AppDomain.CurrentDomain.BaseDirectory).ToString (); System.AppDomain.CurrentDomain.BaseDirectory).ToString ();
@ -95,7 +95,7 @@ namespace SparkleShare {
SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email, SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email,
string message, string repository_path) { string message, string repository_path) {
InvokeOnMainThread (delegate { InvokeOnMainThread (delegate {
if (EventLog != null) if (EventLog != null)
EventLog.UpdateEvents (); EventLog.UpdateEvents ();
@ -103,7 +103,7 @@ namespace SparkleShare {
if (NSApplication.SharedApplication.DockTile.BadgeLabel == null) if (NSApplication.SharedApplication.DockTile.BadgeLabel == null)
NSApplication.SharedApplication.DockTile.BadgeLabel = "1"; NSApplication.SharedApplication.DockTile.BadgeLabel = "1";
else else
NSApplication.SharedApplication.DockTile.BadgeLabel = NSApplication.SharedApplication.DockTile.BadgeLabel =
(int.Parse (NSApplication.SharedApplication.DockTile.BadgeLabel) + 1).ToString (); (int.Parse (NSApplication.SharedApplication.DockTile.BadgeLabel) + 1).ToString ();
if (GrowlApplicationBridge.IsGrowlRunning ()) { if (GrowlApplicationBridge.IsGrowlRunning ()) {
@ -114,13 +114,13 @@ namespace SparkleShare {
bubble.Show (); bubble.Show ();
} else { } else {
NSApplication.SharedApplication.RequestUserAttention NSApplication.SharedApplication.RequestUserAttention (
(NSRequestUserAttentionType.InformationalRequest); NSRequestUserAttentionType.InformationalRequest);
} }
} }
}); });
}; };
SparkleShare.Controller.ConflictNotificationRaised += delegate { SparkleShare.Controller.ConflictNotificationRaised += delegate {
string title = "Ouch! Mid-air collision!"; string title = "Ouch! Mid-air collision!";
@ -130,13 +130,13 @@ namespace SparkleShare {
}; };
SparkleShare.Controller.AvatarFetched += delegate { SparkleShare.Controller.AvatarFetched += delegate {
InvokeOnMainThread (delegate { InvokeOnMainThread (delegate {
if (EventLog != null) if (EventLog != null)
EventLog.UpdateEvents (); EventLog.UpdateEvents ();
}); });
}; };
SparkleShare.Controller.OnIdle += delegate { SparkleShare.Controller.OnIdle += delegate {
InvokeOnMainThread (delegate { InvokeOnMainThread (delegate {
@ -156,29 +156,29 @@ namespace SparkleShare {
}; };
if (SparkleShare.Controller.FirstRun) { if (SparkleShare.Controller.FirstRun) {
Intro = new SparkleIntro (); Intro = new SparkleIntro ();
Intro.ShowAccountForm (); Intro.ShowAccountForm ();
} }
} }
public void SetFolderIcon () public void SetFolderIcon ()
{ {
string folder_icon_path = Path.Combine (NSBundle.MainBundle.ResourcePath, string folder_icon_path = Path.Combine (NSBundle.MainBundle.ResourcePath,
"sparkleshare-mac.icns"); "sparkleshare-mac.icns");
NSImage folder_icon = new NSImage (folder_icon_path); NSImage folder_icon = new NSImage (folder_icon_path);
NSWorkspace.SharedWorkspace.SetIconforFile (folder_icon, NSWorkspace.SharedWorkspace.SetIconforFile (folder_icon,
SparkleShare.Controller.SparklePath, 0); SparkleShare.Controller.SparklePath, 0);
} }
public void Run () public void Run ()
{ {
NSApplication.Main (new string [0]); NSApplication.Main (new string [0]);
} }
[Export("registrationDictionaryForGrowl")] [Export("registrationDictionaryForGrowl")]

View file

@ -286,6 +286,7 @@ namespace SparkleShare {
public string GetHTMLLog (List<SparkleChangeSet> change_sets) public string GetHTMLLog (List<SparkleChangeSet> change_sets)
{ {
List <ActivityDay> activity_days = new List <ActivityDay> (); List <ActivityDay> activity_days = new List <ActivityDay> ();
List<string> emails = new List<string> ();
change_sets.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp))); change_sets.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
change_sets.Reverse (); change_sets.Reverse ();
@ -294,7 +295,8 @@ namespace SparkleShare {
return null; return null;
foreach (SparkleChangeSet change_set in change_sets) { foreach (SparkleChangeSet change_set in change_sets) {
GetAvatar (change_set.UserEmail, 36); if (!emails.Contains (change_set.UserEmail))
emails.Add (change_set.UserEmail);
bool change_set_inserted = false; bool change_set_inserted = false;
foreach (ActivityDay stored_activity_day in activity_days) { foreach (ActivityDay stored_activity_day in activity_days) {
@ -315,6 +317,10 @@ namespace SparkleShare {
} }
} }
new Thread (new ThreadStart (delegate {
FetchAvatars (emails, 36);
})).Start ();
string event_log_html = EventLogHTML; string event_log_html = EventLogHTML;
string day_entry_html = DayEntryHTML; string day_entry_html = DayEntryHTML;
string event_entry_html = EventEntryHTML; string event_entry_html = EventEntryHTML;
@ -837,63 +843,69 @@ namespace SparkleShare {
// Gets the avatar for a specific email address and size // Gets the avatar for a specific email address and size
public string GetAvatar (string email, int size) public void FetchAvatars (List<string> emails, int size)
{ {
string avatar_path = SparkleHelpers.CombineMore (SparklePaths.SparkleLocalIconPath, List<string> old_avatars = new List<string> ();
size + "x" + size, "status"); bool avatar_fetched = false;
string avatar_path = SparkleHelpers.CombineMore (
SparklePaths.SparkleLocalIconPath, size + "x" + size, "status");
string avatar_file_path = Path.Combine (avatar_path, "avatar-" + email); if (!Directory.Exists (avatar_path)) {
Directory.CreateDirectory (avatar_path);
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
}
if (File.Exists (avatar_file_path)) { foreach (string email in emails) {
FileInfo avatar_info = new FileInfo (avatar_file_path); string avatar_file_path = Path.Combine (avatar_path, "avatar-" + email);
// Delete avatars older than a month and get a new one if (File.Exists (avatar_file_path)) {
if (avatar_info.CreationTime < DateTime.Now.AddMonths (-1)) { FileInfo avatar_info = new FileInfo (avatar_file_path);
avatar_info.Delete ();
return GetAvatar (email, size); // Delete avatars older than a month
if (avatar_info.CreationTime < DateTime.Now.AddMonths (-1)) {
avatar_info.Delete ();
old_avatars.Add (email);
}
} else { } else {
return avatar_file_path; WebClient client = new WebClient ();
} string url = "http://gravatar.com/avatar/" + GetMD5 (email) +
".jpg?s=" + size + "&d=404";
} else { try {
if (!Directory.Exists (avatar_path)) { // Fetch the avatar
Directory.CreateDirectory (avatar_path); byte [] buffer = client.DownloadData (url);
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
}
// Let's try to get the person's gravatar for next time // Write the avatar data to a
WebClient web_client = new WebClient (); // if not empty
Uri uri = new Uri ("https://secure.gravatar.com/avatar/" + GetMD5 (email) + if (buffer.Length > 255) {
".jpg?s=" + size + "&d=404"); avatar_fetched = true;
File.WriteAllBytes (avatar_file_path, buffer);
SparkleHelpers.DebugInfo ("Controller", "Fetched gravatar for " + email);
}
string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size); } catch (WebException) {
SparkleHelpers.DebugInfo ("Controller", "Failed fetching gravatar for " + email);
if (!File.Exists (tmp_file_path)) { }
web_client.DownloadFileAsync (uri, tmp_file_path); }
web_client.DownloadFileCompleted += delegate {
if (File.Exists (avatar_file_path))
File.Delete (avatar_file_path);
FileInfo tmp_file_info = new FileInfo (tmp_file_path);
if (tmp_file_info.Length > 255)
File.Move (tmp_file_path, avatar_file_path);
SparkleHelpers.DebugInfo ("Controller", "Fetched gravatar: " + email);
if (AvatarFetched != null)
AvatarFetched ();
};
}
// Fall back to a generic icon if there is no gravatar
if (File.Exists (avatar_file_path))
return avatar_file_path;
else
return null;
} }
// Fetch new versions of the avatars that we
// deleted because they were too old
if (old_avatars.Count > 0)
FetchAvatars (old_avatars, size);
if (AvatarFetched != null && avatar_fetched)
AvatarFetched ();
}
public string GetAvatar (string email, int size)
{
string avatar_file_path = SparkleHelpers.CombineMore (
SparklePaths.SparkleLocalIconPath, size + "x" + size, "status", "avatar-" + email);
return avatar_file_path;
} }

View file

@ -79,12 +79,12 @@ namespace SparkleShare {
return; return;
SparkleBubble bubble = new SparkleBubble (user_name, message); SparkleBubble bubble = new SparkleBubble (user_name, message);
string avatar_file_path = SparkleShare.Controller.GetAvatar (user_email, 32); string avatar_file_path = SparkleShare.Controller.GetAvatar (user_email, 36);
if (avatar_file_path != null) if (avatar_file_path != null)
bubble.Icon = new Gdk.Pixbuf (avatar_file_path); bubble.Icon = new Gdk.Pixbuf (avatar_file_path);
else else
bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 32); bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 36);
bubble.Show (); bubble.Show ();
}); });