Skip to content

Commit

Permalink
Update JS to match GitHub's new React UI
Browse files Browse the repository at this point in the history
  • Loading branch information
davidstosik committed Nov 23, 2023
1 parent 35b0b85 commit eb648ae
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 71 deletions.
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ GEM

PLATFORMS
arm64-darwin-21
arm64-darwin-22

DEPENDENCIES
github-pages (~> 227)
Expand Down
2 changes: 1 addition & 1 deletion better-gh-status-clear.user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// @namespace https://github.com/davidstosik
// @match https://github.com/*
// @grant none
// @version 1.3
// @version 1.4
// @author David Stosik
// @description Freely pick when your GitHub status clears!
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2
Expand Down
128 changes: 58 additions & 70 deletions better-github-status-clear.js
Original file line number Diff line number Diff line change
@@ -1,91 +1,84 @@
class BetterGitHubStatusClear {
static DEBUG_MODE = false;

static get debug() {
if (this.DEBUG_MODE) {
return console.log.bind(window.console, "[BGHSC]");
} else {
return function() {};
};
};

static run() {
const clearStatusDiv = this.getClearStatusDiv();
this.debug("Triggered.");

const select = this.getOriginalClearStatusSelect();

if (!clearStatusDiv?.checkVisibility()) {
if (!select) {
this.debug('Could not find the "clear status" select on the page. Aborting...');
return;
};

if (select.classList.contains("bghsc")) {
this.debug('Job already done. Aborting...');
return;
};

select.classList.add("bghsc");
if (!this.DEBUG_MODE) {
select.parentElement.hidden = true;
};

var previousDateString = "";
var previousTimeString = "";
var helpMessage = "";
var previousDateMatch = null;

const previousDateInput = clearStatusDiv
.querySelector(".js-user-status-expiration-interval-selected");

if (previousDateInput) {
previousDateMatch = previousDateInput
.textContent
.trim()
.match(/^in (?<count>\d+) (?<unit>minute|hour|day|month|year)s?$/);
}

if (previousDateMatch) {
const count = parseInt(previousDateMatch.groups.count);
var previousDate = new Date();

switch (previousDateMatch.groups.unit) {
case "minute":
previousDate.setMinutes(previousDate.getMinutes() + count);
break;
case "hour":
previousDate.setHours(previousDate.getHours() + count);
break;
case "day":
previousDate.setDate(previousDate.getDate() + count);
break;
case "month":
previousDate.setMonth(previousDate.getMonth() + count);
break;
case "year":
previousDate.setFullYear(previousDate.getFullYear() + count);
break;
};

const offset = previousDate.getTimezoneOffset();
previousDate = new Date(previousDate.getTime() - offset * 60 * 1000);

var previousDate = null;
if (select.value != " ") {
previousDate = new Date(select.value);
previousDate = new Date(
previousDate.getTime() - previousDate.getTimezoneOffset() * 60 * 1000
);
[previousDateString, previousTimeString] = previousDate.toISOString().split("T", 2);

previousTimeString = previousTimeString.split(":", 3).slice(0, 2).join(":");
helpMessage = `\
<p class="f6 mt-2">
(GitHub only returns an imprecise clear date, so the value selected above is likely inaccurate.)
</p>`;
};
this.debug("Current clear date/time: " + previousDate);

const html = `\
<div class="f5 pt-3 pb-2">
<div class="d-inline-block mr-2">Clear status</div>
<div>
<input type="date" class="form-control" name="clear-date" value="${previousDateString}">
<input type="time" class="form-control" name="clear-time" value="${previousTimeString}">
${helpMessage}
<input class="js-user-status-expiration-date-input better-gh-status-clear" type="hidden" name="expires_at" value="">
</div>`;

clearStatusDiv.insertAdjacentHTML("beforebegin", html);
select.parentElement.parentElement.insertAdjacentHTML("beforeend", html);

const updateHiddenInput = function(e) {
const hiddenInput = document.querySelector(".js-user-status-expiration-date-input");
const dateString = hiddenInput.parentElement.querySelector("[name='clear-date']").value;
const timeString = hiddenInput.parentElement.querySelector("[name='clear-time']").value;
const that = this;
const updateSelect = function(e) {
that.debug("Updating select with new date...");
const container = select.parentElement.parentElement;
const dateString = container.querySelector("[name='clear-date']").value;
const timeString = container.querySelector("[name='clear-time']").value;

select.childNodes.forEach((option) => {
if (option?.text?.startsWith("Custom")) {
option.remove();
};
});

if (dateString == "") {
hiddenInput.value = "";
console.log("Erased clear date.");
select.value = " ";
that.debug("Erased clear date.");
} else {
const dateTime = new Date(`${dateString} ${timeString}`);
hiddenInput.value = dateTime.toISOString();
console.log(`Set clear date to ${dateTime}.`);
const dateTime = new Date(`${dateString} ${timeString}`).toISOString();
select.options.add(new Option(`Custom (${dateTime})`, dateTime, true, true));
select.value = dateTime;
that.debug(`Set clear date to ${dateTime}.`);
};
};

clearStatusDiv.parentElement.querySelector("[name='clear-date']").addEventListener("input", updateHiddenInput);
clearStatusDiv.parentElement.querySelector("[name='clear-time']").addEventListener("input", updateHiddenInput);
select.parentElement.parentElement.querySelector("[name='clear-date']").addEventListener("input", updateSelect);
select.parentElement.parentElement.querySelector("[name='clear-time']").addEventListener("input", updateSelect);

this.getOriginalClearStatusInput().remove();
clearStatusDiv.remove();
this.debug("Finished.");
};

static ensureContext() {
Expand All @@ -94,20 +87,15 @@ class BetterGitHubStatusClear {
return false;
};

if (!this.getClearStatusDiv()?.checkVisibility()) {
if (!this.getOriginalClearStatusSelect()) {
alert("Please open the 'Set status' modal first.");
return false;
};

return true;
};

static getClearStatusDiv() {
return this.getOriginalClearStatusInput()?.previousElementSibling;
};


static getOriginalClearStatusInput() {
return document.querySelector("input.js-user-status-expiration-date-input:not(.better-gh-status-clear)");
static getOriginalClearStatusSelect() {
return document.querySelector("#user-status-dialog-compact select#expires_at");
};
}

0 comments on commit eb648ae

Please sign in to comment.