Skip to content

Instantly share code, notes, and snippets.

@hsayed21
Last active June 20, 2024 09:28
Show Gist options
  • Save hsayed21/36195f69519e040642624a0a3f8dd705 to your computer and use it in GitHub Desktop.
Save hsayed21/36195f69519e040642624a0a3f8dd705 to your computer and use it in GitHub Desktop.
Web WhatsApp Sort Unreaded Messages
// ==UserScript==
// @name WhatsApp Sort Unreaded Messages
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Web WhatsApp Sort Unreaded Messages Based On Rearest datetime
// @author @hsayed21
// @match https://web.whatsapp.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=whatsapp.com
// @updateURL https://gist.github.com/hsayed21/36195f69519e040642624a0a3f8dd705.js
// @downloadURL https://gist.github.com/hsayed21/36195f69519e040642624a0a3f8dd705.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
// TODO:
// 1.[x] Add a button to toggle the unread messages div
// 2. if the unread messages change not clear previous divs
// 2.1 if exist and readed remove from unread div
// 2.2 after 10 time is still not exist remove from unread div
let lastUnreadMessages = [];
function simulateMouseEvents(element, eventName) {
var mouseEvent= document.createEvent ('MouseEvents');
mouseEvent.initEvent (eventName, true, true);
element.dispatchEvent (mouseEvent);
}
// Function to check if a chat div contains unread messages
function hasUnreadMessages(chatDiv) {
return Array.from(chatDiv.querySelectorAll('span[aria-label*="unread" i]:not(button[aria-label*="Archived" i] span')).some(span => window.getComputedStyle(span).backgroundColor === 'rgb(0, 168, 132)');
}
// Function to get the timestamp of a chat message
function getTimestamp(chatDiv) {
const timestampElement = chatDiv.querySelector("div > div > div > div:nth-child(2) > div:nth-child(1) > div:nth-child(2)");
if (timestampElement) {
const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
const timestampText = timestampElement.textContent.trim().toLowerCase();
if (timestampText === 'yesterday') {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return yesterday.getTime();
} else if (days.includes(timestampText.toLowerCase())) {
const today = new Date();
const dayIndex = days.indexOf(timestampText.toLowerCase());
const daysUntilTargetDay = (dayIndex - today.getDay() + 7) % 7;
const targetDay = new Date(today);
targetDay.setDate(today.getDate() - daysUntilTargetDay);
return targetDay.getTime();
} else if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(timestampText)) {
return new Date(timestampText).getTime();
} else {
const [time, period] = timestampText.split(' ');
let [hours, minutes] = time.split(':').map(part => parseInt(part));
if (period === 'pm' && hours !== 12) hours += 12;
else if (period === 'am' && hours === 12) hours = 0;
const date = new Date();
date.setHours(hours, minutes, 0, 0);
return date.getTime();
}
}
return 0;
}
// Function to sort chat divs based on their timestamps
function sortByTimestamp(a, b) {
return getTimestamp(a) - getTimestamp(b);
}
// Function to filter and sort unread messages within the last two days
function getUnreadMessages(chatArr) {
const twoDaysAgo = Date.now() - (2 * 24 * 60 * 60 * 1000); // Two days ago in milliseconds
return Array.from(chatArr).filter(chatDiv => hasUnreadMessages(chatDiv) && getTimestamp(chatDiv) > twoDaysAgo)
.sort(sortByTimestamp)
.map(chatDiv => {
const newElem = chatDiv.cloneNode(true);
newElem.style.cssText = "transform: ''; z-index: ''; width: 100%; position: '';";
var titleElem = chatDiv.querySelector("span[title][aria-label]");
newElem.className = titleElem?.textContent?.trim();
newElem.addEventListener('mousedown', () => {
simulateMouseEvents(titleElem, "mousedown");
});
return newElem;
});
}
// Function to initiate sorting and display process
function startAction() {
const divUnreadParent = document.querySelector('#side')?.parentNode;
if (!divUnreadParent) return;
const chatDivs = document.querySelectorAll('#side [aria-label="Chat list"] > div');
if (!chatDivs) return;
let divUnread = divUnreadParent.querySelector(".unreadMessages");
if (!divUnread) {
divUnread = document.createElement('div');
divUnread.className = "unreadMessages";
divUnread.style.cssText = "border: 2px solid red; width: 100%; height: 360px; overflow: scroll; background-color: black;";
divUnreadParent.insertBefore(divUnread, divUnreadParent.firstChild);
}
// Add a button to toggle the unread messages div
let pinButton = divUnreadParent.querySelector(".pinMessages");
if (!pinButton) {
pinButton = document.createElement('button');
pinButton.className = "pinMessages";
pinButton.style.cssText = "display: block; padding: 6px; font-size: 22px; position: absolute; top:10%; right:-45px; z-index:999; width: 40px; background-color: black;";
pinButton.innerHTML = "📍";
// on click event to toggle the unread messages div
pinButton.addEventListener('click', function () {
if (divUnread.style.display === "none") {
divUnread.style.display = "block";
} else {
divUnread.style.display = "none";
}
});
divUnreadParent.insertBefore(pinButton, divUnread.nextSibling);
}
const unreadMessages = getUnreadMessages(chatDivs);
if (unreadMessages.length === 0) {
divUnread.innerHTML = '';
return;
}
divUnread.innerHTML = '';
unreadMessages.forEach(chatDiv => {
lastUnreadMessages.push(chatDiv);
divUnread.appendChild(chatDiv);
});
}
// Call the sorting function initially and set up an interval for updates
startAction();
setInterval(startAction, 10000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment