Show week day and week number

I wrote some Javascript code to show week day and week number beside all journal page titles, like below:

I was going to make it a plugin, but writing it as a plugin I did not find a way to have access to the HTML elements I needed to modify. Instead I added a javascript file at my-graph/logseq/custom.js with the following:

function insertInfo() {
  console.log('inserting info');
  var journalTitles = document.querySelectorAll("span.title") // in page view this will find the page title
  if (journalTitles.length == 0)
    journalTitles = document.querySelectorAll("h1.title") // in journals view, this will find all visible journal titles
  for (let t of journalTitles) {
    addToElement(t)
  }
}
function addToElement(t) {
  const dateRegexMatch = new RegExp('([A-Z]\\w+) (\\d+)\\w\\w, (\\d\\d\\d\\d)$').exec(t.textContent)
  
  if (!!dateRegexMatch && dateRegexMatch.length == 4) {
      const journalDate = new Date(dateRegexMatch[1] + " " + dateRegexMatch[2] + " " + dateRegexMatch[3])
      
      const startDate = new Date(journalDate.getFullYear(), 0, 1);
      const days = Math.floor((journalDate - startDate) / (24 * 60 * 60 * 1000));
      const weekNumber = Math.ceil(days / 7);
      
      const dayOfWeekName = journalDate.toLocaleString(
        'default', {weekday: 'long'}
      );

      const span = document.createElement("span")
      span.style = "opacity:0.5;font-size:0.7em"
      span.innerHTML = " " + dayOfWeekName + ', Week ' + weekNumber
      t.append(span)
  }
}
var t=setInterval(insertInfo,1000);

And that did it for me. Feel free to use the code if you wish.

This is amazing! I wonder if you can help making something similar for yyyy-MM-dd type of date? I tried figuring out from your posted code but this is above my skill level for now.

This is what I have been wishing for! Unfortunately, same as the commentor above, I tried it in my graph but does not seem to work with date format do MMM yyyy.

Thanks, I love it! That’s just what I needed. No need to make it a plugin if you can just drop the file into the vault, in my opinion.

1 Like

Try this out

function addToElement(t) {
    const dateRegexMatch = new RegExp("(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$").exec(
        t.textContent
    );

    if (!!dateRegexMatch && dateRegexMatch.length == 4) {
        const journalDate = new Date(
            dateRegexMatch[1] +
                " " +
                dateRegexMatch[2] +
                " " +
                dateRegexMatch[3]
        );

        const startDate = new Date(journalDate.getFullYear(), 0, 1);
        const days = Math.floor(
            (journalDate - startDate) / (24 * 60 * 60 * 1000)
        );
        const weekNumber = Math.ceil(days / 7);

        const dayOfWeekName = journalDate.toLocaleString("default", {
            weekday: "long",
        });

        const span = document.createElement("span");
        span.style = "opacity:0.5;font-size:0.7em";
        span.innerHTML = " " + dayOfWeekName + ", Week " + weekNumber;
        t.append(span);
    }
}
var t = setInterval(insertInfo, 1000);

1 Like

Awesome, this looks really cool! I am just starting out with the advanced capabilities of Logseq. I tried adding a costum.js to " my-graph/logseq/custom.js", then I closed and opened Logseq but I did not see any changes. Is there anything else I need to do? :slight_smile:

It showed up for me after I pressed Command-R. If you use Windows, it should be Control-R.

I did not restart Logseq.

Thank you Sri! :slight_smile: It worked now. I had an old logseq path that I was not using anymore. That’s why it didn’t work. Now I am just wondering, how I can get the :spiral_calendar: into the journal?

Add this custom CSS:

/*add calendar icon to the left of journal titles*/
.journal-title .title::before,
.is-journals .title::before {
  content: "🗓️";
  font-size: 0.75em;
  margin-right: 10px;
  vertical-align: text-bottom;
}
2 Likes

Thank you for the code! :slight_smile:

Awesome! Any chance this can be made extensible to work with the various date formats supported by Logseq?

This looks great - and works in the journals view on macOS. But on iOS, or when looking at an individual journal page, i get two calendar icons. Has anyone else had this?

@danzu - thanks for this. Works great on macOS but on iOS the day of the week shows as “Invaild Date”. Any thoughts on why this is? Can iOS handle custom.js, or is there something in this particular script that doesn’t work.

Try Show week day and week number - #9 by sri.

Thanks @sri - that’s the one I’ve been trying. It looks great when I’m looking at the Journals view (and I was wrong about it not working in iOS). But in my set-up I sometimes view individual journal pages, especially for future days, and on these it shows two calendar icons. It just seems a bit odd so wondered why it was happening,

What date format do you have in config.edn on mobile?

It’s yyyy-MM-dd on iPad, iPhone and macOS. As I say it works on macOS but I get invalid date on the iOS ones.

I refactored the code and implemented several optimizations and improvements over the original one. Notable changes include:

  • The code now checks whether the title element already has a date span element before adding a new one. This avoids unnecessary DOM manipulations, improves performance, and prevents potential issues.
  • The date parsing logic has been simplified using the vanilla Date.parse() method and a regular expression to remove ordinal suffixes from the date string. This improves readability and reduces the number of lines of code. Additionally, this change should make the code more flexible in supporting a variety of date formats.
  • The code now calculates the day of the week name and the week number using built-in JavaScript methods, rather than calculating them manually as in the original code. This improves the readability and maintainability of the code, and may also improve performance.
  • Finally, I implemented a MutationObserver to detect changes in the DOM and apply the addExtendedDate function only to newly added title elements. This narrows the scope of elements to check, avoids the need for a setInterval loop, and improves performance while reducing resource usage.

Here it is the final result:

function addExtendedDate(titleElement) {
    // check if element already has date info
    const existingSpan = titleElement.querySelector("span");
    if (existingSpan) return;

    // remove ordinal suffixes from date
    const journalDate = new Date(Date.parse(titleElement.textContent.replace(/(\d+)(st|nd|rd|th)/, "$1")));
    if (!isFinite(journalDate)) return;

    // calculate dates
    const dayOfWeekName = new Intl.DateTimeFormat("default", {weekday: "long"}).format(journalDate);
    const days = Math.ceil((journalDate - new Date(journalDate.getFullYear(), 0, 1)) / 86400000);
    const weekNumber = Math.ceil(days / 7);

    // apply styles
    const dateInfoElement = document.createElement("span");
    dateInfoElement.style = "opacity:0.5;font-size:0.7em";
    dateInfoElement.textContent = ` ${dayOfWeekName}, Week ${weekNumber}`;

    titleElement.appendChild(dateInfoElement);
}

const observer = new MutationObserver(() => {
    document.querySelectorAll("span.title, h1.title").forEach(addExtendedDate);
});

observer.observe(document.getElementById("main-content-container"), {
    attributes: true,
    subtree: true,
    attributeFilter: ["class"],
});

I hope you like it!

9 Likes

Thanks for this. It now works for me on iPad and iPhone as well.

1 Like

I think your code is fantastic. Based on it, I have created a plugin. Would you be willing to grant me permission for it?

3 Likes