Last active
November 16, 2022 06:48
-
-
Save chadluo/46cb53e730a4dca3298928267aa4a0b5 to your computer and use it in GitHub Desktop.
Bitbucket Pull Request Comment Watch or something
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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) + "…" | |
: content | |
) | |
.replaceAll("'", "'") | |
.replaceAll('"', """)}`, | |
}; | |
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