Merge branch 'notes'
This commit is contained in:
commit
19f428fd8f
|
@ -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();
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
@ -410,6 +413,7 @@ namespace SparkleLib {
|
|||
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 ("-", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,15 +24,29 @@ namespace SparkleLib {
|
|||
|
||||
public string UserName;
|
||||
public string UserEmail;
|
||||
|
||||
public string Folder;
|
||||
public string Revision;
|
||||
public DateTime Timestamp;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,9 @@ namespace SparkleShare {
|
|||
string html = reader.ReadToEnd ();
|
||||
reader.Close ();
|
||||
|
||||
html = html.Replace ("<!-- $jquery-url -->", "file://" +
|
||||
Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "jquery.js"));
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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\" />
|
||||
|
|
|
@ -114,8 +114,8 @@ namespace SparkleShare {
|
|||
bubble.Show ();
|
||||
|
||||
} else {
|
||||
NSApplication.SharedApplication.RequestUserAttention
|
||||
(NSRequestUserAttentionType.InformationalRequest);
|
||||
NSApplication.SharedApplication.RequestUserAttention (
|
||||
NSRequestUserAttentionType.InformationalRequest);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
@ -390,13 +396,34 @@ 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 (File.Exists (avatar_file_path)) {
|
||||
FileInfo avatar_info = new FileInfo (avatar_file_path);
|
||||
|
||||
// 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);
|
||||
|
||||
} else {
|
||||
return avatar_file_path;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!Directory.Exists (avatar_path)) {
|
||||
Directory.CreateDirectory (avatar_path);
|
||||
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
|
||||
}
|
||||
|
||||
// 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");
|
||||
foreach (string email in emails) {
|
||||
string avatar_file_path = Path.Combine (avatar_path, "avatar-" + email);
|
||||
|
||||
string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size);
|
||||
if (File.Exists (avatar_file_path)) {
|
||||
FileInfo avatar_info = new FileInfo (avatar_file_path);
|
||||
|
||||
if (!File.Exists (tmp_file_path)) {
|
||||
web_client.DownloadFileAsync (uri, tmp_file_path);
|
||||
// Delete avatars older than a month
|
||||
if (avatar_info.CreationTime < DateTime.Now.AddMonths (-1)) {
|
||||
avatar_info.Delete ();
|
||||
old_avatars.Add (email);
|
||||
}
|
||||
|
||||
web_client.DownloadFileCompleted += delegate {
|
||||
if (File.Exists (avatar_file_path))
|
||||
File.Delete (avatar_file_path);
|
||||
} else {
|
||||
WebClient client = new WebClient ();
|
||||
string url = "http://gravatar.com/avatar/" + GetMD5 (email) +
|
||||
".jpg?s=" + size + "&d=404";
|
||||
|
||||
FileInfo tmp_file_info = new FileInfo (tmp_file_path);
|
||||
try {
|
||||
// Fetch the avatar
|
||||
byte [] buffer = client.DownloadData (url);
|
||||
|
||||
if (tmp_file_info.Length > 255)
|
||||
File.Move (tmp_file_path, avatar_file_path);
|
||||
// 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);
|
||||
}
|
||||
|
||||
SparkleHelpers.DebugInfo ("Controller", "Fetched gravatar: " + email);
|
||||
} catch (WebException) {
|
||||
SparkleHelpers.DebugInfo ("Controller", "Failed fetching gravatar for " + email);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AvatarFetched != 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 ();
|
||||
};
|
||||
}
|
||||
|
||||
// Fall back to a generic icon if there is no gravatar
|
||||
if (File.Exists (avatar_file_path))
|
||||
|
||||
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;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -167,7 +167,12 @@ namespace SparkleShare {
|
|||
string path = SparkleHelpers.CombineMore (Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "event-log.html");
|
||||
|
||||
return String.Join (Environment.NewLine, File.ReadAllLines (path));
|
||||
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 html;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
dist_html_DATA = \
|
||||
day-entry.html \
|
||||
event-entry.html \
|
||||
event-log.html
|
||||
event-log.html \
|
||||
jquery.js
|
||||
|
||||
htmldir = $(pkgdatadir)/html/
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
@ -31,7 +77,6 @@
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: <!-- $a-color -->;
|
||||
text-decoration: none;
|
||||
|
@ -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,6 +95,7 @@
|
|||
padding: 3px 15px;
|
||||
font-weight: bold;
|
||||
-webkit-border-radius: 100px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.event-entry-content {
|
||||
|
@ -57,12 +103,11 @@
|
|||
background-color: #f0f0f0;
|
||||
margin-bottom: 12px;
|
||||
padding: 0px;
|
||||
padding-bottom: 6px;
|
||||
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
18
data/html/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue