Updated html element creation to single function for smaller code base when creating elements
This commit is contained in:
@@ -1,223 +1,254 @@
|
|||||||
(function runTwitchNotes() {
|
(function runTwitchNotes() {
|
||||||
|
|
||||||
let mousePosition = { x: 0, y: 0 };
|
const Notes = {
|
||||||
let lastMousePosition = { x: 0, y: 0 };
|
getSavedUserList: () => {
|
||||||
let openContainers = {};
|
return JSON.parse(localStorage.getItem(LS_UserList) || "[]");
|
||||||
let isMouseDown = false;
|
},
|
||||||
let activeContainer = null;
|
addUserToSavedList: (username) => {
|
||||||
let settingsWindowOpen = false;
|
let userList = Notes.getSavedUserList();
|
||||||
|
|
||||||
let LS_UserList = "twitch-note-all-users-list";
|
if (!userList.includes(username)) {
|
||||||
let LS_Prefix = "twitch-note-";
|
userList.push(username);
|
||||||
|
localStorage.setItem(LS_UserList, JSON.stringify(userList));
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
}
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
},
|
||||||
|
saveNote: (username, note) => {
|
||||||
function createSettingsButton(buttonContainer) {
|
Notes.addUserToSavedList(username);
|
||||||
const c1 = document.createElement("div");
|
localStorage.setItem(LS_Prefix + username, note);
|
||||||
c1.style.marginLeft = "0.5rem !important";
|
},
|
||||||
const c2 = document.createElement("div");
|
getNote: (username) => {
|
||||||
c2.style.display = "inline-flex !important";
|
return localStorage.getItem(LS_Prefix + username) || "";
|
||||||
|
}
|
||||||
const settingsButton = document.createElement("button");
|
|
||||||
settingsButton.classList.add("twitch-notes-settings-button");
|
|
||||||
settingsButton.innerHTML = "Notes";
|
|
||||||
settingsButton.addEventListener("click", () => {
|
|
||||||
console.log("TN Settings");
|
|
||||||
});
|
|
||||||
|
|
||||||
c2.appendChild(settingsButton);
|
|
||||||
c1.appendChild(c2);
|
|
||||||
|
|
||||||
buttonContainer.lastChild.insertBefore(
|
|
||||||
c1,
|
|
||||||
buttonContainer.lastChild.lastChild
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSavedUserList() {
|
|
||||||
return JSON.parse(localStorage.getItem(LS_UserList) || "[]");
|
|
||||||
}
|
|
||||||
|
|
||||||
function addUserToSavedList(username) {
|
|
||||||
let userList = getSavedUserList();
|
|
||||||
|
|
||||||
if (!userList.includes(username)) {
|
|
||||||
userList.push(username);
|
|
||||||
localStorage.setItem(LS_UserList, JSON.stringify(userList));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function saveNote(username, note) {
|
const Mouse = {
|
||||||
addUserToSavedList(username);
|
mousePosition: {x: 0, y: 0},
|
||||||
localStorage.setItem(LS_Prefix + username, note);
|
lastMousePosition: {x: 0, y: 0},
|
||||||
}
|
handleMouseMove: (event) => {
|
||||||
function getNote(username) {
|
if (isMouseDown) {
|
||||||
return localStorage.getItem(LS_Prefix + username) || "";
|
if (activeContainer) {
|
||||||
}
|
const dx = Mouse.mousePosition.x - Mouse.lastMousePosition.x;
|
||||||
|
const dy = Mouse.mousePosition.y - Mouse.lastMousePosition.y;
|
||||||
function handleMouseMove(event) {
|
openContainers[activeContainer].style.top =
|
||||||
event = event || window.event;
|
parseInt(openContainers[activeContainer].style.top) + dy + "px";
|
||||||
if (isMouseDown) {
|
openContainers[activeContainer].style.left =
|
||||||
if (activeContainer) {
|
parseInt(openContainers[activeContainer].style.left) + dx + "px";
|
||||||
const dx = mousePosition.x - lastMousePosition.x;
|
}
|
||||||
const dy = mousePosition.y - lastMousePosition.y;
|
}
|
||||||
openContainers[activeContainer].style.top =
|
Mouse.updateMousePosition(event.clientX, event.clientY);
|
||||||
parseInt(openContainers[activeContainer].style.top) + dy + "px";
|
},
|
||||||
openContainers[activeContainer].style.left =
|
handleMouseUp: () => {
|
||||||
parseInt(openContainers[activeContainer].style.left) + dx + "px";
|
activeContainer = null;
|
||||||
}
|
isMouseDown = false;
|
||||||
|
},
|
||||||
|
updateMousePosition: (x, y) => {
|
||||||
|
Mouse.lastMousePosition = {...Mouse.mousePosition};
|
||||||
|
Mouse.mousePosition = {x, y};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateMousePosition(event.clientX, event.clientY);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMouseUp(event) {
|
function createElement(tag, body, classes, styles, attributes) {
|
||||||
activeContainer = null;
|
const element = document.createElement(tag);
|
||||||
isMouseDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateMousePosition(x, y) {
|
if (body) {
|
||||||
lastMousePosition = { ...mousePosition };
|
element.innerHTML = body;
|
||||||
mousePosition.x = x;
|
}
|
||||||
mousePosition.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeContainer(username) {
|
if (classes) {
|
||||||
if (!openContainers[username]) return;
|
if (typeof classes === 'object') {
|
||||||
openContainers[username].remove();
|
for (let className of classes) {
|
||||||
delete openContainers[username];
|
element.classList.add((className));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
element.classList.add(classes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function addContainer(username, container) {
|
if (styles) {
|
||||||
if (openContainers[username]) return;
|
if (typeof styles === 'object') {
|
||||||
openContainers[username] = container;
|
for (let style in styles) {
|
||||||
document.body.appendChild(container);
|
element.style[style] = styles[style];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function openTwitchNote(username) {
|
if (attributes) {
|
||||||
// CONTAINER
|
if (typeof attributes === 'object') {
|
||||||
const container = document.createElement("div");
|
for (let attribute in attributes) {
|
||||||
container.style.left = mousePosition.x + "px";
|
element.setAttribute(attribute, attributes[attribute]);
|
||||||
container.style.top = mousePosition.y + 10 + "px";
|
}
|
||||||
container.classList.add("twitch-note-container");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HEADER
|
return element;
|
||||||
const header = document.createElement("div");
|
}
|
||||||
header.classList.add("twitch-note-header");
|
|
||||||
header.addEventListener("mousedown", function close() {
|
|
||||||
activeContainer = username;
|
|
||||||
isMouseDown = true;
|
|
||||||
});
|
|
||||||
const closeButton = document.createElement("span");
|
|
||||||
closeButton.classList.add("twitch-note-close-button");
|
|
||||||
closeButton.innerText = "X";
|
|
||||||
closeButton.addEventListener("click", function close() {
|
|
||||||
removeContainer(username);
|
|
||||||
});
|
|
||||||
header.appendChild(closeButton);
|
|
||||||
const title = document.createElement("span");
|
|
||||||
title.classList.add("twitch-note-title");
|
|
||||||
title.innerHTML = username;
|
|
||||||
header.appendChild(title);
|
|
||||||
container.appendChild(header);
|
|
||||||
|
|
||||||
// BODY
|
function createSettingsButton(buttonContainer) {
|
||||||
const content = document.createElement("div");
|
|
||||||
content.classList.add("twitch-note-content");
|
|
||||||
content.setAttribute("contentEditable", true);
|
|
||||||
content.innerHTML = getNote(username);
|
|
||||||
|
|
||||||
container.appendChild(content);
|
const c1 = createElement('div', null, null, {marginLeft: "0.5rem !important"});
|
||||||
|
const c2 = createElement('div', null, null, {display: "inline-flex !important"});
|
||||||
|
const settingsButton = createElement('button', 'Notes', 'twitch-notes-settings-button');
|
||||||
|
|
||||||
const saveButton = document.createElement("div");
|
settingsButton.addEventListener("click", toggleSettings);
|
||||||
saveButton.classList.add("twitch-note-save-button");
|
|
||||||
saveButton.innerText = "SAVE";
|
|
||||||
saveButton.addEventListener("click", function () {
|
|
||||||
saveNote(username, content.innerHTML);
|
|
||||||
removeContainer(username);
|
|
||||||
});
|
|
||||||
|
|
||||||
container.appendChild(saveButton);
|
c2.appendChild(settingsButton);
|
||||||
|
c1.appendChild(c2);
|
||||||
|
|
||||||
addContainer(username, container);
|
buttonContainer.lastChild.insertBefore(
|
||||||
}
|
c1,
|
||||||
|
buttonContainer.lastChild.lastChild
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let giveUpAt = Date.now() + 20000;
|
function removeContainer(username) {
|
||||||
|
if (!openContainers[username]) return;
|
||||||
|
openContainers[username].remove();
|
||||||
|
delete openContainers[username];
|
||||||
|
}
|
||||||
|
|
||||||
let changeInProgress = false;
|
function addContainer(username, container) {
|
||||||
|
if (openContainers[username]) return;
|
||||||
|
openContainers[username] = container;
|
||||||
|
document.body.appendChild(container);
|
||||||
|
}
|
||||||
|
|
||||||
let targetNode;
|
function openTwitchNote(username) {
|
||||||
let buttonContainer;
|
|
||||||
|
|
||||||
do {
|
const container = createElement('div', null, 'twitch-note-container', {
|
||||||
targetNode = document.getElementsByClassName(
|
left: Mouse.mousePosition.x + 'px',
|
||||||
"chat-scrollable-area__message-container"
|
top: Mouse.mousePosition.y + 10 + 'px'
|
||||||
)[0];
|
});
|
||||||
} while (!targetNode || giveUpAt < Date.now());
|
|
||||||
|
|
||||||
do {
|
const header = createElement('div', null, 'twitch-note-header');
|
||||||
buttonContainer = document.getElementsByClassName(
|
header.addEventListener("mousedown", function close() {
|
||||||
"chat-input__buttons-container"
|
activeContainer = username;
|
||||||
)[0];
|
isMouseDown = true;
|
||||||
} while (!buttonContainer || giveUpAt < Date.now());
|
});
|
||||||
|
|
||||||
createSettingsButton(buttonContainer);
|
const closeButton = createElement('span', "X", 'twitch-note-close-button')
|
||||||
|
closeButton.addEventListener("click", function close() {
|
||||||
|
removeContainer(username);
|
||||||
|
});
|
||||||
|
|
||||||
// Options for the observer (which mutations to observe)
|
const title = createElement('span', username, 'twitch-note-title');
|
||||||
const config = { attributes: true, childList: true, subtree: true };
|
const content = createElement('div', Notes.getNote(username), 'twitch-note-content', [], {
|
||||||
|
contentEditable: 'true'
|
||||||
|
});
|
||||||
|
|
||||||
// Callback function to execute when mutations are observed
|
const saveButton = createElement('div', 'SAVE', 'twitch-note-save-button')
|
||||||
const callback = (mutationList, observer) => {
|
saveButton.addEventListener("click", function () {
|
||||||
if (!changeInProgress) {
|
Notes.saveNote(username, content.innerHTML);
|
||||||
for (const mutation of mutationList) {
|
removeContainer(username);
|
||||||
if (mutation.type === "childList") {
|
});
|
||||||
changeInProgress = true;
|
|
||||||
let nodes = document.getElementsByClassName("chat-line__message");
|
header.appendChild(closeButton);
|
||||||
let users = [];
|
header.appendChild(title);
|
||||||
for (let node of nodes) {
|
container.appendChild(header);
|
||||||
|
container.appendChild(content);
|
||||||
|
container.appendChild(saveButton);
|
||||||
|
|
||||||
|
addContainer(username, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNoteBadges() {
|
||||||
|
let nodes = document.getElementsByClassName("chat-line__message");
|
||||||
|
let users = [];
|
||||||
|
for (let node of nodes) {
|
||||||
const n = node.querySelector(".chat-author__display-name");
|
const n = node.querySelector(".chat-author__display-name");
|
||||||
if (!n) continue;
|
if (!n) continue;
|
||||||
const usernameContainer = node.querySelector(
|
const usernameContainer = node.querySelector(
|
||||||
".chat-line__username-container"
|
".chat-line__username-container"
|
||||||
);
|
);
|
||||||
|
|
||||||
const username = n.attributes["data-a-user"].value;
|
const username = n.attributes["data-a-user"].value;
|
||||||
if (username) {
|
if (username) {
|
||||||
let noteButton = usernameContainer.querySelector(".twitch-note");
|
let noteButton = usernameContainer.querySelector(".twitch-note");
|
||||||
if (!noteButton) {
|
if (!noteButton) {
|
||||||
const twitchNote = document.createElement("span");
|
|
||||||
twitchNote.classList.add("twitch-note");
|
|
||||||
twitchNote.style.cursor = "pointer";
|
|
||||||
twitchNote.addEventListener("click", () => {
|
|
||||||
openTwitchNote(username);
|
|
||||||
});
|
|
||||||
|
|
||||||
const img = document.createElement("img");
|
const twitchNote = createElement('span', null, 'twitch-note', {
|
||||||
img.src = "https://cdn.rdarius.lt/icons/32-id-card.png";
|
cursor: 'pointer',
|
||||||
img.style.height = "18px";
|
})
|
||||||
img.style.paddingRight = "4px";
|
twitchNote.addEventListener("click", () => {
|
||||||
twitchNote.appendChild(img);
|
openTwitchNote(username);
|
||||||
|
});
|
||||||
|
|
||||||
usernameContainer.insertBefore(
|
const img = createElement('img', null, null, {
|
||||||
twitchNote,
|
height: '18px',
|
||||||
usernameContainer.firstChild
|
paddingRight: '4px'
|
||||||
);
|
}, {
|
||||||
}
|
src: "https://cdn.rdarius.lt/icons/32-id-card.png"
|
||||||
if (!users[username]) {
|
})
|
||||||
users[username] = 0;
|
|
||||||
}
|
twitchNote.appendChild(img);
|
||||||
users[username]++;
|
|
||||||
|
usernameContainer.insertBefore(
|
||||||
|
twitchNote,
|
||||||
|
usernameContainer.firstChild
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!users[username]) {
|
||||||
|
users[username] = 0;
|
||||||
|
}
|
||||||
|
users[username]++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
changeInProgress = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Create an observer instance linked to the callback function
|
function toggleSettings() {
|
||||||
const observer = new MutationObserver(callback);
|
console.log('toggle settings');
|
||||||
|
}
|
||||||
|
|
||||||
// Start observing the target node for configured mutations
|
let openContainers = {};
|
||||||
observer.observe(targetNode, config);
|
let isMouseDown = false;
|
||||||
|
let activeContainer = null;
|
||||||
|
// let settingsWindowOpen = false;
|
||||||
|
|
||||||
|
let LS_UserList = "twitch-note-all-users-list";
|
||||||
|
let LS_Prefix = "twitch-note-";
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", Mouse.handleMouseMove);
|
||||||
|
document.addEventListener("mouseup", Mouse.handleMouseUp);
|
||||||
|
|
||||||
|
let giveUpAt = Date.now() + 20000;
|
||||||
|
|
||||||
|
let changeInProgress = false;
|
||||||
|
|
||||||
|
let targetNode;
|
||||||
|
let buttonContainer;
|
||||||
|
|
||||||
|
do {
|
||||||
|
targetNode = document.getElementsByClassName(
|
||||||
|
"chat-scrollable-area__message-container"
|
||||||
|
)[0];
|
||||||
|
} while (!targetNode || giveUpAt < Date.now());
|
||||||
|
|
||||||
|
do {
|
||||||
|
buttonContainer = document.getElementsByClassName(
|
||||||
|
"chat-input__buttons-container"
|
||||||
|
)[0];
|
||||||
|
} while (!buttonContainer || giveUpAt < Date.now());
|
||||||
|
|
||||||
|
createSettingsButton(buttonContainer);
|
||||||
|
|
||||||
|
// Options for the observer (which mutations to observe)
|
||||||
|
const config = {attributes: true, childList: true, subtree: true};
|
||||||
|
|
||||||
|
// Callback function to execute when mutations are observed
|
||||||
|
const callback = (mutationList) => {
|
||||||
|
if (!changeInProgress) {
|
||||||
|
for (const mutation of mutationList) {
|
||||||
|
if (mutation.type === "childList") {
|
||||||
|
changeInProgress = true;
|
||||||
|
addNoteBadges();
|
||||||
|
changeInProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an observer instance linked to the callback function
|
||||||
|
const observer = new MutationObserver(callback);
|
||||||
|
|
||||||
|
// Start observing the target node for configured mutations
|
||||||
|
observer.observe(targetNode, config);
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user