Skip to content

Commit

Permalink
Added a timestamp notice at the bottom of the editor (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
NikkelM committed Aug 12, 2023
1 parent a3b9839 commit 5d86798
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 19 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# Changelog

## v1.2.2
## v1.2.3

<!--Releasenotes start-->
- Updated the settings icon's file format to ensure cross-browser compatibility.
- When opening the Add-In window, the most recently edited note is now opened.
- Added a display for when the current note was last edited.
- Fixed some layouting on the settings page.
<!--Releasenotes end-->

## v1.2.2

- Updated the settings icon's file format to ensure cross-browser compatibility.

## v1.2.1

- Only relevant customization options - depending on other chosen settings - will now be shown.
Expand Down
50 changes: 47 additions & 3 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import Quill from "quill";
import { focusEditor } from "./editor";
import { getIdentifiers, getSettings } from "./officeData";

// Text element showing when the current note was last edited
const lastEditedNotice: HTMLParagraphElement = document.getElementById("lastEditedNotice") as HTMLParagraphElement;

const contextButtons = {
mail: document.getElementById("emailContextButton"),
sender: document.getElementById("senderContextButton"),
Expand All @@ -14,8 +17,8 @@ let activeContext;

export function setupContextButtons(): void {
for (const [key, button] of Object.entries(contextButtons)) {
button.addEventListener("click", () => {
switchToContext(key);
button.addEventListener("click", async () => {
await switchToContext(key);
});
}
}
Expand Down Expand Up @@ -82,8 +85,49 @@ async function loadNoteForContext(context: string, quill?: Quill, itemId?: strin

const allNotes = await settings.get("notes");

let noteContents = allNotes[itemId]?.noteContents ?? null;
const noteContents = allNotes[itemId]?.noteContents ?? null;
quill.setContents(noteContents);

updateLastEditedNotice(itemId, allNotes);

focusEditor();
}

export function updateLastEditedNotice(itemId: string, allNotes: any): void {
let lastEdited = allNotes[itemId]?.lastEdited ?? null;

if (lastEdited) {
const date: any = new Date(lastEdited);
const now: any = new Date();
const today: any = new Date();
const yesterday: any = new Date(today);
yesterday.setDate(today.getDate() - 1);

const minuteDiff = Math.floor((now - date) / (1000 * 60));
const hourDiff = Math.floor((now - date) / (1000 * 60 * 60));
const dayDiff = Math.floor((now - date) / (1000 * 60 * 60 * 24));

let formattedDate;
if (minuteDiff < 1) {
formattedDate = "Just now";
} else if (hourDiff === 0) {
formattedDate = "Less than an hour ago";
} else if (date.toDateString() === today.toDateString()) {
formattedDate = "Today";
} else if (date.toDateString() === yesterday.toDateString()) {
formattedDate = "Yesterday";
} else if (dayDiff < 7) {
formattedDate = date.toLocaleDateString(navigator.language, { weekday: "long", month: "long", day: "numeric" });
} else {
formattedDate = date.toLocaleDateString(navigator.language, {
year: "numeric",
month: "long",
day: "numeric",
});
}

lastEditedNotice.innerHTML = `<i>Last edited: ${formattedDate}</i>`;
} else {
lastEditedNotice.innerText = "";
}
}
8 changes: 8 additions & 0 deletions src/css/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@
transform: rotate(360deg);
}
}

/* Last edited notice */
#lastEditedNotice {
width: 90%;
max-width: 90%;
margin: 0 5px 0 0;
font-size: 14px;
}
49 changes: 36 additions & 13 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Quill from "quill";
var Delta = Quill.import("delta");

import { getSettings, getIdentifiers } from "./officeData";
import { getActiveContext, switchToContext } from "./context";
import { getActiveContext, switchToContext, updateLastEditedNotice } from "./context";

export let quill: Quill;
let mailId: string, senderId: string, conversationId: string, itemSubject: string, itemNormalizedSubject: string;
Expand Down Expand Up @@ -60,30 +60,51 @@ function setupQuill(): void {
async function displayInitialNote(): Promise<void> {
// Try to get an existing note for any of the contexts, in descending priority/specificity
const allNotes = await settings.get("notes");
let mailNote = allNotes[mailId];
const conversationNote = allNotes[conversationId];
const senderNote = allNotes[senderId];
const relevantNotes = [
{
// This needs to be the first entry, to ensure the pre1_2_0Notes check works correctly
note: allNotes[mailId],
id: mailId,
context: "mail",
},
{
note: allNotes[conversationId],
id: conversationId,
context: "conversation",
},
{
note: allNotes[senderId],
id: senderId,
context: "sender",
},
];

// With v1.2.0, the mailId was changed from using the item.itemId to use item.conversationId_item.dateTimeCreated.toISOString()
// We need to check if the current item is still using the old ID format, and if so, update it
const pre1_2_0Notes = await settings.get("pre1_2_0Notes");
if (pre1_2_0Notes) {
console.log("Checking for pre-1.2.0 note");
mailNote = await pre1_2_0Update(Office.context.mailbox.item.itemId, allNotes, pre1_2_0Notes, settings);
mailId = await pre1_2_0Update(Office.context.mailbox.item.itemId, allNotes, pre1_2_0Notes, settings);
relevantNotes[0].id = mailId;
}

if (mailNote) {
await switchToContext("mail", quill, mailId, settings);
} else if (conversationNote) {
await switchToContext("conversation", quill, conversationId, settings);
} else if (senderNote) {
await switchToContext("sender", quill, senderId, settings);
relevantNotes.sort((a, b) => {
const dateA = new Date(a.note?.lastEdited ?? 0);
const dateB = new Date(b.note?.lastEdited ?? 0);
return dateB.getTime() - dateA.getTime();
});

if (relevantNotes[0].note) {
await switchToContext(relevantNotes[0].context, quill, relevantNotes[0].id, settings);
} else {
// The default context is the mail context
await switchToContext("mail", quill, mailId, settings);
}

manageNoteCategories(mailNote, conversationNote, senderNote);
const mail = relevantNotes.find((note) => note.context === "mail")?.note;
const conversation = relevantNotes.find((note) => note.context === "conversation")?.note;
const sender = relevantNotes.find((note) => note.context === "sender")?.note;
manageNoteCategories(mail, conversation, sender);
}

async function pre1_2_0Update(
Expand Down Expand Up @@ -188,14 +209,16 @@ async function saveNote(): Promise<void> {
} else {
allNotes[contextMapping[activeContext]] = allNotes[contextMapping[activeContext]] ?? {};
allNotes[contextMapping[activeContext]].noteContents = newNoteContents;
allNotes[contextMapping[activeContext]].lastEdited = new Date().toISOString().split("T")[0];
allNotes[contextMapping[activeContext]].lastEdited = new Date().toISOString();
}

// Save the note to storage
settings.set("notes", allNotes);
settings.saveAsync();
manageNoteCategories(allNotes[mailId], allNotes[conversationId], allNotes[senderId]);

updateLastEditedNotice(contextMapping[activeContext], allNotes);

// Hide the icon after a timeout
setTimeout(() => {
if (savingIcon.classList.contains("tick")) {
Expand Down
3 changes: 3 additions & 0 deletions src/taskpane.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ <h2>This isn't the page you're looking for...</h2>
<!-- Create the Quill container -->
<div id="noteInput"></div>

<!-- Displays when the current note was last edited -->
<p id="lastEditedNotice" class="align-right"></p>

<!-- Add a button that overlays the settings -->
<div id="settingsDiv" class="settings-div">
<p id="versionNumber" class="version-number"></p>
Expand Down
2 changes: 1 addition & 1 deletion src/versionUpdate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function updateVersion(settings: Office.RoamingSettings) {
pre1_2_0Notes[key] = 1;
}
// Shorten the last edited string for all notes
allNotes[key]["lastEdited"] = allNotes[key]["lastEdited"].split("T")[0];
allNotes[key]["lastEdited"] = allNotes[key]["lastEdited"];
}

if (Object.keys(pre1_2_0Notes).length > 0) {
Expand Down

0 comments on commit 5d86798

Please sign in to comment.