Skip to content

Instantly share code, notes, and snippets.

@Dainius14
Last active March 5, 2024 08:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dainius14/8a9d5bfa06458a93a00b8d34111e7e4f to your computer and use it in GitHub Desktop.
Save Dainius14/8a9d5bfa06458a93a00b8d34111e7e4f to your computer and use it in GitHub Desktop.
OG Developer Sound Pack
// ==UserScript==
// @name OG Developer Sound Pack
// @namespace https://saldainius.lt
// @downloadUrl https://gist.github.com/Dainius14/8a9d5bfa06458a93a00b8d34111e7e4f/raw/og-developer-sound-pack.user.js
// @updateUrl https://gist.github.com/Dainius14/8a9d5bfa06458a93a00b8d34111e7e4f/raw/og-developer-sound-pack.user.js
// @website https://gist.github.com/Dainius14/8a9d5bfa06458a93a00b8d34111e7e4f/
// @version 1.5.2
// @description Plays sound when interacting with Bitbucket and Jira
// @author Dainius
// @match https://bitbucket.cid-dev.net/projects/*/repos/*/pull-requests/*
// @match https://jira.cid-dev.net/browse/*
// @match https://jira.cid-dev.net/secure/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @connect myinstants.com
// ==/UserScript==
'use strict';
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const bitbucketPrMergeAudioUrl = 'https://www.myinstants.com/media/sounds/y2mate_xvijLIk.mp3';
const bitbucketPrNeedsWorkAudioUrl = 'https://www.myinstants.com/media/sounds/tindeck_1.mp3';
const bitbucketPrAcceptedAudioUrl = 'https://www.myinstants.com/media/sounds/meme-okay-lets-go.mp3';
const bitbucketPrPageLoadAudioUrl = 'https://www.myinstants.com/media/sounds/what-are-you-doing-step-bro-tik-tok-meme_80zo59v.mp3';
const jiraTaskAssignToMeAudioUrl = 'https://www.myinstants.com/media/sounds/gta-san-andreas-ah-shit-here-we-go-again.mp3';
const bitbucketPrCommentAudioUrl = 'https://www.myinstants.com/media/sounds/skullsound2.mp3';
const bitbucketPrTaskAudioUrl = 'https://www.myinstants.com/media/sounds/slap-sound-effect-free.mp3';
const bitbuckerPrTaskCompletedUrl = 'https://www.myinstants.com/media/sounds/succ.mp3';
class VisitedPullRequests {
constructor() {
this.pullRequestIdRegex = /pull-requests\/(\d+)\//;
}
getPullRequestId(location) {
const regexMatch = location.pathname.match(this.pullRequestIdRegex);
if (regexMatch) {
return regexMatch[1];
}
return null;
}
isPullRequestNotVisited(location) {
const pullRequestId = this.getPullRequestId(location);
return !this.getVisitedPullRequests().includes(pullRequestId)
}
addVisitedPullRequest(location) {
const pullRequestId = this.getPullRequestId(location);
const visitedPages = this.getVisitedPullRequests();
visitedPages.push(pullRequestId);
this.setVisitedPullRequests(visitedPages);
}
getVisitedPullRequests() {
const visitedPagesJson = GM_getValue('visitedPullRequests', '[]');
return JSON.parse(visitedPagesJson);
}
setVisitedPullRequests(visitedPages) {
GM_setValue('visitedPullRequests', JSON.stringify(visitedPages));
}
}
const visitedPullRequests = new VisitedPullRequests();
function main() {
switch (location.host) {
case 'bitbucket.cid-dev.net': {
setupBitbucket();
break;
}
case 'jira.cid-dev.net': {
setupJira();
break;
}
}
}
function setupBitbucket() {
if (visitedPullRequests.isPullRequestNotVisited(location)) {
playAudioOnPageLoad(bitbucketPrPageLoadAudioUrl);
visitedPullRequests.addVisitedPullRequest(location);
}
addAudioOnElementViaObserver('.merge-dialog-actions > button[type="submit"]', document.querySelector('.atlaskit-portal-container'), new Audio(bitbucketPrMergeAudioUrl));
tryAddOnClickListener(() => document.querySelectorAll('.reviewer-status-buttons-container button')[0], new Audio(bitbucketPrNeedsWorkAudioUrl));
tryAddOnClickListener(() => document.querySelectorAll('.reviewer-status-buttons-container button')[1], new Audio(bitbucketPrAcceptedAudioUrl));
addAudioOnElementViaObserver(() => document.querySelectorAll('.editor-controls button')[0], document.querySelector('body'), new Audio(bitbucketPrCommentAudioUrl), 0.5);
addAudioOnElementViaObserver(() => document.querySelectorAll('.editor-controls button')[1], document.querySelector('body'), new Audio(bitbucketPrTaskAudioUrl), 0.5);
tryAddOnClickListener(() => document.querySelectorAll('.comment-task-checkbox div')[0], new Audio(bitbuckerPrTaskCompletedUrl), 0.2);
}
function setupJira() {
addAudioOnElementViaObserver('#assign-to-me', document.querySelector('body'), new Audio(jiraTaskAssignToMeAudioUrl));
}
function addAudioOnElementViaObserver(elementQuerySelector, observerContainer, audio, probabilityToPlaySound) {
const observer = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
if (tryAddOnClickListener(elementQuerySelector, audio, probabilityToPlaySound)) {
break;
}
}
}
});
observer.observe(observerContainer, {attributes: false, childList: true, subtree: true});
}
function tryAddOnClickListener(selector, audio, probabilityToPlaySound = 1) {
const button = typeof(selector) === 'function'
? selector()
: document.querySelector(selector);
if (button) {
button.addEventListener('click', () => {
if (Math.random() <= probabilityToPlaySound) {
audio.play();
}
});
return true;
}
return false;
}
/**
* Source: https://xenos.reinom.com/mdn/audio-autoplay/audio-autoplay.html
*/
function playAudioOnPageLoad(audioUrl) {
const onLoad = (response) => {
const playSound = (audioBuffer) => {
const source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
source.loop = false;
source.start();
};
audioCtx.decodeAudioData(response.response).then(playSound);
};
GM_xmlhttpRequest({
method: 'GET',
url: audioUrl,
responseType: 'arraybuffer',
onload: onLoad
});
}
function log() {
console.log('OGD', ...arguments);
}
main();
@mark05e
Copy link

mark05e commented Dec 4, 2021

lol'd when I heard some of the tracks. thank you for showing the creative possibilities of userscripts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment