waohg
This commit is contained in:
parent
28e6f30a6a
commit
c33241bfbd
1 changed files with 177 additions and 35 deletions
212
script.user.js
212
script.user.js
|
@ -14,30 +14,23 @@
|
|||
|
||||
var mirrorIcon = '<path d="M1 2.5A2.5 2.5 0 0 1 3.5 0h8.75a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0V1.5h-8a1 1 0 0 0-1 1v6.708A2.5 2.5 0 0 1 3.5 9h3.25a.75.75 0 0 1 0 1.5H3.5a1 1 0 0 0 0 2h5.75a.75.75 0 0 1 0 1.5H3.5A2.5 2.5 0 0 1 1 11.5Zm13.23 7.79zl-1.224-1.224v6.184a.75.75 0 0 1-1.5 0V9.066L10.28 10.29a.75.75 0 0 1-1.06-1.061l2.505-2.504a.75.75 0 0 1 1.06 0L15.29 9.23a.75.75 0 0 1-.018 1.042.75.75 0 0 1-1.042.018"></path>';
|
||||
|
||||
if(!GM) {
|
||||
if (!GM) {
|
||||
alert("This script requires GreaseMonkey!");
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = "https://git.incest.world";
|
||||
var config = {}
|
||||
|
||||
async function api(url, data) {
|
||||
var token = await GM.getValue("token");
|
||||
|
||||
if(!token) {
|
||||
var input = prompt("Enter your git.incest.world access token\nSee: https://git.incest.world/user/settings/applications");
|
||||
GM.setValue("token", input);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
GM.xmlHttpRequest({
|
||||
method: "POST",
|
||||
url: `${instance}/api/v1/${url}`,
|
||||
url: `${config.instance}/api/v1/${url}`,
|
||||
data: JSON.stringify(data),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `token ${token}`,
|
||||
"Authorization": `token ${config.token}`,
|
||||
},
|
||||
onload: (response) => {
|
||||
resolve(response);
|
||||
|
@ -46,61 +39,210 @@ async function api(url, data) {
|
|||
});
|
||||
}
|
||||
|
||||
function createFooterElement() {
|
||||
// Create footer
|
||||
const footer = document.createElement('footer');
|
||||
footer.className = 'SelectMenu-footer px-2';
|
||||
|
||||
// Create button
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'user-lists-menu-action btn-invisible btn btn-block text-left text-normal rounded-1 px-2';
|
||||
|
||||
// Create SVG
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('aria-hidden', 'true');
|
||||
svg.setAttribute('height', '16');
|
||||
svg.setAttribute('viewBox', '0 0 16 16');
|
||||
svg.setAttribute('version', '1.1');
|
||||
svg.setAttribute('width', '16');
|
||||
svg.setAttribute('data-view-component', 'true');
|
||||
svg.setAttribute('class', 'octicon octicon-plus mr-1');
|
||||
|
||||
// Create path for SVG
|
||||
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
path.setAttribute('d', 'M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z');
|
||||
|
||||
// Create text node
|
||||
const textNode = document.createTextNode('Mirror repository');
|
||||
|
||||
// Assemble the elements
|
||||
svg.appendChild(path);
|
||||
button.appendChild(svg);
|
||||
button.appendChild(textNode);
|
||||
footer.appendChild(button);
|
||||
|
||||
return footer;
|
||||
}
|
||||
|
||||
function createCheckbox(labelText, value) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'form-checkbox mt-1 mb-0 p-1';
|
||||
div.setAttribute('role', 'listitem');
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.className = 'd-flex';
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.type = 'checkbox';
|
||||
input.checked = value;
|
||||
input.className = 'mx-0 js-user-list-menu-item';
|
||||
|
||||
const outerSpan = document.createElement('span');
|
||||
outerSpan.setAttribute('data-view-component', 'true');
|
||||
outerSpan.className = 'Truncate ml-2 text-normal f5';
|
||||
|
||||
const innerSpan = document.createElement('span');
|
||||
innerSpan.setAttribute('data-view-component', 'true');
|
||||
innerSpan.className = 'Truncate-text';
|
||||
innerSpan.textContent = labelText;
|
||||
|
||||
outerSpan.appendChild(innerSpan);
|
||||
label.appendChild(input);
|
||||
label.appendChild(outerSpan);
|
||||
div.appendChild(label);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function createInput(placeholder, value) {
|
||||
const input = document.createElement('input');
|
||||
input.className = 'FormControl-input';
|
||||
input.placeholder = placeholder ?? '';
|
||||
input.value = value ?? '';
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
function createSettingElement(key, [label, value, editable]) {
|
||||
if (typeof value === 'boolean') {
|
||||
const checkbox = createCheckbox(label, value);
|
||||
checkbox.querySelector('input').disabled = !editable;
|
||||
checkbox.querySelector('input').name = key;
|
||||
return checkbox;
|
||||
} else {
|
||||
const div = document.createElement('div');
|
||||
div.className = "mx-0 mt-2";
|
||||
|
||||
const labelElement = document.createElement('label');
|
||||
labelElement.textContent = label;
|
||||
div.appendChild(labelElement);
|
||||
|
||||
const input = createInput(label, value);
|
||||
input.disabled = !editable;
|
||||
input.name = key;
|
||||
div.appendChild(input);
|
||||
|
||||
return div;
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
config.instance = await GM.getValue("instance");
|
||||
if (!config.instance) {
|
||||
var input = prompt("Enter your Gitea/Forgejo instance (include protocol, no trailing slash)");
|
||||
GM.setValue("instance", input);
|
||||
config.instance = input;
|
||||
}
|
||||
|
||||
config.token = await GM.getValue("token");
|
||||
if (!config.token) {
|
||||
var input = prompt(`Enter your git access token\nSee: ${config.instance}/user/settings/applications`);
|
||||
GM.setValue("token", input);
|
||||
config.token = input;
|
||||
}
|
||||
|
||||
function main() {
|
||||
var container = document.querySelector(".pagehead-actions");
|
||||
if(!container)
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
var mirrorButton = container.querySelector("#mirror");
|
||||
if(mirrorButton != null)
|
||||
if (mirrorButton != null)
|
||||
return;
|
||||
|
||||
mirrorButton = container.children[container.children.length - 1].cloneNode(true);
|
||||
mirrorButton.id = "mirror";
|
||||
|
||||
var starCount = mirrorButton.querySelector("#repo-stars-counter-star");
|
||||
if(starCount)
|
||||
if (starCount)
|
||||
starCount.parentNode.removeChild(starCount);
|
||||
|
||||
var dropDown = mirrorButton.querySelector("details");
|
||||
dropDown.parentNode.removeChild(dropDown);
|
||||
dropDown.querySelector("details-menu").removeAttribute("src");
|
||||
|
||||
var btn = mirrorButton.querySelector(".unstarred button");
|
||||
var title = dropDown.querySelector(".SelectMenu-title");
|
||||
title.textContent = "Mirror Settings";
|
||||
|
||||
var newButton = document.createElement("button");
|
||||
newButton.className = btn.className;
|
||||
newButton.innerHTML = btn.innerHTML;
|
||||
newButton.querySelector("svg").innerHTML = mirrorIcon;
|
||||
newButton.querySelector("span").innerText = "Mirror";
|
||||
newButton.onclick = async () => {
|
||||
newButton.disabled = true;
|
||||
var data = {}
|
||||
|
||||
var repo = location.pathname.split("/")[2];
|
||||
var address = document.querySelector("meta[name=go-import]").content.split(" ").slice(-1)[0];
|
||||
var repo = address.split("/")[4].slice(0, -4);
|
||||
|
||||
var data = await api("repos/migrate", {
|
||||
"clone_addr": document.querySelector("meta[name=go-import]").content.split(" ").slice(-1)[0],
|
||||
var settings = {
|
||||
"repo_owner": ["Owner", "mirrors", true],
|
||||
"repo_name": ["Repository Name", repo, true],
|
||||
"description": ["Description", "Mirror of " + address, true],
|
||||
"mirror": ["Mirror", true, true],
|
||||
"private": ["Private", false, true]
|
||||
}
|
||||
|
||||
var list = dropDown.querySelector(".SelectMenu-list");
|
||||
list.className += " flex-1 overflow-y-auto px-3 py-2 mb-0";
|
||||
list.innerHTML = "";
|
||||
|
||||
Object.entries(settings).forEach(([key, value]) => {
|
||||
const settingElement = list.appendChild(createSettingElement(key, value));
|
||||
settingElement.querySelector("input").addEventListener("input", (ev) => {
|
||||
var input = ev.target;
|
||||
data[input.name] = input.type == "checkbox" ? input.checked : input.value;
|
||||
});
|
||||
});
|
||||
|
||||
var callback = async () => {
|
||||
mirrorButton.querySelector("button").disabled = true;
|
||||
footer.querySelector("button").disabled = true;
|
||||
|
||||
var _data = {
|
||||
"clone_addr": address,
|
||||
"repo_name": repo,
|
||||
"mirror": true,
|
||||
"repo_owner": "mirrors",
|
||||
"description": "Mirror of " + location.href,
|
||||
"description": "Mirror of " + address,
|
||||
"private": false,
|
||||
"issues": false,
|
||||
"pull_requests": false
|
||||
});
|
||||
|
||||
var resp = JSON.parse(data.response);
|
||||
if(resp.message) {
|
||||
if(resp.message == "The repository with the same name already exists.") {
|
||||
window.open(`${instance}/mirrors/${repo}`);
|
||||
"pull_requests": false,
|
||||
...data
|
||||
}
|
||||
|
||||
var res = await api("repos/migrate", _data);
|
||||
var resp = JSON.parse(res);
|
||||
|
||||
if (resp.message) {
|
||||
if (resp.message == "The repository with the same name already exists.") {
|
||||
window.open(`${config.instance}/mirrors/${repo}`);
|
||||
} else alert(resp.message);
|
||||
} else {
|
||||
window.open(resp.html_url);
|
||||
window.open(resp.html_url);
|
||||
}
|
||||
};
|
||||
|
||||
const footer = createFooterElement(repo);
|
||||
list.parentNode.appendChild(footer);
|
||||
list.parentNode.querySelector("footer button").onclick = callback;
|
||||
|
||||
var btn = mirrorButton.querySelector(".unstarred button");
|
||||
|
||||
var newButton = btn.cloneNode(true);
|
||||
newButton.querySelector("svg").innerHTML = mirrorIcon;
|
||||
newButton.querySelector("span").innerText = "Mirror";
|
||||
newButton.onclick = footer.querySelector("button").onclick;
|
||||
|
||||
btn.parentNode.removeChild(btn);
|
||||
mirrorButton.innerHTML = "";
|
||||
mirrorButton.appendChild(newButton);
|
||||
mirrorButton.appendChild(dropDown);
|
||||
|
||||
container.prepend(mirrorButton);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue