Merge branch 'notes'

This commit is contained in:
Hylke 2011-08-25 15:37:01 +01:00
commit b31783c3eb
16 changed files with 476 additions and 132 deletions

View file

@ -102,7 +102,10 @@ namespace SparkleLib {
// Ignore permission changes
config = config.Replace ("filemode = true", "filemode = false");
config = config.Replace ("fetch = +refs/heads/*:refs/remotes/origin/*",
"fetch = +refs/heads/*:refs/remotes/origin/*" + Environment.NewLine +
"\tfetch = +refs/notes/*:refs/notes/*");
Console.WriteLine (">>>>>>>>>>>>>>>" + config);
// Add user info
string n = Environment.NewLine;
XmlDocument xml = new XmlDocument();

View file

@ -19,7 +19,10 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
namespace SparkleLib {
@ -89,6 +92,7 @@ namespace SparkleLib {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")");
return true;
} else {
// FetchNotes ();TODO
return false;
}
}
@ -115,8 +119,7 @@ namespace SparkleLib {
public override bool SyncDown ()
{
SparkleGit git = new SparkleGit (LocalPath, "fetch -v origin master");
SparkleGit git = new SparkleGit (LocalPath, "fetch -v");
git.Start ();
git.WaitForExit ();
@ -347,7 +350,7 @@ namespace SparkleLib {
List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso");
SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso --show-notes=*");
Console.OutputEncoding = System.Text.Encoding.Unicode;
git_log.Start ();
@ -405,11 +408,12 @@ namespace SparkleLib {
if (match.Success) {
SparkleChangeSet change_set = new SparkleChangeSet ();
change_set.Folder = Name;
change_set.Revision = match.Groups [1].Value;
change_set.UserName = match.Groups [2].Value;
change_set.UserEmail = match.Groups [3].Value;
change_set.IsMerge = is_merge_commit;
change_set.Folder = Name;
change_set.Revision = match.Groups [1].Value;
change_set.UserName = match.Groups [2].Value;
change_set.UserEmail = match.Groups [3].Value;
change_set.IsMerge = is_merge_commit;
change_set.SupportsNotes = true;
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
@ -449,6 +453,26 @@ namespace SparkleLib {
change_set.MovedFrom.Add (file_path);
change_set.MovedTo.Add (to_file_path);
}
} else if (entry_line.StartsWith (" <note>")) {
Regex regex_notes = new Regex (@"<name>(.+)</name>.*" +
"<email>(.+)</email>.*" +
"<timestamp>([0-9]+)</timestamp>.*" +
"<body>(.+)</body>", RegexOptions.Compiled);
Match match_notes = regex_notes.Match (entry_line);
if (match_notes.Success) {
SparkleNote note = new SparkleNote () {
UserName = match_notes.Groups [1].Value,
UserEmail = match_notes.Groups [2].Value,
Timestamp = new DateTime (1970, 1, 1).AddSeconds (int.Parse (match_notes.Groups [3].Value)),
Body = match_notes.Groups [4].Value
};
change_set.Notes.Add (note);
}
}
}
@ -527,6 +551,55 @@ namespace SparkleLib {
return message.TrimEnd ();
}
public override void AddNote (string revision, string note)
{
int timestamp = (int) (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
// Create the note in one line for easier merging
note = "<note>" +
" <user>" +
" <name>" + SparkleConfig.DefaultConfig.UserName + "</name>" +
" <email>" + SparkleConfig.DefaultConfig.UserEmail + "</email>" +
" </user>" +
" <timestamp>" + timestamp + "</timestamp>" +
" <body>" + note + "</body>" +
"</note>";
string note_namespace = SHA1 (timestamp.ToString () + note);
SparkleGit git_notes = new SparkleGit (LocalPath,
"notes --ref=" + note_namespace + " append -m \"" + note + "\" " + revision);
git_notes.Start ();
git_notes.WaitForExit ();
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Added note to " + revision);
SyncUpNotes ();
}
public override void SyncUpNotes ()
{
while (Status != SyncStatus.Idle) {
System.Threading.Thread.Sleep (5 * 20);
}
SparkleGit git_push = new SparkleGit (LocalPath, "push origin refs/notes/*");
git_push.Start ();
git_push.WaitForExit ();
if (git_push.ExitCode == 0) {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Notes pushed");
} else {
HasUnsyncedChanges = true;
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing notes failed, trying again later");
}
SparkleAnnouncement announcement = new SparkleAnnouncement (Identifier, SHA1 (DateTime.Now.ToString ()));
base.listener.Announce (announcement);
}
public override bool UsesNotificationCenter
{
get {
@ -534,5 +607,15 @@ namespace SparkleLib {
return !File.Exists (file_path);
}
}
// Creates a SHA-1 hash of input
private string SHA1 (string s)
{
SHA1 sha1 = new SHA1CryptoServiceProvider ();
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
Byte[] encoded_bytes = sha1.ComputeHash (bytes);
return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", "");
}
}
}

View file

@ -24,15 +24,29 @@ namespace SparkleLib {
public string UserName;
public string UserEmail;
public string Folder;
public string Revision;
public DateTime Timestamp;
public bool IsMerge = false;
public bool SupportsNotes = false;
public bool IsMerge = false;
public List<string> Added = new List<string> ();
public List<string> Deleted = new List<string> ();
public List<string> Edited = new List<string> ();
public List<string> MovedFrom = new List<string> ();
public List<string> MovedTo = new List<string> ();
public List<SparkleNote> Notes = new List<SparkleNote> ();
}
public class SparkleNote {
public string UserName;
public string UserEmail;
public DateTime Timestamp;
public string Body;
}
}

View file

@ -38,7 +38,6 @@ namespace SparkleLib {
private TimeSpan long_interval = new TimeSpan (0, 0, 10, 0);
private SparkleWatcher watcher;
private SparkleListenerBase listener;
private TimeSpan poll_interval;
private Timer local_timer = new Timer () { Interval = 0.25 * 1000 };
private Timer remote_timer = new Timer () { Interval = 10 * 1000 };
@ -47,6 +46,7 @@ namespace SparkleLib {
private bool has_changed = false;
private Object change_lock = new Object ();
protected SparkleListenerBase listener;
protected SyncStatus status;
protected bool is_buffering = false;
protected bool server_online = true;
@ -110,8 +110,10 @@ namespace SparkleLib {
// In the unlikely case that we haven't synced up our
// changes or the server was down, sync up again
if (HasUnsyncedChanges)
if (HasUnsyncedChanges) {
SyncUpBase ();
SyncUpNotes ();
}
};
this.remote_timer.Start ();
@ -232,8 +234,10 @@ namespace SparkleLib {
SyncDownBase ();
// Push changes that were made since the last disconnect
if (HasUnsyncedChanges)
if (HasUnsyncedChanges) {
SyncUpBase ();
SyncUpNotes ();
}
};
// Start polling when the connection to the irc channel is lost
@ -392,8 +396,9 @@ namespace SparkleLib {
if (SyncStatusChanged != null)
SyncStatusChanged (SyncStatus.Idle);
if (NewChangeSet != null)
NewChangeSet (GetChangeSets (1) [0], LocalPath);
SparkleChangeSet change_set = GetChangeSets (1) [0];
if (NewChangeSet != null && change_set.Revision != CurrentRevision)
NewChangeSet (change_set, LocalPath);
// There could be changes from a
// resolved conflict. Tries only once,
@ -442,6 +447,18 @@ namespace SparkleLib {
}
public virtual void AddNote (string revision, string note)
{
}
public virtual void SyncUpNotes ()
{
}
// Recursively gets a folder's size in bytes
private double CalculateFolderSize (DirectoryInfo parent)
{
@ -455,7 +472,7 @@ namespace SparkleLib {
if (parent.Name.Equals ("rebase-apply"))
return 0;
foreach (FileInfo file in parent.GetFiles()) {
foreach (FileInfo file in parent.GetFiles ()) {
if (!file.Exists)
return 0;

View file

@ -20,6 +20,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using MonoMac.Foundation;
@ -220,10 +221,30 @@ namespace SparkleShare {
public override void DecidePolicyForNavigation (WebView web_view, NSDictionary action_info,
NSUrlRequest request, WebFrame frame, NSObject decision_token)
{
string file_path = request.Url.ToString ();
file_path = file_path.Replace ("%20", " ");
NSWorkspace.SharedWorkspace.OpenFile (file_path);
string url = request.Url.ToString ();
if (url.StartsWith (Path.VolumeSeparatorChar.ToString ())) {
string file_path = request.Url.ToString ();
file_path = file_path.Replace ("%20", " ");
NSWorkspace.SharedWorkspace.OpenFile (file_path);
} else {
Regex regex = new Regex (@"(.+)~(.+)~(.+)");
Match match = regex.Match (url);
if (match.Success) {
string folder_name = match.Groups [1].Value;
string revision = match.Groups [2].Value;
string note = match.Groups [3].Value.Replace ("%20", " ");
Thread thread = new Thread (new ThreadStart (delegate {
SparkleShare.Controller.AddNoteToFolder (folder_name, revision, note);
}));
thread.Start ();
}
}
}
}
}

View file

@ -138,8 +138,11 @@ namespace SparkleShare {
StreamReader reader = new StreamReader (html_path);
string html = reader.ReadToEnd ();
reader.Close ();
return html;
html = html.Replace ("<!-- $jquery-url -->", "file://" +
Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "jquery.js"));
return html;
}
}

View file

@ -62,7 +62,7 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\Meebey.SmartIrc4net.dll</HintPath>
</Reference>
<Reference Include="SparkleLib, Version=0.2.1.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="SparkleLib, Version=0.2.2.0, Culture=neutral, PublicKeyToken=null">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\SparkleLib.dll</HintPath>
</Reference>
@ -170,6 +170,9 @@
<Content Include="..\..\data\icons\document-moved-12.png">
<Link>Pixmaps\document-moved-12.png</Link>
</Content>
<Content Include="..\..\data\html\jquery.js">
<Link>HTML\jquery.js</Link>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="Pixmaps\" />

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;
@ -389,14 +395,35 @@ namespace SparkleShare {
}
}
}
string comments = "";
if (change_set.SupportsNotes) {
comments = "<table class=\"comments\">";
change_set.Notes.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
foreach (SparkleNote note in change_set.Notes) {
comments += "<tr>" +
" <td class=\"comment-author\">" + note.UserName + "</td>" +
" <td class=\"comment-timestamp\">" + note.Timestamp.ToString ("d MMM") + "</td>" +
"</tr>" +
"<tr>" +
" <td class=\"comment-text\" colspan=\"2\">" + note.Body + "</td>" +
"</tr>";
}
comments += "</table>";
}
event_entry += "</dl>";
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
.Replace ("<!-- $event-user-name -->", change_set.UserName)
.Replace ("<!-- $event-avatar-url -->", "file://" + GetAvatar (change_set.UserEmail, 36))
.Replace ("<!-- $event-time -->", change_set.Timestamp.ToString ("H:mm"))
.Replace ("<!-- $event-folder -->", change_set.Folder)
.Replace ("<!-- $event-folder-color -->", AssignColor (change_set.Folder));
.Replace ("<!-- $event-revision -->", change_set.Revision)
.Replace ("<!-- $event-folder-color -->", AssignColor (change_set.Folder))
.Replace ("<!-- $event-comments -->", comments);
}
string day_entry = "";
@ -431,7 +458,8 @@ namespace SparkleShare {
event_log += day_entry.Replace ("<!-- $day-entry-content -->", event_entries);
}
return event_log_html.Replace ("<!-- $event-log-content -->", event_log);
return event_log_html.Replace ("<!-- $event-log-content -->", event_log)
.Replace ("<!-- $username -->", UserName);
}
@ -815,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;
}
@ -1023,6 +1057,15 @@ namespace SparkleShare {
}
public void AddNoteToFolder (string folder_name, string revision, string note)
{
foreach (SparkleRepoBase repo in Repositories) {
if (repo.Name.Equals (folder_name))
repo.AddNote (revision, note);
}
}
public void CheckForNewVersion ()
{
WebClient web_client = new WebClient ();

View file

@ -84,7 +84,6 @@ namespace SparkleShare {
LinkStatus = args.Link;
};
// FIXME: Use the right event, waiting for newer webkit bindings: NavigationPolicyDecisionRequested
WebView.NavigationRequested += delegate (object o, WebKit.NavigationRequestedArgs args) {
if (args.Request.Uri == LinkStatus) {
Process process = new Process ();
@ -92,9 +91,26 @@ namespace SparkleShare {
process.StartInfo.Arguments = args.Request.Uri.Replace (" ", "\\ "); // Escape space-characters
process.Start ();
// Don't follow HREFs (as this would cause a page refresh)
args.RetVal = 1;
} else {
Regex regex = new Regex (@"(.+)~(.+)~(.+)");
Match match = regex.Match (args.Request.Uri);
if (match.Success) {
string folder_name = match.Groups [1].Value;
string revision = match.Groups [2].Value;
string note = match.Groups [3].Value.Replace ("%20", " ");
Thread thread = new Thread (new ThreadStart (delegate {
SparkleShare.Controller.AddNoteToFolder (folder_name, revision, note);
}));
thread.Start ();
}
}
// Don't follow HREFs (as this would cause a page refresh)
if (!args.Request.Uri.Equals ("file:"))
args.RetVal = 1;
};
ScrolledWindow.Add (WebView);
@ -142,6 +158,12 @@ namespace SparkleShare {
return (item == "---");
};
if (this.selected_log != null &&
!SparkleShare.Controller.Folders.Contains (this.selected_log)) {
this.selected_log = null;
}
this.combo_box.Changed += delegate {
TreeIter iter;
this.combo_box.GetActiveIter (out iter);

View file

@ -166,8 +166,13 @@ namespace SparkleShare {
get {
string path = SparkleHelpers.CombineMore (Defines.PREFIX,
"share", "sparkleshare", "html", "event-log.html");
string html = String.Join (Environment.NewLine, File.ReadAllLines (path));
html = html.Replace ("<!-- $jquery-url -->", "file://" +
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "html", "jquery.js"));
return String.Join (Environment.NewLine, File.ReadAllLines (path));
return html;
}
}

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 ();
});

View file

@ -1,7 +1,8 @@
dist_html_DATA = \
day-entry.html \
event-entry.html \
event-log.html
event-log.html \
jquery.js
htmldir = $(pkgdatadir)/html/

View file

@ -8,9 +8,20 @@
<b><!-- $event-user-name --></b><br/>
<small><!-- $event-time --></small>
</div>
<div class='event-time' style='background-color: <!-- $event-folder-color -->'><!-- $event-folder --></div>
<div class='event-folder' style='background-color: <!-- $event-folder-color -->'><!-- $event-folder --></div>
</div>
<!-- $event-entry-content -->
<div class="comments-section">
<div class="comments-wrapper">
<!-- $event-comments -->
<textarea class="comment-textarea"></textarea>
<input class="comment-button" type="button" value="Add note"
id="<!-- $event-folder -->~<!-- $event-revision -->">
<div style='clear: both'></div>
</div>
<div style='clear: both'></div>
</div>
<div style='clear: both'></div>
</div>
</div>

View file

@ -2,6 +2,47 @@
<html>
<head>
<title>SparkleShare Event Log</title>
<script type="text/javascript" src="<!-- $jquery-url -->"></script>
<script type="text/javascript">
$(document).ready(function () {
$('.comments-wrapper').each (function () {
if ($(this).find ('.comments').children ().size () < 1) {
$(this).hide ();
} else {
$(this).css ('cursor', 'default');
}
});
$('.comments-section').click(function () {
$(this).find ('.comments-wrapper').show ();
$(this).find ('.comments-wrapper').css ('cursor', 'default');
});
$("input").click(function () {
textarea = $(this).parent ().find ('textarea');
text = textarea.val ();
if (text == '')
return;
textarea.val ('');
table = $(this).parent ().find ("table");
comments = table.html ();
comments += '<tr>' +
' <td class=\"comment-author\"><!-- $username --></td>' +
' <td class=\"comment-timestamp\">just now</td>' +
'</tr>' +
'<tr>' +
' <td class=\"comment-text\" colspan=\"2\">' + text + '</td>' +
'</tr>';
table.html (comments);
location = this.id + '~' + text;
});
});
</script>
<style>
body {
background-color: #dedede;
@ -22,6 +63,11 @@
color: <!-- $secondary-font-color -->;
}
td {
vertical-align: top;
font-size: 12px;
}
.day-entry-header {
font-size: <!-- $day-entry-header-font-size -->;
color: #444;
@ -30,7 +76,6 @@
margin-left: auto;
margin-right: auto;
}
a {
color: <!-- $a-color -->;
@ -41,8 +86,8 @@
color: <!-- $a-hover-color -->;
}
.event-time {
margin: 15px;
.event-folder {
margin: 6px;
opacity: 0.8;
font-size: 80%;
color: #fff;
@ -50,19 +95,19 @@
padding: 3px 15px;
font-weight: bold;
-webkit-border-radius: 100px;
cursor: pointer;
}
.event-entry-content {
display: block;
background-color: #f0f0f0;
margin-bottom: 12px;
padding: 0px;
padding-bottom: 6px;
border: #ccc 1px solid;
display: block;
background-color: #f0f0f0;
margin-bottom: 12px;
padding: 0px;
border: #ccc 1px solid;
}
.wrapper {
margin: 15px;
margin: 9px;
float: left;
}
@ -89,6 +134,7 @@
dd:last-child {
border: none;
margin-bottom: 6px;
}
.document-added {
@ -122,11 +168,65 @@
}
.event-info {
padding: 6px;
float: left;
margin-bottom: 8px;
width: 100%;
background-color: #fff;
border-bottom: 1px #ccc solid;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.comments {
width: 100%;
}
.comment-author {
font-weight: bold;
width: 75%;
}
.comment-timestamp {
color: <!-- $secondary-font-color -->;
text-align: right;
}
.comment-button {
float:right;
margin-top: 6px;
margin-bottom: 12px;
}
.comment-textarea {
box-sizing: border-box;
-webkit-box-sizing: border-box;
width: 100%;
height: 50px;
padding-bottom: 6px;
}
.comments-section {
box-sizing: border-box;
-webkit-box-sizing: border-box;
border-top: 1px #ccc solid;
width: 100%;
height: 9px;
}
.comments-wrapper {
box-sizing: border-box;
-webkit-box-sizing: border-box;
width: 100%;
padding: 12px;
}
.comments-section:hover {
cursor: pointer;
}
.comment-text {
padding-bottom: 15px;
}
</style>
</head>

18
data/html/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long