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 + ")");
return true;
} else {
// FetchNotes ();TODO
return false;
}
}

View file

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

View file

@ -286,6 +286,7 @@ namespace SparkleShare {
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
{
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.Reverse ();
@ -294,7 +295,8 @@ namespace SparkleShare {
return null;
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;
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 day_entry_html = DayEntryHTML;
string event_entry_html = EventEntryHTML;
@ -837,63 +843,69 @@ namespace SparkleShare {
// 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,
size + "x" + size, "status");
List<string> old_avatars = new List<string> ();
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)) {
FileInfo avatar_info = new FileInfo (avatar_file_path);
foreach (string email in emails) {
string avatar_file_path = Path.Combine (avatar_path, "avatar-" + email);
// Delete avatars older than a month and get a new one
if (avatar_info.CreationTime < DateTime.Now.AddMonths (-1)) {
avatar_info.Delete ();
return GetAvatar (email, size);
if (File.Exists (avatar_file_path)) {
FileInfo avatar_info = new FileInfo (avatar_file_path);
// Delete avatars older than a month
if (avatar_info.CreationTime < DateTime.Now.AddMonths (-1)) {
avatar_info.Delete ();
old_avatars.Add (email);
}
} else {
return avatar_file_path;
}
WebClient client = new WebClient ();
string url = "http://gravatar.com/avatar/" + GetMD5 (email) +
".jpg?s=" + size + "&d=404";
} else {
if (!Directory.Exists (avatar_path)) {
Directory.CreateDirectory (avatar_path);
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
}
try {
// Fetch the avatar
byte [] buffer = client.DownloadData (url);
// Let's try to get the person's gravatar for next time
WebClient web_client = new WebClient ();
Uri uri = new Uri ("https://secure.gravatar.com/avatar/" + GetMD5 (email) +
".jpg?s=" + size + "&d=404");
// Write the avatar data to a
// if not empty
if (buffer.Length > 255) {
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);
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;
} catch (WebException) {
SparkleHelpers.DebugInfo ("Controller", "Failed fetching gravatar for " + email);
}
}
}
// 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;
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)
bubble.Icon = new Gdk.Pixbuf (avatar_file_path);
else
bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 32);
bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 36);
bubble.Show ();
});