Skip to content

Commit

Permalink
Release v0.1: quick access to Files changed page and bulk comment (#1)
Browse files Browse the repository at this point in the history
* update LICENSE

Signed-off-by: Aolin <[email protected]>

* README: add feature description, usage, and FAQs

Signed-off-by: Aolin <[email protected]>

* script: (CreateFileLink) add a File element to quick access to Files Changed page

Signed-off-by: Aolin <[email protected]>

* script: (GetRepositoryInformation) get the owner and name of the current GitHub repository

Signed-off-by: Aolin <[email protected]>

* script: (EnsureToken) prompt uses to add GitHub token

Signed-off-by: Aolin <[email protected]>

* script: (LeaveCommentOnPR) comment on PR using the GitHub issue API

Signed-off-by: Aolin <[email protected]>

* script: (CreateCommentButton) create a button to comment on multiple PRs

Signed-off-by: Aolin <[email protected]>

* script: add newline at the end

Signed-off-by: Aolin <[email protected]>

---------

Signed-off-by: Aolin <[email protected]>
  • Loading branch information
Oreoxmt authored Feb 9, 2023
1 parent a7e7151 commit 5d34e1d
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 2 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2023 Oreoxmt

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,32 @@
# octopus-github
A GitHub extension

A userscript for GitHub with the following features:

- Quick access to the **Files changed** page of a PR
- Bulk comment on multiple PRs

## Usage

1. Install a userscript manager of your choice, such as [Tampermonkey](https://tampermonkey.net/).

2. Add the userscript by clicking [`gh-util.user.js`](https://raw.githubusercontent.com/Oreoxmt/octopus-github/main/gh-util.user.js).

3. (Optional) Configure your own GitHub [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) (`repo` scope) when you use the bulk comment feature for the first time.

## FAQs

### Why is the bulk comment feature not working?

1. Check if you have configured a Github personal access token.

2. Check if the token has the `repo` scope.

3. Check if the token has expired.

### How to manage the token used by this script?

1. Go to the **Developer Tools** of your browser and then click the **Application** tab.

2. In the **Storage** section on the left panel, click **Local Storage > https://github.com**.

3. Search for the key `octopus-github-util:token` and modify/delete it.
142 changes: 142 additions & 0 deletions gh-util.user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// ==UserScript==
// @name Octopus GitHub
// @version 0.1
// @description A userscript for GitHub
// @author Oreo
// @match https://github.com/*/pulls*
// @grant none
// ==/UserScript==

(function () {

'use strict';

const STORAGEKEY = 'octopus-github-util:token'

function GetRepositoryInformation() {
// Get the pathname of the current page
var pathname = location.pathname;

// Split the pathname into an array of parts
var parts = pathname.split('/');

// Return an object containing the user name and repository name
return {
owner: parts[1],
name: parts[2],
}
}

function EnsureToken() {
var token = localStorage.getItem(STORAGEKEY)
if (!token) {
// Prompt user to set token
// TODO: Use HTML element instead of prompt
token = prompt('Enter your GitHub token:');
if (!token) {
throw 'No token set'
}
localStorage.setItem(STORAGEKEY, token);
}
return token;
}

// This function can be used to leave a comment on a specific PR
function LeaveCommentOnPR(commentLink, comment) {
// Send the POST request to the GitHub API
// TODO: Use Octokit to create requests
fetch(commentLink, {
method: 'POST',
headers: {
'Authorization': `Bearer ${EnsureToken()}`,
'Accept': 'application/vnd.github+json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'body': comment
})
}).then((response) => {
console.log('response to ', commentLink, response)
}).catch((error) => {
console.log('error on ', commentLink, error)
})
}

// TODO: Use toggle instead of button, and add more features to the toggle, e.g., editing tokens.
function CreateCommentButton() {
// First, find the "table-list-header-toggle" div
var toggleDiv = document.querySelector('.table-list-header-toggle.float-right');

// Next, create a button element and add it to the page
var button = document.createElement('button');
button.innerHTML = 'Comment';
button.setAttribute('class', 'btn btn-sm js-details-target d-inline-block float-left float-none m-0 mr-md-0 js-title-edit-button')
toggleDiv.appendChild(button);

// Next, add an event listener to the button to listen for clicks
button.addEventListener('click', function () {
EnsureToken();

// Get a list of all the checkboxes on the page (these are used to select PRs)
var checkboxes = document.querySelectorAll('input[type=checkbox][data-check-all-item]');

// Iterate through the checkboxes and get the ones that are checked
var selectedPRs = [];

checkboxes.forEach(function (checkbox) {
if (checkbox.checked) {
selectedPRs.push(checkbox.value);
}
})

// Prompt the user for a comment to leave on the selected PRs
var comment = prompt('Enter a comment to leave on the selected PRs:');
if (!comment) {
return;
}
var repo = GetRepositoryInformation();

// Leave the comment on each selected PR
selectedPRs.forEach(function (pr) {
var commentLink = `https://api.github.com/repos/${repo.owner}/${repo.name}/issues/${pr}/comments`;
// Leave a comment on the PR
LeaveCommentOnPR(commentLink, comment);
});
});
}

function CreateFileLink() {

// Get all div elements with an id that starts with "issue_"
var issueElements = document.querySelectorAll('div[id^="issue_"]');
issueElements.forEach((element) => {
var issueId = element.getAttribute("id")
var originalLinkElement = document.getElementById(issueId + "_link")
var originalLink = originalLinkElement.getAttribute("href")
var newLink = originalLink + "/files"
// Get all span elements within the current element
var spanElements = element.querySelectorAll('span[class="opened-by"]');
if (spanElements.length == 1) {
var openedBy = spanElements[0];
var linkSpanElement = document.createElement('span');
linkSpanElement.setAttribute('class', 'd-inline-block mr-1')
var dotSpanElement = document.createElement('span');
dotSpanElement.innerHTML = ' • ';
dotSpanElement.setAttribute('class', 'd-inline-block mr-1')
var linkElement = document.createElement('a')
linkElement.setAttribute('href', newLink)
linkElement.setAttribute('class', 'Link--muted')
linkElement.innerHTML = "Files"
linkSpanElement.appendChild(linkElement)
openedBy.insertAdjacentElement('beforebegin', linkSpanElement)
openedBy.insertAdjacentElement('beforebegin', dotSpanElement);
}
})

}

// TODO: Do this everytime on switching to new page
CreateCommentButton();
CreateFileLink();

})();

0 comments on commit 5d34e1d

Please sign in to comment.