Merge branch 'logstyle'
|
@ -19,8 +19,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
|
@ -122,8 +120,6 @@ namespace SparkleLib {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching notes");
|
|
||||||
SyncDown ();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +382,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
|
List <SparkleChangeSet> change_sets = new List <SparkleChangeSet> ();
|
||||||
|
|
||||||
SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso --show-notes=*");
|
SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw -M --date=iso");
|
||||||
Console.OutputEncoding = System.Text.Encoding.Unicode;
|
Console.OutputEncoding = System.Text.Encoding.Unicode;
|
||||||
git_log.Start ();
|
git_log.Start ();
|
||||||
|
|
||||||
|
@ -448,7 +444,6 @@ namespace SparkleLib {
|
||||||
change_set.UserName = match.Groups [2].Value;
|
change_set.UserName = match.Groups [2].Value;
|
||||||
change_set.UserEmail = match.Groups [3].Value;
|
change_set.UserEmail = match.Groups [3].Value;
|
||||||
change_set.IsMerge = is_merge_commit;
|
change_set.IsMerge = is_merge_commit;
|
||||||
change_set.SupportsNotes = true;
|
|
||||||
|
|
||||||
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
|
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
|
||||||
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
|
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
|
||||||
|
@ -471,7 +466,7 @@ namespace SparkleLib {
|
||||||
string file_path = entry_line.Substring (39);
|
string file_path = entry_line.Substring (39);
|
||||||
string to_file_path;
|
string to_file_path;
|
||||||
|
|
||||||
if (change_type.Equals ("A")) {
|
if (change_type.Equals ("A") && !file_path.Contains (".notes")) {
|
||||||
change_set.Added.Add (file_path);
|
change_set.Added.Add (file_path);
|
||||||
|
|
||||||
} else if (change_type.Equals ("M")) {
|
} else if (change_type.Equals ("M")) {
|
||||||
|
@ -488,32 +483,18 @@ namespace SparkleLib {
|
||||||
change_set.MovedFrom.Add (file_path);
|
change_set.MovedFrom.Add (file_path);
|
||||||
change_set.MovedTo.Add (to_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((change_set.Added.Count +
|
||||||
|
change_set.Edited.Count +
|
||||||
|
change_set.Deleted.Count) > 0) {
|
||||||
|
|
||||||
|
change_set.Notes.AddRange (GetNotes (change_set.Revision));
|
||||||
change_sets.Add (change_set);
|
change_sets.Add (change_set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return change_sets;
|
return change_sets;
|
||||||
}
|
}
|
||||||
|
@ -587,59 +568,6 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void AddNote (string revision, string note)
|
|
||||||
{
|
|
||||||
string url = SparkleConfig.DefaultConfig.GetUrlForFolder (Name);
|
|
||||||
|
|
||||||
if (url.StartsWith ("git") || url.StartsWith ("http"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
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
|
public override bool UsesNotificationCenter
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
|
@ -654,15 +582,5 @@ namespace SparkleLib {
|
||||||
base.CreateInitialChangeSet ();
|
base.CreateInitialChangeSet ();
|
||||||
SyncUp ();
|
SyncUp ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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 ("-", "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ namespace SparkleLib {
|
||||||
public string Folder;
|
public string Folder;
|
||||||
public string Revision;
|
public string Revision;
|
||||||
public DateTime Timestamp;
|
public DateTime Timestamp;
|
||||||
public bool SupportsNotes = false;
|
|
||||||
public bool IsMerge = false;
|
public bool IsMerge = false;
|
||||||
|
|
||||||
public List<string> Added = new List<string> ();
|
public List<string> Added = new List<string> ();
|
||||||
|
@ -38,6 +37,39 @@ namespace SparkleLib {
|
||||||
public List<string> MovedTo = new List<string> ();
|
public List<string> MovedTo = new List<string> ();
|
||||||
|
|
||||||
public List<SparkleNote> Notes = new List<SparkleNote> ();
|
public List<SparkleNote> Notes = new List<SparkleNote> ();
|
||||||
|
|
||||||
|
public string RelativeTimestamp {
|
||||||
|
get {
|
||||||
|
TimeSpan time_span = DateTime.Now - Timestamp;
|
||||||
|
|
||||||
|
if (time_span <= TimeSpan.FromSeconds (60))
|
||||||
|
return "just now";
|
||||||
|
|
||||||
|
if (time_span <= TimeSpan.FromMinutes (60))
|
||||||
|
return time_span.Minutes > 1
|
||||||
|
? time_span.Minutes + " minutes ago"
|
||||||
|
: "a minute ago";
|
||||||
|
|
||||||
|
if (time_span <= TimeSpan.FromHours (24))
|
||||||
|
return time_span.Hours > 1
|
||||||
|
? time_span.Hours + " hours ago"
|
||||||
|
: "an hour ago";
|
||||||
|
|
||||||
|
if (time_span <= TimeSpan.FromDays (30))
|
||||||
|
return time_span.Days > 1
|
||||||
|
? time_span.Days + " days ago"
|
||||||
|
: "a day ago";
|
||||||
|
|
||||||
|
if (time_span <= TimeSpan.FromDays (365))
|
||||||
|
return time_span.Days > 30
|
||||||
|
? (time_span.Days / 30) + " months ago"
|
||||||
|
: "a month ago";
|
||||||
|
|
||||||
|
return time_span.Days > 365
|
||||||
|
? (time_span.Days / 365) + " years ago"
|
||||||
|
: "a year ago";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
@ -109,10 +111,8 @@ namespace SparkleLib {
|
||||||
|
|
||||||
// In the unlikely case that we haven't synced up our
|
// In the unlikely case that we haven't synced up our
|
||||||
// changes or the server was down, sync up again
|
// changes or the server was down, sync up again
|
||||||
if (HasUnsyncedChanges) {
|
if (HasUnsyncedChanges)
|
||||||
SyncUpBase ();
|
SyncUpBase ();
|
||||||
SyncUpNotes ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sync up everything that changed
|
// Sync up everything that changed
|
||||||
|
@ -239,10 +239,8 @@ namespace SparkleLib {
|
||||||
SyncDownBase ();
|
SyncDownBase ();
|
||||||
|
|
||||||
// Push changes that were made since the last disconnect
|
// Push changes that were made since the last disconnect
|
||||||
if (HasUnsyncedChanges) {
|
if (HasUnsyncedChanges)
|
||||||
SyncUpBase ();
|
SyncUpBase ();
|
||||||
SyncUpNotes ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start polling when the connection to the irc channel is lost
|
// Start polling when the connection to the irc channel is lost
|
||||||
|
@ -310,7 +308,8 @@ namespace SparkleLib {
|
||||||
if (!this.watcher.EnableRaisingEvents)
|
if (!this.watcher.EnableRaisingEvents)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (args.FullPath.Contains (Path.DirectorySeparatorChar + "."))
|
if (args.FullPath.Contains (Path.DirectorySeparatorChar + ".") &&
|
||||||
|
!args.FullPath.Contains (Path.DirectorySeparatorChar + ".notes"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WatcherChangeTypes wct = args.ChangeType;
|
WatcherChangeTypes wct = args.ChangeType;
|
||||||
|
@ -337,6 +336,42 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<SparkleNote> GetNotes (string revision) {
|
||||||
|
List<SparkleNote> notes = new List<SparkleNote> ();
|
||||||
|
|
||||||
|
string notes_path = Path.Combine (LocalPath, ".notes");
|
||||||
|
|
||||||
|
if (!Directory.Exists (notes_path))
|
||||||
|
Directory.CreateDirectory (notes_path);
|
||||||
|
|
||||||
|
Regex regex_notes = new Regex (@"<name>(.+)</name>.*" +
|
||||||
|
"<email>(.+)</email>.*" +
|
||||||
|
"<timestamp>([0-9]+)</timestamp>.*" +
|
||||||
|
"<body>(.+)</body>", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
foreach (string file_path in Directory.GetFiles (notes_path)) {
|
||||||
|
if (Path.GetFileName (file_path).StartsWith (revision)) {
|
||||||
|
string note_xml = String.Join ("", File.ReadAllLines (file_path));
|
||||||
|
|
||||||
|
Match match_notes = regex_notes.Match (note_xml);
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
notes.Add (note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void SyncUpBase ()
|
private void SyncUpBase ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -452,15 +487,41 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual void AddNote (string revision, string note)
|
public void AddNote (string revision, string note)
|
||||||
{
|
{
|
||||||
|
string notes_path = Path.Combine (LocalPath, ".notes");
|
||||||
|
|
||||||
}
|
if (!Directory.Exists (notes_path))
|
||||||
|
Directory.CreateDirectory (notes_path);
|
||||||
|
|
||||||
|
// Add a timestamp in seconds since unix epoch
|
||||||
|
int timestamp = (int) (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
|
||||||
|
|
||||||
|
string n = Environment.NewLine;
|
||||||
|
note = "<note>" + n +
|
||||||
|
" <user>" + n +
|
||||||
|
" <name>" + SparkleConfig.DefaultConfig.UserName + "</name>" + n +
|
||||||
|
" <email>" + SparkleConfig.DefaultConfig.UserEmail + "</email>" + n +
|
||||||
|
" </user>" + n +
|
||||||
|
" <timestamp>" + timestamp + "</timestamp>" + n +
|
||||||
|
" <body>" + note + "</body>" + n +
|
||||||
|
"</note>" + n;
|
||||||
|
|
||||||
|
string note_name = revision + SHA1 (timestamp.ToString () + note);
|
||||||
|
string note_path = Path.Combine (notes_path, note_name);
|
||||||
|
|
||||||
|
StreamWriter writer = new StreamWriter (note_path);
|
||||||
|
writer.Write (note);
|
||||||
|
writer.Close ();
|
||||||
|
|
||||||
|
|
||||||
public virtual void SyncUpNotes ()
|
// The watcher doesn't like .*/ so we need to trigger
|
||||||
{
|
// a change manually
|
||||||
|
FileSystemEventArgs args = new FileSystemEventArgs (WatcherChangeTypes.Changed,
|
||||||
|
notes_path, note_name);
|
||||||
|
|
||||||
|
OnFileActivity (args);
|
||||||
|
SparkleHelpers.DebugInfo ("Note", "Added note to " + revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,5 +550,15 @@ namespace SparkleLib {
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 ("-", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,6 +264,9 @@
|
||||||
<Content Include="..\..\data\about.png">
|
<Content Include="..\..\data\about.png">
|
||||||
<Link>Pixmaps\about.png</Link>
|
<Link>Pixmaps\about.png</Link>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="..\..\data\html\jquery.js">
|
||||||
|
<Link>HTML\jquery.js</Link>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Pixmaps\" />
|
<Folder Include="Pixmaps\" />
|
||||||
|
|
|
@ -312,7 +312,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
new Thread (new ThreadStart (delegate {
|
new Thread (new ThreadStart (delegate {
|
||||||
FetchAvatars (emails, 36);
|
FetchAvatars (emails, 48);
|
||||||
})).Start ();
|
})).Start ();
|
||||||
|
|
||||||
string event_log_html = EventLogHTML;
|
string event_log_html = EventLogHTML;
|
||||||
|
@ -336,9 +336,9 @@ namespace SparkleShare {
|
||||||
change_set.Folder, file_path);
|
change_set.Folder, file_path);
|
||||||
|
|
||||||
if (File.Exists (absolute_file_path))
|
if (File.Exists (absolute_file_path))
|
||||||
event_entry += "<dd class='document-edited'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
event_entry += "<dd class='document edited'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
else
|
else
|
||||||
event_entry += "<dd class='document-edited'>" + file_path + "</dd>";
|
event_entry += "<dd class='document edited'>" + file_path + "</dd>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,9 +348,9 @@ namespace SparkleShare {
|
||||||
change_set.Folder, file_path);
|
change_set.Folder, file_path);
|
||||||
|
|
||||||
if (File.Exists (absolute_file_path))
|
if (File.Exists (absolute_file_path))
|
||||||
event_entry += "<dd class='document-added'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
event_entry += "<dd class='document added'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
else
|
else
|
||||||
event_entry += "<dd class='document-added'>" + file_path + "</dd>";
|
event_entry += "<dd class='document added'>" + file_path + "</dd>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,9 +360,9 @@ namespace SparkleShare {
|
||||||
change_set.Folder, file_path);
|
change_set.Folder, file_path);
|
||||||
|
|
||||||
if (File.Exists (absolute_file_path))
|
if (File.Exists (absolute_file_path))
|
||||||
event_entry += "<dd class='document-deleted'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
event_entry += "<dd class='document deleted'><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
else
|
else
|
||||||
event_entry += "<dd class='document-deleted'>" + file_path + "</dd>";
|
event_entry += "<dd class='document deleted'>" + file_path + "</dd>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,9 +376,9 @@ namespace SparkleShare {
|
||||||
change_set.Folder, to_file_path);
|
change_set.Folder, to_file_path);
|
||||||
|
|
||||||
if (File.Exists (absolute_file_path))
|
if (File.Exists (absolute_file_path))
|
||||||
event_entry += "<dd class='document-moved'><a href='" + absolute_file_path + "'>" + file_path + "</a><br/>";
|
event_entry += "<dd class='document moved'><a href='" + absolute_file_path + "'>" + file_path + "</a><br/>";
|
||||||
else
|
else
|
||||||
event_entry += "<dd class='document-moved'>" + file_path + "<br/>";
|
event_entry += "<dd class='document moved'>" + file_path + "<br/>";
|
||||||
|
|
||||||
if (File.Exists (absolute_to_file_path))
|
if (File.Exists (absolute_to_file_path))
|
||||||
event_entry += "<a href='" + absolute_to_file_path + "'>" + to_file_path + "</a></dd>";
|
event_entry += "<a href='" + absolute_to_file_path + "'>" + to_file_path + "</a></dd>";
|
||||||
|
@ -391,34 +391,31 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
string comments = "";
|
string comments = "";
|
||||||
if (change_set.SupportsNotes) {
|
comments = "<div class=\"comments\">";
|
||||||
comments = "<table class=\"comments\">";
|
|
||||||
|
|
||||||
if (change_set.Notes != null) {
|
if (change_set.Notes != null) {
|
||||||
change_set.Notes.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
|
change_set.Notes.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
|
||||||
|
|
||||||
foreach (SparkleNote note in change_set.Notes) {
|
foreach (SparkleNote note in change_set.Notes) {
|
||||||
comments += "<tr>" +
|
comments += "<div class=\"comment-text\">" +
|
||||||
" <td class=\"comment-author\">" + note.UserName + "</td>" +
|
"<p class=\"comment-author\"" +
|
||||||
" <td class=\"comment-timestamp\">" + note.Timestamp.ToString ("d MMM") + "</td>" +
|
" style=\"background-image: url('file://" + GetAvatar (note.UserEmail, 48) + "');\">" +
|
||||||
"</tr>" +
|
note.UserName + "</p>" +
|
||||||
"<tr>" +
|
note.Body +
|
||||||
" <td class=\"comment-text\" colspan=\"2\">" + note.Body + "</td>" +
|
"</div>";
|
||||||
"</tr>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
comments += "</table>";
|
comments += "</div>";
|
||||||
}
|
|
||||||
|
|
||||||
string avatar_email = "";
|
string avatar_email = "";
|
||||||
if (File.Exists (GetAvatar (change_set.UserEmail, 36)))
|
if (File.Exists (GetAvatar (change_set.UserEmail, 48)))
|
||||||
avatar_email = change_set.UserEmail;
|
avatar_email = change_set.UserEmail;
|
||||||
|
|
||||||
event_entry += "</dl>";
|
event_entry += "</dl>";
|
||||||
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
|
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
|
||||||
.Replace ("<!-- $event-user-name -->", change_set.UserName)
|
.Replace ("<!-- $event-user-name -->", change_set.UserName)
|
||||||
.Replace ("<!-- $event-avatar-url -->", "file://" + GetAvatar (avatar_email, 36))
|
.Replace ("<!-- $event-avatar-url -->", "file://" + GetAvatar (avatar_email, 48))
|
||||||
.Replace ("<!-- $event-time -->", change_set.Timestamp.ToString ("H:mm"))
|
.Replace ("<!-- $event-time -->", change_set.Timestamp.ToString ("H:mm"))
|
||||||
.Replace ("<!-- $event-folder -->", change_set.Folder)
|
.Replace ("<!-- $event-folder -->", change_set.Folder)
|
||||||
.Replace ("<!-- $event-revision -->", change_set.Revision)
|
.Replace ("<!-- $event-revision -->", change_set.Revision)
|
||||||
|
@ -434,32 +431,35 @@ namespace SparkleShare {
|
||||||
today.Month == activity_day.DateTime.Month &&
|
today.Month == activity_day.DateTime.Month &&
|
||||||
today.Year == activity_day.DateTime.Year) {
|
today.Year == activity_day.DateTime.Year) {
|
||||||
|
|
||||||
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", "<b>Today</b>");
|
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", "Today");
|
||||||
|
|
||||||
} else if (yesterday.Day == activity_day.DateTime.Day &&
|
} else if (yesterday.Day == activity_day.DateTime.Day &&
|
||||||
yesterday.Month == activity_day.DateTime.Month &&
|
yesterday.Month == activity_day.DateTime.Month &&
|
||||||
yesterday.Year == activity_day.DateTime.Year) {
|
yesterday.Year == activity_day.DateTime.Year) {
|
||||||
|
|
||||||
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", "<b>Yesterday</b>");
|
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->", "Yesterday");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (activity_day.DateTime.Year != DateTime.Now.Year) {
|
if (activity_day.DateTime.Year != DateTime.Now.Year) {
|
||||||
// TRANSLATORS: This is the date in the event logs
|
// TRANSLATORS: This is the date in the event logs
|
||||||
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
|
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
|
||||||
"<b>" + activity_day.DateTime.ToString (_("ddd MMM d, yyyy")) + "</b>");
|
activity_day.DateTime.ToString (_("dddd, MMMM d, yyyy")));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TRANSLATORS: This is the date in the event logs, without the year
|
// TRANSLATORS: This is the date in the event logs, without the year
|
||||||
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
|
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
|
||||||
"<b>" + activity_day.DateTime.ToString (_("ddd MMM d")) + "</b>");
|
activity_day.DateTime.ToString (_("dddd, MMMM d")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event_log += day_entry.Replace ("<!-- $day-entry-content -->", event_entries);
|
event_log += day_entry.Replace ("<!-- $day-entry-content -->", event_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_log_html.Replace ("<!-- $event-log-content -->", event_log)
|
string html = event_log_html.Replace ("<!-- $event-log-content -->", event_log)
|
||||||
.Replace ("<!-- $username -->", UserName);
|
.Replace ("<!-- $username -->", UserName)
|
||||||
|
.Replace ("<!-- $user-avatar-url -->", "file://" + GetAvatar (UserEmail, 48));
|
||||||
|
|
||||||
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@ SUBDIRS = \
|
||||||
html
|
html
|
||||||
|
|
||||||
dist_pixmaps_DATA = \
|
dist_pixmaps_DATA = \
|
||||||
sparkleshare-gnome.svg \
|
|
||||||
sparkleshare-mist.svg \
|
|
||||||
side-splash.png \
|
side-splash.png \
|
||||||
about.png
|
about.png
|
||||||
|
|
||||||
|
|
1960
data/actions.svg
Before Width: | Height: | Size: 64 KiB |
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
|
|
||||||
<sparkleshare_invitation>
|
|
||||||
|
|
||||||
<server>git.gnome.org</server>
|
|
||||||
<folder>gnome-design</folder>
|
|
||||||
<token>a22bc6f4b9ffe8e5acd4be0838d41aa10a1187dd</token>
|
|
||||||
|
|
||||||
</sparkleshare_invitation>
|
|
|
@ -1,29 +1,22 @@
|
||||||
<div class='event-entry'>
|
<div class='event-entry' style='background-image: url("<!-- $event-avatar-url -->");'>
|
||||||
<div class='event-entry-content'>
|
<div class='event-user-name'><!-- $event-user-name --></div>
|
||||||
<div class='event-info'>
|
<div class='event-folder'><!-- $event-folder --></div>
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='no-buddy-icon'>
|
|
||||||
<div class='buddy-icon' style='background-image: url("<!-- $event-avatar-url -->");'></div>
|
|
||||||
</div>
|
|
||||||
<b><!-- $event-user-name --></b><br/>
|
|
||||||
<small><!-- $event-time --></small>
|
|
||||||
</div>
|
|
||||||
<span title="<!-- $event-revision -->">
|
|
||||||
<div class='event-folder' style='background-color: <!-- $event-folder-color -->'><!-- $event-folder --></div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<!-- $event-entry-content -->
|
<!-- $event-entry-content -->
|
||||||
|
|
||||||
|
<div class="clearer"></div>
|
||||||
|
<div class="event-timestamp"><!-- $event-time --></div>
|
||||||
|
<div class="action note">Add note</div>
|
||||||
|
<div class="action show">Show all</div>
|
||||||
|
|
||||||
|
<div class="clearer"></div>
|
||||||
|
|
||||||
<div class="comments-section">
|
<div class="comments-section">
|
||||||
<div class="comments-wrapper">
|
|
||||||
<!-- $event-comments -->
|
<!-- $event-comments -->
|
||||||
<textarea class="comment-textarea"></textarea>
|
<textarea class="comment-textarea"></textarea>
|
||||||
|
|
||||||
<input class="comment-button" type="button" value="Add note"
|
<input class="comment-button" type="button" value="Add note"
|
||||||
id="<!-- $event-folder -->~<!-- $event-revision -->">
|
id="<!-- $event-folder -->~<!-- $event-revision -->">
|
||||||
<div style='clear: both'></div>
|
<div style='clear: both'></div>
|
||||||
</div>
|
</div>
|
||||||
<div style='clear: both'></div>
|
<div class="clearer"></div>
|
||||||
</div>
|
|
||||||
<div style='clear: both'></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,11 +5,9 @@
|
||||||
<script type="text/javascript" src="<!-- $jquery-url -->"></script>
|
<script type="text/javascript" src="<!-- $jquery-url -->"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.comments-wrapper').each (function () {
|
$('.comments-section').each (function () {
|
||||||
if ($(this).find ('.comments').children ().size () < 1) {
|
if ($(this).find ('.comments').children ().size () < 1) {
|
||||||
$(this).hide ();
|
$(this).hide ();
|
||||||
} else {
|
|
||||||
$(this).css ('cursor', 'default');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,9 +17,27 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.comments-section').click(function () {
|
// Show the form when 'Add note' is clicked
|
||||||
$(this).find ('.comments-wrapper').show ();
|
$('.note').click(function () {
|
||||||
$(this).find ('.comments-wrapper').css ('cursor', 'default');
|
$(this).parent ().find ('.comments-section').show ();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hide the 'Show all' link when there are less than 10 events
|
||||||
|
$('.show').each (function () {
|
||||||
|
var entries = $(this).parent ().find ('dl').children ().length;
|
||||||
|
|
||||||
|
if (entries <= 10) {
|
||||||
|
$(this).hide ();
|
||||||
|
} else {
|
||||||
|
// Append the number of entries
|
||||||
|
$(this).html ('Show all ' + entries);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// When 'Show all' is clicked, show all collapsed events
|
||||||
|
$('.show').click(function () {
|
||||||
|
$(this).parent ().find ('dl').children ().show ();
|
||||||
|
$(this).hide ();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("input").click(function () {
|
$("input").click(function () {
|
||||||
|
@ -31,27 +47,36 @@
|
||||||
if (text == '')
|
if (text == '')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Clear the textarea
|
||||||
textarea.val ('');
|
textarea.val ('');
|
||||||
|
|
||||||
table = $(this).parent ().find ("table");
|
table = $(this).parent ().find (".comments");
|
||||||
comments = table.html ();
|
comments = table.html ();
|
||||||
comments += '<tr>' +
|
|
||||||
' <td class=\"comment-author\"><!-- $username --></td>' +
|
// Add the note to the html
|
||||||
' <td class=\"comment-timestamp\">just now</td>' +
|
comments += '<div class="comment-text">' +
|
||||||
'</tr>' +
|
'<p class="comment-author"' +
|
||||||
'<tr>' +
|
' style="background-image: url(\'<!-- $user-avatar-url -->\');">' +
|
||||||
' <td class=\"comment-text\" colspan=\"2\">' + text + '</td>' +
|
'<!-- $username --></p>' +
|
||||||
'</tr>';
|
text +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
table.html (comments);
|
table.html (comments);
|
||||||
|
|
||||||
|
// Feed the note to the backend
|
||||||
location = this.id + '~' + text;
|
location = this.id + '~' + text;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #dedede;
|
background-color: #fff;
|
||||||
color: <!-- $body-color -->;
|
color: <!-- $body-color -->;
|
||||||
font-size: <!-- $body-font-size -->;
|
font-size: <!-- $body-font-size -->;
|
||||||
font-family: <!-- $body-font-family -->;
|
font-family: <!-- $body-font-family -->;
|
||||||
|
@ -69,18 +94,25 @@
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
.comment-text {
|
||||||
vertical-align: top;
|
font-size: 90%;
|
||||||
font-size: 12px;
|
padding: 12px;
|
||||||
|
background-color: #FFF4DB;
|
||||||
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-entry-header {
|
.day-entry-header {
|
||||||
font-size: <!-- $day-entry-header-font-size -->;
|
color: #aaa;
|
||||||
color: #444;
|
|
||||||
padding: 18px;
|
|
||||||
padding-top: 9px;
|
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 36px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day-entry-content .event-entry:last-child {
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -92,104 +124,147 @@
|
||||||
color: <!-- $a-hover-color -->;
|
color: <!-- $a-hover-color -->;
|
||||||
}
|
}
|
||||||
|
|
||||||
.event-folder {
|
.event-timestamp {
|
||||||
margin: 6px;
|
|
||||||
opacity: 0.8;
|
|
||||||
font-size: 80%;
|
|
||||||
color: #fff;
|
|
||||||
float: right;
|
|
||||||
padding: 3px 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
-webkit-border-radius: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.event-entry-content {
|
|
||||||
display: block;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding: 0px;
|
|
||||||
border: #ccc 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
margin: 9px;
|
|
||||||
float: left;
|
float: left;
|
||||||
|
font-size: 80%;
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-user-name {
|
||||||
|
float: left;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-folder {
|
||||||
|
float: right;
|
||||||
|
color: <!-- $secondary-font-color -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-entry {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding-bottom: 24px;
|
||||||
|
border-bottom: 1px <!-- $secondary-font-color --> solid;
|
||||||
|
width: 90%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding-left: 72px;
|
||||||
|
padding-right: 12px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 12px top;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
font-size: 80%;
|
||||||
|
margin-left: 15px;
|
||||||
|
float: right;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
color: <!-- $a-color -->;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action:hover {
|
||||||
|
color: <!-- $a-hover-color -->;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clearer {
|
||||||
|
clear: both;
|
||||||
|
backround-color: blue;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
clear: both;
|
||||||
|
border-bottom: 1px #ccc solid;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
dl {
|
dl {
|
||||||
padding : 0;
|
padding : 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-top: 6px;
|
||||||
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
width: 90%;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
width: 90%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 2px;
|
||||||
padding-left: 22px;
|
padding-left: 20px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 1px;
|
||||||
margin-left: 12px;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center left;
|
background-position: center left;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd:last-child {
|
dl dd:nth-child(-n+10) {
|
||||||
border: none;
|
display: block;
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-added {
|
.document {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.added {
|
||||||
background-image: url('<!-- $document-added-background-image -->');
|
background-image: url('<!-- $document-added-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-deleted {
|
.deleted {
|
||||||
background-image: url('<!-- $document-deleted-background-image -->');
|
background-image: url('<!-- $document-deleted-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-edited {
|
.edited {
|
||||||
background-image: url('<!-- $document-edited-background-image -->');
|
background-image: url('<!-- $document-edited-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-moved {
|
.moved {
|
||||||
background-image: url('<!-- $document-moved-background-image -->');
|
background-image: url('<!-- $document-moved-background-image -->');
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-buddy-icon {
|
.no-buddy-icon {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
width: 36px;
|
width: 48px;
|
||||||
background-image: url('<!-- $no-buddy-icon-background-image -->');
|
background-image: url('<!-- $no-buddy-icon-background-image -->');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top center;
|
background-position: top center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buddy-icon {
|
.buddy-icon {
|
||||||
width: 36px;
|
width: 48px;
|
||||||
height: 36px;
|
height: 48px;
|
||||||
}
|
|
||||||
|
|
||||||
.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 {
|
.comments {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
font-size: 90%;
|
||||||
|
margin-bottom: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-author {
|
.comment-author {
|
||||||
|
font-size: 90%;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
width: 75%;
|
margin: 0;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: bottom left;
|
||||||
|
background-size: 24px;
|
||||||
|
height: 24px;
|
||||||
|
padding-left: 30px;
|
||||||
|
line-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-timestamp {
|
.comment-timestamp {
|
||||||
|
@ -200,34 +275,27 @@
|
||||||
.comment-button {
|
.comment-button {
|
||||||
float:right;
|
float:right;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-textarea {
|
.comment-textarea {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50px;
|
height: 3em;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-section {
|
.comments-section {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
border-top: 1px #ccc solid;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 9px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-wrapper {
|
.comments-wrapper {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 12px;
|
margin-top: 12px;
|
||||||
}
|
|
||||||
|
|
||||||
.comments-section:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-text {
|
.comment-text {
|
||||||
|
|
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 498 B |
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
21204
data/src/actions.svg
Normal file
After Width: | Height: | Size: 682 KiB |
Before Width: | Height: | Size: 841 KiB After Width: | Height: | Size: 841 KiB |
Before Width: | Height: | Size: 913 KiB After Width: | Height: | Size: 913 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 458 KiB |