Skip to content

Instantly share code, notes, and snippets.

@chadluo
Last active November 16, 2022 06:48
Show Gist options
  • Save chadluo/46cb53e730a4dca3298928267aa4a0b5 to your computer and use it in GitHub Desktop.
Save chadluo/46cb53e730a4dca3298928267aa4a0b5 to your computer and use it in GitHub Desktop.
Bitbucket Pull Request Comment Watch or something
// ==UserScript==
// @name Pull Request Comment Watch or something
// @namespace Violentmonkey Scripts
// @match https://bitbucket.org/*/pull-requests/*
// @version 1.0
// @author https://gist.github.com/chadluo
// @icon https://www.google.com/s2/favicons?domain=bitbucket.org
// @grant GM_addStyle
// ==/UserScript==
"use strict";
const COMMENTS_WATCHLIST_KEY = "COMMENTS_WATCHLIST_KEY";
/* Comments list */
const watch = document.createElement("div");
watch.id = "watch";
setTimeout(() => {
document.querySelector("#pull-request-details").prepend(watch);
renderWatchList();
}, 2000);
function renderWatchList() {
const commentsWatchlist = JSON.parse(
localStorage.getItem(COMMENTS_WATCHLIST_KEY) ?? "{}"
);
document.getElementById("watch").innerHTML =
"<ul>" +
Object.values(commentsWatchlist)
.sort((c1, c2) => (c2.timestamp ?? 0) - (c1.timestamp ?? 0))
.map(
(comment) => `<li><a href="${comment.url}"
${comment.url.includes(window.location.pathname) ? 'class="current"' : ""}
${comment.timestamp ? `title="${new Date(comment.timestamp)}"` : ""}
>${comment.text}</a></li>`
)
.join("") +
"</ul>";
}
/* Add Checkbox */
setInterval(() => {
const comments = document.querySelectorAll(
'div[id^="comment-"]:not(.checkboxAdded)'
);
if (comments.length > 0) {
const commentsWatchlist = JSON.parse(
localStorage.getItem(COMMENTS_WATCHLIST_KEY) ?? "{}"
);
const commentIds = Object.keys(commentsWatchlist);
comments.forEach((commentDiv) => createCheckbox(commentDiv, commentIds));
}
}, 3000);
function createCheckbox(commentDiv, commentIds) {
const author = commentDiv.querySelector(
"div:nth-of-type(2) > div > div:nth-of-type(1) > div:nth-of-type(1)"
).innerText;
const content = commentDiv.querySelector(".ak-renderer-document").innerText;
const url = commentDiv.querySelector(
"div:nth-of-type(2) > div > div:nth-of-type(1) > div:nth-of-type(2) a"
).href;
const parts = new URL(window.location.href).pathname.split("/");
const repo = parts[2];
const prId = parts[4];
const commentInfo = {
url: url,
text: `${repo} #${prId} ${author}: ${(content.length > 140
? content.slice(0, 140) + "&hellip;"
: content
)
.replaceAll("'", "&apos;")
.replaceAll('"', "&quot;")}`,
};
console.log(COMMENTS_WATCHLIST_KEY, commentDiv);
const checkbox = document.createElement("label");
checkbox.classList.add("checkbox");
checkbox.innerHTML = `<input type="checkbox"
data-id="${commentDiv.id}"
data-content='${JSON.stringify(commentInfo)}'
${commentIds.includes(commentDiv.id) ? "checked" : ""}/> Watch`;
commentDiv
.querySelector("div:nth-of-type(2) > div > div:nth-of-type(1)")
.appendChild(checkbox);
commentDiv.classList.add("checkboxAdded");
}
/* Listen checkbox */
document.addEventListener("change", (event) => {
if (!(event.target.tagName === "INPUT" && event.target.type === "checkbox")) {
return;
}
const checkbox = event.target;
const commentsWatchlist = JSON.parse(
localStorage.getItem(COMMENTS_WATCHLIST_KEY) ?? "{}"
);
if (checkbox.checked) {
const content = JSON.parse(checkbox.dataset.content);
content.timestamp = new Date().getTime();
commentsWatchlist[checkbox.dataset.id] = content;
} else {
delete commentsWatchlist[checkbox.dataset.id];
}
localStorage.setItem(
COMMENTS_WATCHLIST_KEY,
JSON.stringify(commentsWatchlist)
);
renderWatchList();
});
document.addEventListener("visibilitychange", function () {
if (!document.hidden) {
renderWatchList();
}
});
/* Styles */
GM_addStyle(`
#pull-request-details {
position: relative;
}
#pull-request-details > header,
#pull-request-details > div {
margin-left: 0;
}
#watch {
position: absolute;
top: 0;
right: 40px;
max-width: calc(100vw - 1200px);
}
#watch, label.checkbox {
font-family: 'Chalkboard', 'Comic Sans', cursive;
}
#watch .current {
font-weight:bold;
}
`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment