From 62c278a6390fbab69eab9006ad142ee24fb76a3d Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sat, 17 Nov 2018 16:50:01 +0000
Subject: [PATCH] Support multiple reminders for the same time This is done by
 offsetting duplicate reminders by 1ms

---
 RhinoReminds/ClientListener.cs |  9 ++++---
 RhinoReminds/ReminderList.cs   | 47 +++++++++++++++++++++++-----------
 2 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/RhinoReminds/ClientListener.cs b/RhinoReminds/ClientListener.cs
index 9d40093..6f8f048 100644
--- a/RhinoReminds/ClientListener.cs
+++ b/RhinoReminds/ClientListener.cs
@@ -112,13 +112,16 @@ namespace RhinoReminds
 				case "list":
 				case "show":
 					if (parts.Select((n) => n.ToLower()).Contains("all")) {
-						// TODO: Make sure that you can't see other people's reminders
+						// Filter by reminders for this user.
+						IEnumerable<Reminder> userReminderList = reminderList.Reminders.Values.Where(
+							(Reminder next) => message.From.GetBareJid() == next.JidObj.GetBareJid()
+						);
 						StringBuilder listMessage = new StringBuilder("I've got the following reminders on my list:\n");
-						foreach (Reminder nextReminder in reminderList.Reminders.Values) {
+						foreach (Reminder nextReminder in userReminderList) {
 							listMessage.AppendLine($" - {nextReminder.Message} at {nextReminder.Time}");
 						}
 						listMessage.AppendLine();
-						listMessage.AppendLine($"({reminderList.Reminders.Count} total)");
+						listMessage.AppendLine($"({userReminderList.Count()} total)");
 						sendChatReply(message, listMessage.ToString());
 						return;
 					}
diff --git a/RhinoReminds/ReminderList.cs b/RhinoReminds/ReminderList.cs
index f93caa1..a7fa432 100644
--- a/RhinoReminds/ReminderList.cs
+++ b/RhinoReminds/ReminderList.cs
@@ -23,19 +23,42 @@ namespace RhinoReminds
 
 		}
 
+
 		public Reminder CreateReminder(Jid inJid, DateTime time, string message) {
 			Reminder result = new Reminder(nextId++, $"{inJid.Node}@{inJid.Domain}", time, message);
 			Console.WriteLine($"[Rhino/ReminderList] Created reminder {result}");
+			while (Reminders.ContainsKey(time)) {
+				Console.WriteLine($"[Rhino/ReminderList] Reminder list contained {time}, adding 1ms");
+				time = time.AddMilliseconds(1);
+			}
 			Reminders.Add(time, result);
 			OnReminderListUpdate(this, result);
 			return result;
 		}
 
+
+		public Reminder GetNextReminder()
+		{
+			if (Reminders.Count == 0)
+				return null;
+
+			return Reminders.Values[0];
+		}
+
+		public void DeleteReminder(Reminder nextReminder)
+		{
+			Reminders.Remove(nextReminder.Time);
+		}
+
+
+		#region Persistence
+
 		public void Save(string filename)
 		{
 			// Make sure that the reminder thread doesn't try to save the reminders at the exact same time
 			// we receive a request for a new reminder
-			lock (saveLock) { // FUTURE: We could go lockless here with some work, but it's not worth it for the teeny chance & low overhead 
+			lock (saveLock)
+			{ // FUTURE: We could go lockless here with some work, but it's not worth it for the teeny chance & low overhead 
 				XmlWriter xml = XmlWriter.Create(
 					filename,
 					new XmlWriterSettings() { Indent = true }
@@ -57,18 +80,6 @@ namespace RhinoReminds
 			}
 		}
 
-		public Reminder GetNextReminder()
-		{
-			if (Reminders.Count == 0)
-				return null;
-
-			return Reminders.Values[0];
-		}
-
-		public void DeleteReminder(Reminder nextReminder) {
-			Reminders.Remove(nextReminder.Time);
-		}
-
 		public static ReminderList FromXmlFile(string filepath)
 		{
 			XmlDocument xml = new XmlDocument();
@@ -76,12 +87,18 @@ namespace RhinoReminds
 
 			ReminderList result = new ReminderList();
 			result.nextId = int.Parse(xml.GetElementsByTagName("NextId")[0].InnerText);
-			foreach (XmlNode reminderXML in xml.GetElementsByTagName("Reminders")[0].ChildNodes) {
+			foreach (XmlNode reminderXML in xml.GetElementsByTagName("Reminders")[0].ChildNodes)
+			{
 				Reminder nextReminder = Reminder.FromXml(reminderXML);
-				result.Reminders.Add(nextReminder.Time, nextReminder);
+				DateTime timeKey = nextReminder.Time;
+				while (result.Reminders.ContainsKey(timeKey))
+					timeKey = timeKey.AddMilliseconds(1);
+				result.Reminders.Add(timeKey, nextReminder);
 			}
 
 			return result;
 		}
+
+		#endregion
 	}
 }
