Updates...
This commit is contained in:
@@ -39,6 +39,5 @@
|
||||
"*://*.twitch.tv/*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"permissions": ["webNavigation"]
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,168 +0,0 @@
|
||||
import {CustomHTMLElementConstructor} from "./types";
|
||||
|
||||
export class CustomHTMLElement<T = HTMLElement> {
|
||||
|
||||
element: HTMLElement;
|
||||
|
||||
constructor(element: string, data: CustomHTMLElementConstructor) {
|
||||
this.element = document.createElement(element);
|
||||
|
||||
if (data.id) {
|
||||
this.setId(data.id);
|
||||
} else {
|
||||
this.setId(element + '-generated-id-' + Math.floor(Math.random() * 10000000));
|
||||
}
|
||||
|
||||
if (data.class) {
|
||||
if (typeof data.class === "string") {
|
||||
this.addClass(data.class);
|
||||
} else {
|
||||
for (const className of data.class) {
|
||||
this.addClass(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.attributes) {
|
||||
for (const key in data.attributes) {
|
||||
this.addAttribute(key, data.attributes[key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.css) this.setStyle(data.css);
|
||||
|
||||
if (data.body) typeof data.body === "string" ? this.setBody(data.body) : this.appendChild(data.body);
|
||||
if (data.customBody) this.appendCustomChild(data.customBody);
|
||||
}
|
||||
|
||||
setId(id: string): CustomHTMLElement<T> {
|
||||
this.element.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
addClass(classes: string): CustomHTMLElement<T> {
|
||||
this.element.classList.add(classes);
|
||||
return this;
|
||||
}
|
||||
|
||||
addAttribute(name: string, value: string): CustomHTMLElement<T> {
|
||||
this.element.setAttribute(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
setStyle(attributes: Partial<CSSStyleDeclaration>): CustomHTMLElement<T> {
|
||||
for(let key in attributes) {
|
||||
this.element.style[key] = attributes[key] || '';
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
setBody(body: string): CustomHTMLElement<T> {
|
||||
this.element.innerHTML = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
appendBody(body: string): CustomHTMLElement<T> {
|
||||
this.element.innerHTML += body;
|
||||
return this;
|
||||
}
|
||||
|
||||
appendChild(child: HTMLElement): CustomHTMLElement<T> {
|
||||
this.element.appendChild(child);
|
||||
return this;
|
||||
}
|
||||
|
||||
appendCustomChild(child: CustomHTMLElement): CustomHTMLElement<T> {
|
||||
this.element.appendChild(child.getElement());
|
||||
return this;
|
||||
}
|
||||
|
||||
getElement(): T {
|
||||
return this.element as T;
|
||||
}
|
||||
|
||||
setClickListener(listener: Function): CustomHTMLElement<T> {
|
||||
this.element.addEventListener('click', () => listener());
|
||||
return this;
|
||||
}
|
||||
|
||||
setChangeListener(listener: Function): CustomHTMLElement<T> {
|
||||
this.element.addEventListener('change', () => listener());
|
||||
return this;
|
||||
}
|
||||
|
||||
setMouseMoveListener(listener: Function): CustomHTMLElement<T> {
|
||||
this.element.addEventListener('mousemove', () => listener());
|
||||
return this;
|
||||
}
|
||||
|
||||
setMouseDownListener(listener: Function): CustomHTMLElement<T> {
|
||||
this.element.addEventListener('mousedown', () => listener());
|
||||
return this;
|
||||
}
|
||||
|
||||
setMouseUpListener(listener: Function): CustomHTMLElement<T> {
|
||||
this.element.addEventListener('mouseup', () => listener());
|
||||
return this;
|
||||
}
|
||||
|
||||
remove(): void {
|
||||
this.element.remove();
|
||||
}
|
||||
|
||||
show(): CustomHTMLElement<T> {
|
||||
this.setStyle({
|
||||
display: 'unset',
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
hide(): CustomHTMLElement<T> {
|
||||
this.setStyle({
|
||||
display: 'none',
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class CustomDivElement extends CustomHTMLElement<HTMLDivElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('div', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
export class CustomInputElement extends CustomHTMLElement<HTMLInputElement> {
|
||||
constructor(className: string = '') {
|
||||
super('input', {class: className});
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomPElement extends CustomHTMLElement<HTMLParagraphElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('p', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomButtonElement extends CustomHTMLElement<HTMLButtonElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('button', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomAElement extends CustomHTMLElement<HTMLAnchorElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('a', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomSpanElement extends CustomHTMLElement<HTMLSpanElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('span', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomImgElement extends CustomHTMLElement<HTMLSpanElement> {
|
||||
constructor(className: string = '', content: string = '') {
|
||||
super('img', {class: className, body: content});
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,11 @@ export default class HTMLBuilder {
|
||||
if (data.attributes) this.setAttributes(data.attributes);
|
||||
if (data.style) this.setStyles(data.style);
|
||||
if (data.mouseClickEvent) this.setMouseClickListener(data.mouseClickEvent);
|
||||
if (data.mouseMoveEvent) this.setMouseClickListener(data.mouseMoveEvent);
|
||||
if (data.mouseDownEvent) this.setMouseClickListener(data.mouseDownEvent);
|
||||
if (data.mouseUpEvent) this.setMouseClickListener(data.mouseUpEvent);
|
||||
if (data.mouseMoveEvent) this.setMouseMoveListener(data.mouseMoveEvent);
|
||||
if (data.mouseDownEvent) this.setMouseDownListener(data.mouseDownEvent);
|
||||
if (data.mouseUpEvent) this.setMouseUpListener(data.mouseUpEvent);
|
||||
if (data.keyUpEvent) this.setKeyUpListener(data.keyUpEvent);
|
||||
if (data.changeListener) this.setChangeListener(data.changeListener);
|
||||
if (data.content) this.setContent(data.content);
|
||||
}
|
||||
|
||||
@@ -61,18 +62,22 @@ export default class HTMLBuilder {
|
||||
this.element.addEventListener('click', () => cb());
|
||||
}
|
||||
|
||||
setContent(content: (HTMLBuilderBlock|string)[]) {
|
||||
setContent(content: (HTMLBuilderBlock|string|HTMLElement)[]) {
|
||||
for (let block of content) {
|
||||
this.addContent(block);
|
||||
}
|
||||
}
|
||||
|
||||
addContent(content: HTMLBuilderBlock|string) {
|
||||
addContent(content: HTMLBuilderBlock|string|HTMLElement) {
|
||||
if (typeof content === 'string') {
|
||||
this.element.innerHTML += content;
|
||||
} else {
|
||||
const el = new HTMLBuilder(content);
|
||||
this.element.appendChild(el.element)
|
||||
if (content instanceof HTMLElement) {
|
||||
this.element.appendChild(content);
|
||||
} else {
|
||||
const el = new HTMLBuilder(content);
|
||||
this.element.appendChild(el.element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +97,10 @@ export default class HTMLBuilder {
|
||||
this.element.addEventListener('keyup', () => cb(this.element.innerHTML));
|
||||
}
|
||||
|
||||
setChangeListener(cb: Function) {
|
||||
this.element.addEventListener('change', (e) => cb(e));
|
||||
}
|
||||
|
||||
getElement() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
30
src/HTMLElements/TwitchButton.ts
Normal file
30
src/HTMLElements/TwitchButton.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export default class TwitchButton {
|
||||
|
||||
element: HTMLButtonElement;
|
||||
|
||||
constructor(content: string, type: 'default' | 'outline' = 'default', classes: string|string[] = '') {
|
||||
this.element = document.createElement('button');
|
||||
this.element.textContent = content;
|
||||
|
||||
this.element.classList.add('twitch-notes_button');
|
||||
if(type === 'outline') {
|
||||
this.element.classList.add('twitch-notes_button__outline');
|
||||
}
|
||||
|
||||
if (classes) {
|
||||
if (typeof classes === 'string') {
|
||||
this.element.classList.add(classes);
|
||||
} else {
|
||||
for (let className of classes) {
|
||||
this.element.classList.add(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClick(cb: Function) {
|
||||
this.element.addEventListener('click', () => cb());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
31
src/HTMLElements/TwitchCloseButton.ts
Normal file
31
src/HTMLElements/TwitchCloseButton.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
export default class TwitchCloseButton {
|
||||
|
||||
element: HTMLButtonElement;
|
||||
|
||||
constructor(classes: string|string[] = '') {
|
||||
this.element = document.createElement('button');
|
||||
this.element.innerHTML = `<svg width="100%" height="100%" viewBox="0 0 20 20" x="0px" y="0px" class="twitch-notes_x-button">
|
||||
<g>
|
||||
<path d="M8.5 10L4 5.5 5.5 4 10 8.5 14.5 4 16 5.5 11.5 10l4.5 4.5-1.5 1.5-4.5-4.5L5.5 16 4 14.5 8.5 10z"></path>
|
||||
</g>
|
||||
</svg>`;
|
||||
|
||||
this.element.classList.add('twitch-notes_close-button');
|
||||
|
||||
if (classes) {
|
||||
if (typeof classes === 'string') {
|
||||
this.element.classList.add(classes);
|
||||
} else {
|
||||
for (let className of classes) {
|
||||
this.element.classList.add(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClick(cb: Function) {
|
||||
this.element.addEventListener('click', () => cb());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
113
src/HTMLElements/TwitchNotesImport.ts
Normal file
113
src/HTMLElements/TwitchNotesImport.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import TwitchCloseButton from "./TwitchCloseButton";
|
||||
import NoteStorage from "../NoteStorage";
|
||||
// import openImportNotesWindow from "../openImprtNotesWindow";
|
||||
import openClearDataWindow from "../openClearDataWindow";
|
||||
import TwitchButton from "./TwitchButton";
|
||||
import TwitchNotesWindow from "./TwitchNotesWindow";
|
||||
import importNotesResult from "../importNotesResult";
|
||||
import TwitchNotesImportResolve from "./TwitchNotesImportResolve";
|
||||
|
||||
export default class TwitchNotesImport {
|
||||
|
||||
private static instance?: TwitchNotesImport;
|
||||
private element?: HTMLDivElement;
|
||||
private userList?: HTMLDivElement;
|
||||
private static resolveCallback?: Function;
|
||||
|
||||
constructor() {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
private create() {
|
||||
if (!this.element) {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
this.element.innerHTML = '';
|
||||
|
||||
this.element.classList.add('twitch-notes-blurred-background');
|
||||
|
||||
const closeButton = new TwitchCloseButton();
|
||||
closeButton.onClick(() => {
|
||||
this.close();
|
||||
});
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('twitch-notes-center-floating-container');
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('twitch-notes-container-header');
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.classList.add('twitch-notes-container-header-title');
|
||||
title.textContent = 'Import Notes';
|
||||
header.appendChild(title);
|
||||
container.appendChild(header);
|
||||
header.insertAdjacentElement("beforeend", closeButton.element);
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.classList.add('twitch-notes-container-content');
|
||||
content.style.display = 'block';
|
||||
content.style.padding = '1rem';
|
||||
container.appendChild(content);
|
||||
|
||||
content.innerHTML = `
|
||||
<strong>WARNING!</strong> <em>This action might override existing data!</em><br />
|
||||
<br />
|
||||
Select exported twitch notes file<br />
|
||||
`;
|
||||
|
||||
const blurredBackground = this.element;
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.classList.add('twitch-notes-file-input');
|
||||
input.setAttribute('type', 'file');
|
||||
input.setAttribute('accept', 'json');
|
||||
input.addEventListener('change', () => {
|
||||
if (!input.files) return;
|
||||
// @ts-ignore
|
||||
let file = input.files.item(0);
|
||||
if (!file) return;
|
||||
let reader = new FileReader();
|
||||
reader.readAsText(file, "UTF-8");
|
||||
reader.onload = function (evt) {
|
||||
if (!evt?.target?.result) return;
|
||||
|
||||
NoteStorage.inputData = JSON.parse(evt.target.result.toString());
|
||||
if (NoteStorage.inputData) {
|
||||
input.style.display = 'none';
|
||||
importNotesResult(container, blurredBackground, TwitchNotesImport.resolveCallback);
|
||||
}
|
||||
}
|
||||
reader.onerror = function () {
|
||||
console.error("error reading file");
|
||||
}
|
||||
});
|
||||
|
||||
content.appendChild(input);
|
||||
|
||||
this.element.appendChild(container);
|
||||
document.body.appendChild(this.element);
|
||||
}
|
||||
|
||||
private close() {
|
||||
if (this.element) this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
public static update() {
|
||||
TwitchNotesImport.instance?.create();
|
||||
}
|
||||
|
||||
public static open(cb: Function) {
|
||||
TwitchNotesImport.resolveCallback = cb;
|
||||
TwitchNotesImport.instance = new TwitchNotesImport();
|
||||
TwitchNotesImport.instance.create();
|
||||
}
|
||||
|
||||
public static close() {
|
||||
TwitchNotesImport.instance?.element?.remove();
|
||||
TwitchNotesImport.instance = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
76
src/HTMLElements/TwitchNotesImportResolve.ts
Normal file
76
src/HTMLElements/TwitchNotesImportResolve.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import TwitchCloseButton from "./TwitchCloseButton";
|
||||
import NoteStorage from "../NoteStorage";
|
||||
// import openImportNotesWindow from "../openImprtNotesWindow";
|
||||
import openClearDataWindow from "../openClearDataWindow";
|
||||
import TwitchButton from "./TwitchButton";
|
||||
import TwitchNotesWindow from "./TwitchNotesWindow";
|
||||
import importNotesResult from "../importNotesResult";
|
||||
import importNotesConflictResolve from "../importNotesConflictResolve";
|
||||
import HTMLBuilder from "../HTMLBuilder";
|
||||
|
||||
export default class TwitchNotesImportResolve {
|
||||
|
||||
private static instance?: TwitchNotesImportResolve;
|
||||
private element?: HTMLDivElement;
|
||||
|
||||
constructor() {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
private create(
|
||||
user: string,
|
||||
parentContainer: HTMLElement,
|
||||
blurredBackground: HTMLElement
|
||||
) {
|
||||
if (!this.element) {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
this.element.innerHTML = '';
|
||||
|
||||
this.element.classList.add('twitch-notes-blurred-background');
|
||||
|
||||
const closeButton = new TwitchCloseButton();
|
||||
closeButton.onClick(() => {
|
||||
this.close();
|
||||
});
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('twitch-notes-center-floating-container');
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('twitch-notes-container-header');
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.classList.add('twitch-notes-container-header-title');
|
||||
title.textContent = 'Resolve note ('+user+') conflict';
|
||||
header.appendChild(title);
|
||||
container.appendChild(header);
|
||||
header.insertAdjacentElement("beforeend", closeButton.element);
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.classList.add('twitch-notes-container-content');
|
||||
content.style.display = 'block';
|
||||
content.style.padding = '1rem';
|
||||
container.appendChild(content);
|
||||
|
||||
content.appendChild(importNotesConflictResolve(user, this.element, parentContainer, blurredBackground));
|
||||
|
||||
this.element.appendChild(container);
|
||||
document.body.appendChild(this.element);
|
||||
}
|
||||
|
||||
private close() {
|
||||
if (this.element) this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
public static open(user: string,
|
||||
container: HTMLElement,
|
||||
blurredBackground: HTMLElement) {
|
||||
TwitchNotesImportResolve.instance = new TwitchNotesImportResolve();
|
||||
TwitchNotesImportResolve.instance.create(user, container, blurredBackground);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
259
src/HTMLElements/TwitchNotesWindow.ts
Normal file
259
src/HTMLElements/TwitchNotesWindow.ts
Normal file
@@ -0,0 +1,259 @@
|
||||
import TwitchCloseButton from "./TwitchCloseButton";
|
||||
import NoteStorage from "../NoteStorage";
|
||||
// import openImportNotesWindow from "../openImprtNotesWindow";
|
||||
import openClearDataWindow from "../openClearDataWindow";
|
||||
import TwitchButton from "./TwitchButton";
|
||||
import TwitchNotesImport from "./TwitchNotesImport";
|
||||
|
||||
export default class TwitchNotesWindow {
|
||||
|
||||
private static instance?: TwitchNotesWindow;
|
||||
private element?: HTMLDivElement;
|
||||
private userList?: HTMLDivElement;
|
||||
|
||||
constructor() {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
private buildContent(content: HTMLDivElement) {
|
||||
content.innerHTML = '';
|
||||
|
||||
const userButtons: HTMLDivElement[] = [];
|
||||
|
||||
this.userList = document.createElement('div');
|
||||
this.userList.classList.add('twitch-notes-container-content-user-list');
|
||||
|
||||
const addNoteButton = document.createElement('div');
|
||||
addNoteButton.classList.add('twitch-notes-container-content-user-list-item');
|
||||
addNoteButton.textContent = '+ Add New Note';
|
||||
addNoteButton.addEventListener('click', () => {
|
||||
this.newNote(noteContainer, userButtons);
|
||||
});
|
||||
this.userList.appendChild(addNoteButton);
|
||||
|
||||
const searchField = document.createElement('input');
|
||||
searchField.classList.add('twitch-notes-container-content-user-list-item');
|
||||
searchField.classList.add('twitch-notes-container-content-user-list-item-search');
|
||||
searchField.placeholder = 'Search...'
|
||||
searchField.addEventListener('keyup', () => {
|
||||
for(let row of userButtons) {
|
||||
if (searchField.value === '') {
|
||||
row.style.display = 'block';
|
||||
continue;
|
||||
}
|
||||
if(row.textContent?.includes(searchField.value)) {
|
||||
row.style.display = 'block';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.userList.appendChild(searchField);
|
||||
|
||||
for (const user of NoteStorage.getSavedUserList()) {
|
||||
const userButton = document.createElement('div');
|
||||
userButton.classList.add('twitch-notes-container-content-user-list-item');
|
||||
userButton.textContent = user;
|
||||
userButtons.push(userButton);
|
||||
this.userList.appendChild(userButton);
|
||||
userButton.addEventListener('click', () => {
|
||||
this.openNote(noteContainer, user, userButtons, userButton);
|
||||
});
|
||||
}
|
||||
|
||||
const noteContainer = document.createElement('div');
|
||||
noteContainer.classList.add('twitch-notes-container-content-note-container');
|
||||
|
||||
if (NoteStorage.getSavedUserList().length) {
|
||||
userButtons[0].click();
|
||||
} else {
|
||||
noteContainer.textContent = '';
|
||||
const noNotes = document.createElement('div');
|
||||
noNotes.classList.add('twitch-notes-container-content-note-container-note');
|
||||
noNotes.innerHTML = 'You have not notes yet...';
|
||||
noteContainer.appendChild(noNotes);
|
||||
}
|
||||
|
||||
content.appendChild(this.userList);
|
||||
content.appendChild(noteContainer);
|
||||
}
|
||||
|
||||
private newNote(noteContainer: HTMLDivElement, userButtons: HTMLDivElement[]) {
|
||||
noteContainer.innerHTML = '';
|
||||
for (let btn of userButtons) {
|
||||
btn.style.background = 'transparent';
|
||||
}
|
||||
|
||||
const noteTitle = document.createElement('input');
|
||||
noteTitle.classList.add('twitch-notes-container-header-title');
|
||||
noteTitle.classList.add('twitch-notes-container-content-user-list-item-search');
|
||||
noteTitle.style.marginTop = '1rem';
|
||||
noteTitle.placeholder = 'Note title or username';
|
||||
noteContainer.appendChild(noteTitle);
|
||||
|
||||
const note = document.createElement('div');
|
||||
note.classList.add('twitch-notes-container-content-note-container-note');
|
||||
note.setAttribute('contentEditable', 'true');
|
||||
note.innerHTML = '';
|
||||
|
||||
noteContainer.appendChild(note);
|
||||
|
||||
const controls = document.createElement('div');
|
||||
controls.classList.add('twitch-notes-container-content-note-container-controls');
|
||||
noteContainer.appendChild(controls);
|
||||
|
||||
const save = new TwitchButton('Save');
|
||||
controls.appendChild(save.element);
|
||||
|
||||
const savedNote = document.createElement('span');
|
||||
savedNote.classList.add('twitch-notes-container-content-note-container-controls-saved')
|
||||
savedNote.textContent = 'Note Saved!';
|
||||
savedNote.style.opacity = '0';
|
||||
controls.appendChild(savedNote);
|
||||
|
||||
save.onClick(() => {
|
||||
const user = noteTitle.value.trim().toLowerCase();
|
||||
const userButton = document.createElement('div');
|
||||
userButton.classList.add('twitch-notes-container-content-user-list-item');
|
||||
userButton.textContent = user;
|
||||
userButtons.push(userButton);
|
||||
this.userList?.appendChild(userButton);
|
||||
userButton.addEventListener('click', () => {
|
||||
this.openNote(noteContainer, user, userButtons, userButton);
|
||||
});
|
||||
userButtons.push(userButton);
|
||||
NoteStorage.saveNote(user, note.innerHTML);
|
||||
this.openNote(noteContainer, user, userButtons, userButton);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private openNote(noteContainer: HTMLDivElement, user: string, userButtons: HTMLDivElement[], userButton: HTMLDivElement) {
|
||||
noteContainer.innerHTML = '';
|
||||
for (let btn of userButtons) {
|
||||
btn.style.background = 'transparent';
|
||||
}
|
||||
userButton.style.background = 'var(--color-twitch-purple-5)'
|
||||
const noteTitle = document.createElement('div');
|
||||
noteTitle.classList.add('twitch-notes-container-header-title');
|
||||
noteTitle.textContent = user;
|
||||
noteTitle.style.marginTop = '1rem';
|
||||
noteContainer.appendChild(noteTitle);
|
||||
|
||||
const note = document.createElement('div');
|
||||
note.classList.add('twitch-notes-container-content-note-container-note');
|
||||
note.setAttribute('contentEditable', 'true');
|
||||
note.innerHTML = NoteStorage.getNote(user);
|
||||
|
||||
noteContainer.appendChild(note);
|
||||
|
||||
const controls = document.createElement('div');
|
||||
controls.classList.add('twitch-notes-container-content-note-container-controls');
|
||||
noteContainer.appendChild(controls);
|
||||
|
||||
const save = new TwitchButton('Save');
|
||||
controls.appendChild(save.element);
|
||||
|
||||
const savedNote = document.createElement('span');
|
||||
savedNote.classList.add('twitch-notes-container-content-note-container-controls-saved')
|
||||
savedNote.textContent = 'Note Saved!';
|
||||
savedNote.style.opacity = '0';
|
||||
controls.appendChild(savedNote);
|
||||
|
||||
save.onClick(() => {
|
||||
NoteStorage.saveNote(user, note.innerHTML);
|
||||
savedNote.style.opacity = '1';
|
||||
});
|
||||
}
|
||||
|
||||
private create() {
|
||||
if (!this.element) {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
this.element.innerHTML = '';
|
||||
|
||||
this.element.classList.add('twitch-notes-blurred-background');
|
||||
|
||||
const closeButton = new TwitchCloseButton();
|
||||
closeButton.onClick(() => {
|
||||
this.close();
|
||||
});
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('twitch-notes-center-floating-container');
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('twitch-notes-container-header');
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.classList.add('twitch-notes-container-header-title');
|
||||
title.textContent = 'Twitch Notes';
|
||||
header.appendChild(title);
|
||||
container.appendChild(header);
|
||||
header.insertAdjacentElement("beforeend", closeButton.element);
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.classList.add('twitch-notes-container-content')
|
||||
container.appendChild(content);
|
||||
|
||||
this.buildContent(content);
|
||||
|
||||
const footer = document.createElement('div');
|
||||
footer.classList.add('twitch-notes-container-footer');
|
||||
container.appendChild(footer);
|
||||
|
||||
const exportNotes = document.createElement('span');
|
||||
exportNotes.classList.add('twitch-notes-link');
|
||||
exportNotes.textContent = 'Export Notes';
|
||||
exportNotes.addEventListener('click', () => {
|
||||
NoteStorage.exportNotes();
|
||||
})
|
||||
footer.appendChild(exportNotes);
|
||||
|
||||
const importNotes = document.createElement('span');
|
||||
importNotes.classList.add('twitch-notes-link');
|
||||
importNotes.textContent = 'Import Notes';
|
||||
importNotes.addEventListener('click', () => {
|
||||
TwitchNotesImport.open(() => {
|
||||
TwitchNotesWindow.update();
|
||||
});
|
||||
});
|
||||
footer.appendChild(importNotes);
|
||||
|
||||
const clearNotes = document.createElement('span');
|
||||
clearNotes.classList.add('twitch-notes-link');
|
||||
clearNotes.textContent = 'Clear Notes';
|
||||
clearNotes.addEventListener('click', () => {
|
||||
openClearDataWindow();
|
||||
});
|
||||
footer.appendChild(clearNotes);
|
||||
|
||||
this.element.appendChild(container);
|
||||
document.body.appendChild(this.element);
|
||||
}
|
||||
|
||||
private close() {
|
||||
if (this.element) this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
public static update() {
|
||||
TwitchNotesWindow.instance?.create();
|
||||
}
|
||||
|
||||
public static toggle() {
|
||||
if (!TwitchNotesWindow.instance) {
|
||||
TwitchNotesWindow.instance = new TwitchNotesWindow();
|
||||
TwitchNotesWindow.instance.create();
|
||||
return;
|
||||
}
|
||||
if (TwitchNotesWindow.instance.element) {
|
||||
TwitchNotesWindow.instance.close();
|
||||
} else {
|
||||
TwitchNotesWindow.instance.create();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export default class Mouse {
|
||||
}
|
||||
|
||||
static handleMouseUp() {
|
||||
NoteContainers.activeContainer = '';
|
||||
NoteContainers.activeContainer = null;
|
||||
Mouse.isMouseDown = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
|
||||
const containers: {[key: string]: HTMLBuilder} = {};
|
||||
export default class NoteContainers {
|
||||
static activeContainer: string | null = null;
|
||||
static containers: { [key: string]: HTMLBuilder } = {};
|
||||
|
||||
export default {
|
||||
activeContainer: '',
|
||||
containers,
|
||||
addContainer(username: string, container: HTMLBuilder) {
|
||||
if (this.containers[username]) return;
|
||||
this.containers[username] = container;
|
||||
},
|
||||
removeContainer(username: string) {
|
||||
if (!this.containers[username]) return;
|
||||
this.containers[username].remove();
|
||||
delete this.containers[username];
|
||||
}
|
||||
static addContainer(username: string, container: HTMLBuilder) {
|
||||
if (NoteContainers.containers[username]) return;
|
||||
NoteContainers.containers[username] = container;
|
||||
};
|
||||
|
||||
static removeContainer(username: string) {
|
||||
if (!NoteContainers.containers[username]) return;
|
||||
NoteContainers.containers[username].remove();
|
||||
delete NoteContainers.containers[username];
|
||||
};
|
||||
}
|
||||
@@ -2,15 +2,14 @@ import { ELEMENT_ButtonContainer } from "./const";
|
||||
import toggleSettingsList from "./toggleSettingsList";
|
||||
import openTwitchNote from "./openTwitchNote";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
import TwitchButton from "./HTMLElements/TwitchButton";
|
||||
import TwitchNotesWindow from "./HTMLElements/TwitchNotesWindow";
|
||||
|
||||
export default class TwitchNote {
|
||||
|
||||
observer: MutationObserver | null = null;
|
||||
observer?: MutationObserver;
|
||||
chatContainerNode?: Element;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
init(chatContainerNode: Element) {
|
||||
this.chatContainerNode = chatContainerNode;
|
||||
this.startObserver(chatContainerNode);
|
||||
@@ -55,41 +54,16 @@ export default class TwitchNote {
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = new HTMLBuilder({
|
||||
element: 'div',
|
||||
style: {
|
||||
marginLeft: "0.5rem !important"
|
||||
},
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
style: {
|
||||
display: "inline-flex !important"
|
||||
},
|
||||
content: [
|
||||
{
|
||||
element: 'button',
|
||||
class: [
|
||||
'twitch-notes-settings-button',
|
||||
'twitch-notes-settings-button__outline'
|
||||
],
|
||||
content: [
|
||||
'Notes'
|
||||
],
|
||||
mouseClickEvent: () => toggleSettingsList(),
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
const button = new TwitchButton('Notes', 'outline');
|
||||
button.onClick(TwitchNotesWindow.toggle);
|
||||
|
||||
if (buttonContainer.lastChild) {
|
||||
buttonContainer.lastChild.insertBefore(
|
||||
btn.getElement(),
|
||||
button.element,
|
||||
buttonContainer.lastChild.lastChild
|
||||
);
|
||||
} else {
|
||||
buttonContainer.appendChild(btn.getElement());
|
||||
buttonContainer.appendChild(button.element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,85 +1,101 @@
|
||||
import {CustomButtonElement, CustomDivElement, CustomHTMLElement, CustomPElement} from "./CustomHTMLElement";
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import importNotesResult from "./importNotesResult";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
|
||||
export default function importNotesConflictResolve(
|
||||
user: string,
|
||||
resultsContainer: CustomHTMLElement,
|
||||
container: CustomHTMLElement,
|
||||
blurredBackground: CustomHTMLElement
|
||||
resultsContainer: HTMLElement,
|
||||
container: HTMLElement,
|
||||
blurredBackground: HTMLElement
|
||||
) {
|
||||
const diffBlurredBackground = new CustomDivElement('twitch-notes-blurred-background');
|
||||
const diffContainer = new CustomDivElement('twitch-notes-center-floating-container', '<strong>Select which note to keep for <em>' + user + '</em></strong><br /><em>You can modify notes to merge them and keep updated one</em><br /><br />');
|
||||
|
||||
const inputContainer = new CustomDivElement();
|
||||
inputContainer.setStyle({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'no-wrap',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
const valueStyle = {
|
||||
minWidth: '320px',
|
||||
padding: '6px',
|
||||
border: '1px solid #FFFFFF19',
|
||||
outline: 'none',
|
||||
};
|
||||
const valueAttr: [string, string] = ['contentEditable', 'true'];
|
||||
const valueAttr = {contentEditable: 'true'};
|
||||
|
||||
const localValueContainer = new CustomDivElement();
|
||||
const pLocal = new CustomPElement('', '<strong>Locally saved note</strong>');
|
||||
localValueContainer.appendCustomChild(pLocal);
|
||||
|
||||
const localValue = new CustomDivElement();
|
||||
localValue.setStyle(valueStyle);
|
||||
localValue.addAttribute(...valueAttr);
|
||||
localValue.setId('local-value-container');
|
||||
const localValueSave = new CustomButtonElement('twitch-notes-settings-button', 'Save this');
|
||||
localValueSave.setClickListener(() => {
|
||||
const val = document.getElementById('local-value-container')?.innerHTML || '';
|
||||
NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? {
|
||||
user: n.user,
|
||||
note: val,
|
||||
resolved: true
|
||||
} : n);
|
||||
diffBlurredBackground.remove();
|
||||
resultsContainer.remove();
|
||||
importNotesResult(container, blurredBackground);
|
||||
const diffBlurredBackground = new HTMLBuilder({
|
||||
element: 'div',
|
||||
content: [
|
||||
'<strong>Select which note to keep for <em>' + user + '</em></strong><br /><em>You can modify notes to merge them and keep updated one</em><br /><br />',
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-grid-col-2',
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
content: [{
|
||||
element: 'p',
|
||||
content: [
|
||||
'<strong>Locally saved note</strong>',
|
||||
{
|
||||
element: 'div',
|
||||
style: valueStyle,
|
||||
attributes: valueAttr,
|
||||
id: 'local-value-container',
|
||||
content: [NoteStorage.getNote(user)]
|
||||
},
|
||||
'<br />',
|
||||
{
|
||||
element: 'button',
|
||||
class: 'twitch-notes_button',
|
||||
content: ['Save this'],
|
||||
mouseClickEvent: () => {
|
||||
const val = document.getElementById('local-value-container')?.innerHTML || '';
|
||||
NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? {
|
||||
user: n.user,
|
||||
note: val,
|
||||
resolved: true
|
||||
} : n);
|
||||
diffBlurredBackground.remove();
|
||||
resultsContainer.remove();
|
||||
importNotesResult(container, blurredBackground);
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
content: [{
|
||||
element: 'p',
|
||||
content: [
|
||||
'<strong>Locally saved note</strong>',
|
||||
{
|
||||
element: 'div',
|
||||
style: valueStyle,
|
||||
attributes: valueAttr,
|
||||
id: 'import-value-container',
|
||||
content: [NoteStorage.inputData.notes.filter(n => n.user === user)[0].note || '']
|
||||
},
|
||||
'<br />',
|
||||
{
|
||||
element: 'button',
|
||||
class: 'twitch-notes_button',
|
||||
content: ['Save this'],
|
||||
mouseClickEvent: () => {
|
||||
const val = document.getElementById('import-value-container')?.innerHTML || '';
|
||||
NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? {
|
||||
user: n.user,
|
||||
note: val,
|
||||
resolved: true
|
||||
} : n);
|
||||
diffBlurredBackground.remove();
|
||||
resultsContainer.remove();
|
||||
importNotesResult(container, blurredBackground);
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
localValueContainer.appendCustomChild(localValue);
|
||||
localValueContainer.appendBody('<br />');
|
||||
localValueContainer.appendCustomChild(localValueSave);
|
||||
|
||||
const importedValueContainer = new CustomDivElement();
|
||||
const iLocal = new CustomPElement('', '<strong>Imported note</strong>');
|
||||
importedValueContainer.appendCustomChild(iLocal);
|
||||
const importedValue = new CustomDivElement('', NoteStorage.inputData.notes.filter(n => n.user === user)[0].note || '');
|
||||
importedValue.setId('import-value-container');
|
||||
importedValue.setStyle(valueStyle);
|
||||
importedValue.addAttribute(...valueAttr);
|
||||
const importedValueSave = new CustomButtonElement('twitch-notes-settings-button', 'Save this');
|
||||
importedValueSave.setClickListener(() => {
|
||||
const val = document.getElementById('import-value-container')?.innerHTML || '';
|
||||
NoteStorage.inputData.notes = NoteStorage.inputData.notes.map(n => n.user === user ? {
|
||||
user: n.user,
|
||||
note: val,
|
||||
resolved: true
|
||||
} : n);
|
||||
diffBlurredBackground.remove();
|
||||
resultsContainer.remove();
|
||||
importNotesResult(container, blurredBackground);
|
||||
});
|
||||
|
||||
importedValueContainer.appendCustomChild(importedValue);
|
||||
importedValueContainer.appendBody('<br />');
|
||||
importedValueContainer.appendCustomChild(importedValueSave);
|
||||
|
||||
|
||||
inputContainer.appendCustomChild(localValueContainer);
|
||||
inputContainer.appendCustomChild(importedValueContainer);
|
||||
|
||||
diffContainer.appendCustomChild(inputContainer);
|
||||
diffBlurredBackground.appendCustomChild(diffContainer);
|
||||
document.body.appendChild(diffBlurredBackground.getElement());
|
||||
return diffBlurredBackground.getElement();
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import {CustomAElement, CustomButtonElement, CustomDivElement, CustomHTMLElement} from "./CustomHTMLElement";
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import importNotesConflictResolve from "./importNotesConflictResolve";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
import TwitchButton from "./HTMLElements/TwitchButton";
|
||||
import TwitchNotesImportResolve from "./HTMLElements/TwitchNotesImportResolve";
|
||||
|
||||
export default function importNotesResult(container: CustomHTMLElement, blurredBackground: CustomHTMLElement) {
|
||||
export default function importNotesResult(container: HTMLElement, blurredBackground: HTMLElement, cb?: Function) {
|
||||
const willBeAdded = [];
|
||||
let willBeOverwritten = [];
|
||||
const noChanges = [];
|
||||
@@ -19,71 +21,85 @@ export default function importNotesResult(container: CustomHTMLElement, blurredB
|
||||
}
|
||||
}
|
||||
|
||||
const resultsContainer = new CustomDivElement();
|
||||
const resultsContainer = new HTMLBuilder({
|
||||
element: 'div',
|
||||
style: {
|
||||
padding: '1rem'
|
||||
}
|
||||
});
|
||||
|
||||
if (willBeOverwritten.length) {
|
||||
const overwrittenContainer = new CustomDivElement('', '<strong>Note conflicts found for:</strong><br />');
|
||||
overwrittenContainer.setStyle({marginTop: '1rem'});
|
||||
const overwrittenContainer = new HTMLBuilder({
|
||||
element: 'div',
|
||||
content: ['<strong>Note conflicts found for:</strong><br />'],
|
||||
style: {
|
||||
marginTop: '1rem',
|
||||
}
|
||||
});
|
||||
|
||||
for (let item of willBeOverwritten) {
|
||||
const row = new CustomDivElement('', item + ' ');
|
||||
const isResolved = NoteStorage.inputData.notes.find(note => note.user === item)?.resolved;
|
||||
row.setStyle({
|
||||
color: isResolved ? 'green' : 'red',
|
||||
overwrittenContainer.addContent({
|
||||
element: 'div',
|
||||
content: [item + ' ', {
|
||||
element: 'a',
|
||||
content: [isResolved ? '[update]' : '[resolve]'],
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
mouseClickEvent: () => {
|
||||
TwitchNotesImportResolve.open(item, container, blurredBackground);
|
||||
// importNotesConflictResolve(item, resultsContainer, container, blurredBackground);
|
||||
}
|
||||
}],
|
||||
style: {
|
||||
color: isResolved ? 'green' : 'red',
|
||||
}
|
||||
});
|
||||
const resolve = new CustomAElement('', isResolved ? '[update]' : '[resolve]');
|
||||
resolve.setStyle({
|
||||
cursor: 'pointer'
|
||||
});
|
||||
|
||||
resolve.setClickListener(() => {
|
||||
importNotesConflictResolve(item, resultsContainer, container, blurredBackground);
|
||||
})
|
||||
row.appendCustomChild(resolve);
|
||||
overwrittenContainer.appendCustomChild(row);
|
||||
}
|
||||
resultsContainer.appendCustomChild(overwrittenContainer);
|
||||
resultsContainer.addContent(overwrittenContainer.getElement());
|
||||
}
|
||||
|
||||
if (willBeAdded.length) {
|
||||
const addedContainer = new CustomDivElement('', '<strong>Note will be added for:</strong><br />' + willBeAdded.join('<br />'));
|
||||
addedContainer.setStyle({
|
||||
marginTop: '1rem',
|
||||
color: 'white'
|
||||
resultsContainer.addContent({
|
||||
element: 'div',
|
||||
content: ['<strong>Note will be added for:</strong><br />' + willBeAdded.join('<br />')],
|
||||
style: {
|
||||
marginTop: '1rem',
|
||||
color: 'white'
|
||||
}
|
||||
});
|
||||
resultsContainer.appendCustomChild(addedContainer);
|
||||
}
|
||||
|
||||
if (noChanges.length) {
|
||||
const noChangesContainer = new CustomDivElement('', '<strong>No changes for:</strong><br />' + noChanges.join('<br />'));
|
||||
noChangesContainer.setStyle({
|
||||
marginTop: '1rem',
|
||||
color: 'gray'
|
||||
resultsContainer.addContent({
|
||||
element: 'div',
|
||||
content: ['<strong>No changes for:</strong><br />' + noChanges.join('<br />')],
|
||||
style: {
|
||||
marginTop: '1rem',
|
||||
color: 'gray'
|
||||
}
|
||||
});
|
||||
resultsContainer.appendCustomChild(noChangesContainer);
|
||||
}
|
||||
|
||||
const spacer = new CustomDivElement();
|
||||
spacer.setStyle({height: '24px'});
|
||||
resultsContainer.appendCustomChild(spacer);
|
||||
resultsContainer.addContent({element: 'div', style: {height: '24px'}});
|
||||
|
||||
willBeOverwritten = willBeOverwritten.filter(x => !NoteStorage.inputData.notes.find(n => n.user === x)?.resolved);
|
||||
|
||||
const saveButton = new CustomButtonElement('twitch-notes-settings-button', 'Complete import');
|
||||
saveButton.setStyle({})
|
||||
if (willBeOverwritten.length > 0) saveButton.setStyle({background: 'gray'});
|
||||
if (willBeOverwritten.length > 0) saveButton.addAttribute('disabled', 'true');
|
||||
const saveButton = new TwitchButton('Complete import');
|
||||
if (willBeOverwritten.length > 0) saveButton.element.style.background = 'gray';
|
||||
if (willBeOverwritten.length > 0) saveButton.element.setAttribute('disabled', 'true');
|
||||
|
||||
resultsContainer.appendCustomChild(saveButton)
|
||||
resultsContainer.addContent(saveButton.element)
|
||||
|
||||
if (willBeOverwritten.length > 0) {
|
||||
const note = new CustomDivElement('', '<em>Import cannot be completed while there are unresolved conflicts</em>');
|
||||
note.setStyle({
|
||||
color: 'gray',
|
||||
resultsContainer.addContent({
|
||||
element: 'div',
|
||||
content: ['<em>Import cannot be completed while there are unresolved conflicts</em>'],
|
||||
style: {color: 'gray'}
|
||||
});
|
||||
resultsContainer.appendCustomChild(note);
|
||||
} else {
|
||||
saveButton.setClickListener(() => {
|
||||
saveButton.element.addEventListener('click', () => {
|
||||
for (let note of NoteStorage.inputData.notes) {
|
||||
NoteStorage.saveNote(note.user, note.note);
|
||||
}
|
||||
@@ -93,8 +109,10 @@ export default function importNotesResult(container: CustomHTMLElement, blurredB
|
||||
notes: [],
|
||||
settings: {},
|
||||
};
|
||||
cb ? cb() : () => {};
|
||||
});
|
||||
}
|
||||
|
||||
container.appendCustomChild(resultsContainer);
|
||||
container.innerHTML = '';
|
||||
container.appendChild(resultsContainer.getElement());
|
||||
}
|
||||
@@ -1,126 +1,149 @@
|
||||
import {CustomButtonElement, CustomDivElement, CustomSpanElement} from "./CustomHTMLElement";
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import {getCloseButtonSVG} from "./HTMLTemplates";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
|
||||
export default function openAllNoteListWindow() {
|
||||
let activeNote: string = '';
|
||||
const blurredBackground = new CustomDivElement('twitch-notes-blurred-background');
|
||||
const blurredBackground = new HTMLBuilder({element: "div", class: 'twitch-notes-blurred-background'});
|
||||
|
||||
const noteSaved = new CustomSpanElement('', 'Note saved!');
|
||||
noteSaved.setStyle({
|
||||
color: 'green',
|
||||
marginLeft: '2rem',
|
||||
});
|
||||
noteSaved.hide();
|
||||
|
||||
const container = new CustomDivElement('twitch-notes-center-floating-container');
|
||||
container.setStyle({
|
||||
padding: '0',
|
||||
paddingTop: '1rem',
|
||||
width: '100%',
|
||||
maxWidth: '800px',
|
||||
height: 'calc(320px + 5rem)',
|
||||
maxHeight: '90vh',
|
||||
});
|
||||
|
||||
const closeButton = new CustomButtonElement('twitch-notes-settings-close-button', getCloseButtonSVG());
|
||||
closeButton.setStyle({
|
||||
position: 'absolute',
|
||||
top: '1rem',
|
||||
right: '1rem',
|
||||
});
|
||||
|
||||
const title = new CustomDivElement('twitch-note-title', 'Notes:');
|
||||
title.setStyle({
|
||||
borderBottom: '1px solid #FFFFFF19',
|
||||
paddingBottom: '1rem',
|
||||
});
|
||||
container.appendCustomChild(title);
|
||||
|
||||
const content = new CustomDivElement();
|
||||
content.setStyle({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'no-wrap',
|
||||
width: '100%',
|
||||
height: '320px'
|
||||
});
|
||||
container.appendCustomChild(content);
|
||||
closeButton.setClickListener(() => {
|
||||
blurredBackground.remove();
|
||||
});
|
||||
container.appendCustomChild(closeButton);
|
||||
|
||||
const userList = new CustomDivElement();
|
||||
userList.setStyle({
|
||||
borderRight: '1px solid #FFFFFF19',
|
||||
height: '320px',
|
||||
minWidth: '240px',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
});
|
||||
|
||||
const noteContainer = new CustomDivElement();
|
||||
noteContainer.setStyle({
|
||||
height: '320px',
|
||||
padding: '1rem',
|
||||
width: '100%',
|
||||
opacity: '0',
|
||||
});
|
||||
|
||||
const note = new CustomDivElement();
|
||||
note.setStyle({
|
||||
marginBottom: '3rem',
|
||||
border: '1px solid #FFFFFF19',
|
||||
height: 'calc(320px - 7rem)',
|
||||
width: '100%',
|
||||
padding: '6px',
|
||||
outline: 'none',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
});
|
||||
note.addAttribute('contentEditable', 'true');
|
||||
|
||||
const saveNote = new CustomButtonElement('twitch-notes-settings-button','Save Note');
|
||||
saveNote.setStyle({
|
||||
position: 'absolute',
|
||||
bottom: '1rem',
|
||||
left: '1rem'
|
||||
});
|
||||
|
||||
saveNote.setClickListener(() => {
|
||||
if(!activeNote) {
|
||||
return;
|
||||
const noteSaved = new HTMLBuilder({
|
||||
element: 'span',
|
||||
content: ['Note saved!'],
|
||||
style: {
|
||||
color: 'green',
|
||||
marginLeft: '2rem',
|
||||
display: 'none'
|
||||
}
|
||||
NoteStorage.saveNote(activeNote, note.getElement().innerHTML);
|
||||
noteSaved.setStyle({
|
||||
display: 'inline-block',
|
||||
});
|
||||
});
|
||||
|
||||
for(let user of NoteStorage.getSavedUserList()) {
|
||||
const userLine = new CustomDivElement('twitch-notes-user-list-user', user);
|
||||
userLine.setClickListener(() => {
|
||||
const list = document.getElementsByClassName('twitch-notes-user-list-user');
|
||||
for(let i = 0; i < list.length; i++) {
|
||||
list.item(i)?.removeAttribute('data-active');
|
||||
const content = new HTMLBuilder({
|
||||
element: 'div',
|
||||
style: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'no-wrap',
|
||||
width: '100%',
|
||||
height: '320px'
|
||||
}
|
||||
});
|
||||
|
||||
const closeButton = new HTMLBuilder({
|
||||
element: 'button',
|
||||
class: 'twitch-notes-settings-close-button',
|
||||
content: [getCloseButtonSVG()],
|
||||
style: {
|
||||
position: 'absolute',
|
||||
top: '1rem',
|
||||
right: '1rem',
|
||||
},
|
||||
mouseClickEvent: () => {
|
||||
blurredBackground.remove();
|
||||
}
|
||||
});
|
||||
|
||||
const container = new HTMLBuilder({
|
||||
element: 'div',
|
||||
class: 'twitch-notes-center-floating-container',
|
||||
style: {
|
||||
padding: '0',
|
||||
paddingTop: '1rem',
|
||||
width: '100%',
|
||||
maxWidth: '800px',
|
||||
height: 'calc(320px + 5rem)',
|
||||
maxHeight: '90vh',
|
||||
},
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-title',
|
||||
content: ['Notes:'],
|
||||
style: {
|
||||
borderBottom: '1px solid #FFFFFF19',
|
||||
paddingBottom: '1rem',
|
||||
}
|
||||
},
|
||||
content.getElement(),
|
||||
closeButton.getElement()
|
||||
]
|
||||
});
|
||||
|
||||
const userList = new HTMLBuilder({
|
||||
element: 'div',
|
||||
class: 'twitch-notes-user-list'
|
||||
});
|
||||
|
||||
const noteContainer = new HTMLBuilder({
|
||||
element: 'div',
|
||||
style: {
|
||||
height: '320px',
|
||||
padding: '1rem',
|
||||
width: '100%',
|
||||
opacity: '0',
|
||||
}
|
||||
});
|
||||
|
||||
const note = new HTMLBuilder({
|
||||
element: 'div',
|
||||
style: {
|
||||
marginBottom: '3rem',
|
||||
border: '1px solid #FFFFFF19',
|
||||
height: 'calc(320px - 7rem)',
|
||||
width: '100%',
|
||||
padding: '6px',
|
||||
outline: 'none',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
},
|
||||
attributes: {
|
||||
contentEditable: 'true'
|
||||
}
|
||||
});
|
||||
|
||||
const saveNote = new HTMLBuilder({
|
||||
element: 'button',
|
||||
class: 'twitch-notes-settings-button',
|
||||
content: ['Save Note'],
|
||||
style: {
|
||||
position: 'absolute',
|
||||
bottom: '1rem',
|
||||
left: '1rem'
|
||||
},
|
||||
mouseClickEvent: () => {
|
||||
if (!activeNote) {
|
||||
return;
|
||||
}
|
||||
NoteStorage.saveNote(activeNote, note.getElement().innerHTML);
|
||||
noteSaved.getElement().style.display = 'inline-block';
|
||||
}
|
||||
});
|
||||
|
||||
for (let user of NoteStorage.getSavedUserList()) {
|
||||
const userLine = new HTMLBuilder({
|
||||
element: 'div',
|
||||
class: 'twitch-notes-user-list-user',
|
||||
content: [user],
|
||||
mouseClickEvent: () => {
|
||||
const list = document.getElementsByClassName('twitch-notes-user-list-user');
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
list.item(i)?.removeAttribute('data-active');
|
||||
}
|
||||
noteSaved.getElement().style.display = 'none';
|
||||
userLine.addAttribute('data-active', 'true');
|
||||
noteContainer.getElement().style.opacity = '1';
|
||||
note.getElement().innerHTML = NoteStorage.getNote(user);
|
||||
activeNote = user;
|
||||
}
|
||||
noteSaved.hide();
|
||||
userLine.addAttribute('data-active', 'true');
|
||||
noteContainer.setStyle({opacity: '1'});
|
||||
note.getElement().innerHTML = NoteStorage.getNote(user);
|
||||
activeNote = user;
|
||||
});
|
||||
userList.appendCustomChild(userLine);
|
||||
userList.addContent(userLine.getElement());
|
||||
}
|
||||
|
||||
noteContainer.appendCustomChild(note);
|
||||
noteContainer.appendCustomChild(saveNote);
|
||||
noteContainer.appendCustomChild(noteSaved);
|
||||
noteContainer.addContent(note.getElement());
|
||||
noteContainer.addContent(saveNote.getElement());
|
||||
noteContainer.addContent(noteSaved.getElement());
|
||||
|
||||
content.appendCustomChild(userList);
|
||||
content.appendCustomChild(noteContainer);
|
||||
content.addContent(userList.getElement());
|
||||
content.addContent(noteContainer.getElement());
|
||||
|
||||
blurredBackground.appendCustomChild(container);
|
||||
blurredBackground.addContent(container.getElement());
|
||||
document.body.appendChild(blurredBackground.getElement());
|
||||
}
|
||||
@@ -1,28 +1,48 @@
|
||||
import {CustomButtonElement, CustomDivElement} from "./CustomHTMLElement";
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
import TwitchNotesWindow from "./HTMLElements/TwitchNotesWindow";
|
||||
|
||||
export default function openClearDataWindow() {
|
||||
const blurredBackground = new CustomDivElement( 'twitch-notes-blurred-background');
|
||||
const container = new CustomDivElement('twitch-notes-center-floating-container', '<strong>This action will delete all saved notes!</strong><br /><br /><em>Consider exporting notes before performing this action in case you will need to use notes again</em>');
|
||||
const spacer = new CustomDivElement();
|
||||
spacer.setStyle({
|
||||
height: '24px'
|
||||
const blurredBackground = new HTMLBuilder({
|
||||
element: 'div',
|
||||
class: 'twitch-notes-blurred-background',
|
||||
content: [{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-center-floating-container',
|
||||
style: {
|
||||
padding: '1rem',
|
||||
},
|
||||
content: [
|
||||
'<strong>This action will delete all saved notes!</strong><br /><br /><em>Consider exporting notes before performing this action in case you will need to use notes again</em>',
|
||||
{
|
||||
element: 'div',
|
||||
style: {
|
||||
height: '24px',
|
||||
}
|
||||
},
|
||||
{
|
||||
element: 'button',
|
||||
class: 'twitch-notes_button',
|
||||
content: ['DELETE ALL NOTES'],
|
||||
style: {
|
||||
background: 'red'
|
||||
},
|
||||
mouseClickEvent: () => {
|
||||
NoteStorage.clearData();
|
||||
blurredBackground.remove();
|
||||
TwitchNotesWindow.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
element: 'button',
|
||||
class: 'twitch-notes_button',
|
||||
content: ['Cancel'],
|
||||
mouseClickEvent: () => {
|
||||
blurredBackground.remove();
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
});
|
||||
const deleteAction = new CustomButtonElement('twitch-notes-settings-button', 'DELETE ALL NOTES');
|
||||
deleteAction.setStyle({
|
||||
background: 'red'
|
||||
});
|
||||
deleteAction.setClickListener(() => {
|
||||
NoteStorage.clearData();
|
||||
blurredBackground.remove();
|
||||
});
|
||||
const cancelAction = new CustomButtonElement('twitch-notes-settings-button', 'Cancel');
|
||||
cancelAction.setClickListener(() => {
|
||||
blurredBackground.remove();
|
||||
});
|
||||
container.appendCustomChild(spacer);
|
||||
container.appendCustomChild(deleteAction);
|
||||
container.appendCustomChild(cancelAction);
|
||||
blurredBackground.appendCustomChild(container);
|
||||
document.body.appendChild(blurredBackground.getElement());
|
||||
}
|
||||
@@ -1,52 +1,73 @@
|
||||
import {CustomButtonElement, CustomDivElement, CustomInputElement} from "./CustomHTMLElement";
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import {getCloseButtonSVG} from "./HTMLTemplates";
|
||||
import importNotesResult from "./importNotesResult";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
|
||||
export default function openImportNotesWindow() {
|
||||
const blurredBackground = new CustomDivElement('twitch-notes-blurred-background');
|
||||
const container = new CustomDivElement('twitch-notes-center-floating-container', '<strong>WARNING!</strong> <em>This action might override existing data!</em><br /><br />');
|
||||
const inputBlock = new CustomDivElement('','Select exported twitch notes file<br /><br />');
|
||||
const input = new CustomInputElement('twitch-notes-file-input');
|
||||
input.addAttribute('type', 'file').addAttribute('accept', 'json');
|
||||
const settingsCloseButton = new CustomButtonElement('twitch-notes-settings-close-button', getCloseButtonSVG());
|
||||
settingsCloseButton.setStyle({
|
||||
position: 'absolute',
|
||||
top: '1rem',
|
||||
right: '1rem',
|
||||
});
|
||||
|
||||
inputBlock.appendCustomChild(input);
|
||||
|
||||
settingsCloseButton.setClickListener(() => {
|
||||
blurredBackground.remove();
|
||||
})
|
||||
|
||||
input.setChangeListener(() => {
|
||||
if (!input?.getElement()?.files) return;
|
||||
// @ts-ignore
|
||||
let file = input.getElement().files.item(0);
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
let reader = new FileReader();
|
||||
reader.readAsText(file, "UTF-8");
|
||||
reader.onload = function (evt) {
|
||||
if (!evt?.target?.result) return;
|
||||
|
||||
NoteStorage.inputData = JSON.parse(evt.target.result.toString());
|
||||
if (NoteStorage.inputData) {
|
||||
inputBlock.setStyle({display: 'none'});
|
||||
importNotesResult(container, blurredBackground);
|
||||
}
|
||||
}
|
||||
reader.onerror = function () {
|
||||
console.error("error reading file");
|
||||
}
|
||||
});
|
||||
|
||||
container.appendCustomChild(settingsCloseButton);
|
||||
container.appendCustomChild(inputBlock);
|
||||
blurredBackground.appendCustomChild(container);
|
||||
document.body.appendChild(blurredBackground.getElement());
|
||||
}
|
||||
// export default function openImportNotesWindow() {
|
||||
// const blurredBackground = new HTMLBuilder({
|
||||
// element: 'div',
|
||||
// class: 'twitch-notes-blurred-background'
|
||||
// });
|
||||
// const container = new HTMLBuilder({
|
||||
// element: 'div',
|
||||
// class: 'twitch-notes-center-floating-container',
|
||||
// style: {
|
||||
// padding: '1rem',
|
||||
// },
|
||||
// content: [
|
||||
// '<strong>WARNING!</strong> <em>This action might override existing data!</em><br /><br />',
|
||||
// {
|
||||
// element: 'button',
|
||||
// class: 'twitch-notes-settings-close-button',
|
||||
// content: [getCloseButtonSVG()],
|
||||
// style: {
|
||||
// position: 'absolute',
|
||||
// top: '1rem',
|
||||
// right: '1rem',
|
||||
// },
|
||||
// mouseClickEvent:() => {
|
||||
// blurredBackground.remove();
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// });
|
||||
// const input = new HTMLBuilder({
|
||||
// element: 'input',
|
||||
// class: 'twitch-notes-file-input',
|
||||
// attributes: {
|
||||
// type: 'file',
|
||||
// accept: 'json'
|
||||
// }
|
||||
// });
|
||||
// const inputBlock = new HTMLBuilder({
|
||||
// element: 'div',
|
||||
// content: ['Select exported twitch notes file<br /><br />', input.getElement()]
|
||||
// });
|
||||
//
|
||||
// input.setChangeListener(() => {
|
||||
// if (!(input?.getElement() as HTMLInputElement)?.files) return;
|
||||
// // @ts-ignore
|
||||
// let file = input.getElement().files.item(0);
|
||||
// if (!file) {
|
||||
// return;
|
||||
// }
|
||||
// let reader = new FileReader();
|
||||
// reader.readAsText(file, "UTF-8");
|
||||
// reader.onload = function (evt) {
|
||||
// if (!evt?.target?.result) return;
|
||||
//
|
||||
// NoteStorage.inputData = JSON.parse(evt.target.result.toString());
|
||||
// if (NoteStorage.inputData) {
|
||||
// inputBlock.setStyles({display: 'none'});
|
||||
// importNotesResult(container, blurredBackground);
|
||||
// }
|
||||
// }
|
||||
// reader.onerror = function () {
|
||||
// console.error("error reading file");
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// container.addContent(inputBlock.getElement());
|
||||
// blurredBackground.addContent(container.getElement());
|
||||
// document.body.appendChild(blurredBackground.getElement());
|
||||
// }
|
||||
@@ -10,7 +10,7 @@ export default function openTwitchNote(username: string) {
|
||||
let noteContent = NoteStorage.getNote(username);
|
||||
const container: HTMLBuilderBlock = {
|
||||
element: 'div',
|
||||
class: 'twitch-note-container',
|
||||
class: 'twitch-notes-floating-container',
|
||||
style: {
|
||||
left: Mouse.mousePosition.x + 'px',
|
||||
top: Mouse.mousePosition.y + 10 + 'px'
|
||||
@@ -18,7 +18,7 @@ export default function openTwitchNote(username: string) {
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-note-header',
|
||||
class: 'twitch-notes-header',
|
||||
mouseDownEvent: () => {
|
||||
NoteContainers.activeContainer = username;
|
||||
Mouse.isMouseDown = true;
|
||||
@@ -26,20 +26,20 @@ export default function openTwitchNote(username: string) {
|
||||
content: [
|
||||
{
|
||||
element: 'span',
|
||||
class: 'twitch-note-close-button',
|
||||
class: 'twitch-notes-close-button',
|
||||
content: [getCloseButtonSVG()],
|
||||
mouseClickEvent: () => NoteContainers.removeContainer(username),
|
||||
},
|
||||
{
|
||||
element: 'span',
|
||||
class: 'twitch-note-title',
|
||||
class: 'twitch-notes-title',
|
||||
content: [username],
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-note-content',
|
||||
class: 'twitch-notes-content',
|
||||
content: [NoteStorage.getNote(username)],
|
||||
attributes: {
|
||||
contentEditable: 'true'
|
||||
@@ -50,7 +50,7 @@ export default function openTwitchNote(username: string) {
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-note-save-button',
|
||||
class: 'twitch-notes-save-button',
|
||||
content: ['SAVE'],
|
||||
mouseClickEvent: () => {
|
||||
NoteStorage.saveNote(username, noteContent);
|
||||
|
||||
@@ -1,302 +1,303 @@
|
||||
.twitch-note-container {
|
||||
position: fixed;
|
||||
z-index: 1000000;
|
||||
min-width: 420px;
|
||||
max-width: 95vw;
|
||||
min-height: 240px;
|
||||
max-height: 50vh;
|
||||
background: var(--color-background-base);
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
}
|
||||
.twitch-notes {
|
||||
|
||||
.twitch-note-header {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-bottom: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
position: relative;
|
||||
cursor: move;
|
||||
}
|
||||
&_button {
|
||||
z-index: var(--z-index-default) !important;
|
||||
position: relative !important;
|
||||
background-color: var(--color-background-button-primary-default);
|
||||
color: var(--color-text-button-primary);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
border-radius: var(--border-radius-medium);
|
||||
font-size: var(--button-text-default);
|
||||
height: var(--button-size-default);
|
||||
padding: 0 var(--button-padding-x);
|
||||
|
||||
.twitch-note-title {
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
padding-left: calc((32px - var(--font-size-6)) / 2);
|
||||
}
|
||||
&__outline {
|
||||
background: transparent;
|
||||
border: 2px solid var(--color-text-button-primary);
|
||||
}
|
||||
|
||||
.twitch-note-close-button {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
aspect-ratio: 1;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.twitch-note-content {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 32px;
|
||||
background: transparent;
|
||||
color: var(--color-text-base) !important;
|
||||
font-family: var(--font-base);
|
||||
vertical-align: baseline;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
padding: calc((32px - var(--font-size-6)) / 2);
|
||||
}
|
||||
&_close-button {
|
||||
cursor: default;
|
||||
text-transform: none;
|
||||
text-indent: 0;
|
||||
text-shadow: none;
|
||||
letter-spacing: normal;
|
||||
text-rendering: auto;
|
||||
appearance: auto;
|
||||
writing-mode: horizontal-tb !important;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
font: inherit;
|
||||
border: none;
|
||||
font-size: var(--button-text-default);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
border-radius: var(--border-radius-medium);
|
||||
height: calc(var(--button-size-default) - 1rem);
|
||||
width: calc(var(--button-size-default) - 1rem);
|
||||
background-color: var(--color-background-button-text-default);
|
||||
color: var(--color-fill-button-icon);
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
|
||||
.twitch-note-save-button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
border-top: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
cursor: pointer;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
.twitch-notes_x-button {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: calc(var(--button-size-default) - 1rem);
|
||||
height: calc(var(--button-size-default) - 1rem);
|
||||
top: 0;
|
||||
fill: currentcolor;
|
||||
}
|
||||
}
|
||||
|
||||
.twitch-notes-settings-button {
|
||||
z-index: var(--z-index-default) !important;
|
||||
position: relative !important;
|
||||
background-color: var(--color-background-button-primary-default);
|
||||
color: var(--color-text-button-primary);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
border-radius: var(--border-radius-medium);
|
||||
font-size: var(--button-text-default);
|
||||
height: var(--button-size-default);
|
||||
padding: 0 var(--button-padding-x);
|
||||
&-floating-container {
|
||||
position: fixed;
|
||||
z-index: 1000000;
|
||||
width: 320px;
|
||||
height: 240px;
|
||||
background: var(--color-background-base);
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
}
|
||||
|
||||
&__outline {
|
||||
&-container {
|
||||
position: fixed;
|
||||
z-index: 1000000;
|
||||
min-width: 500px;
|
||||
max-width: 95vw;
|
||||
min-height: 240px;
|
||||
max-height: 50vh;
|
||||
background: var(--color-background-base);
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
|
||||
&-header {
|
||||
width: 100%;
|
||||
height: calc(var(--button-size-default) + 1rem);
|
||||
line-height: calc(var(--button-size-default) + 1rem);
|
||||
border-bottom: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
position: relative;
|
||||
|
||||
&-title {
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
margin-left: calc((32px - var(--font-size-6)) / 2);
|
||||
width: calc(100% - 2rem);
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
display: grid;
|
||||
grid-template-columns: 240px 1fr;
|
||||
|
||||
|
||||
&-user-list {
|
||||
border-right: 1px solid #FFFFFF19;
|
||||
height: 100%;
|
||||
min-width: 240px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
|
||||
&-item {
|
||||
padding: 1rem;
|
||||
border-bottom: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
|
||||
&-search {
|
||||
background: transparent;
|
||||
outline: none;
|
||||
color: var(--color-fill-button-icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-note-container {
|
||||
|
||||
&-note {
|
||||
min-width: 420px;
|
||||
min-height: 320px;
|
||||
display: block;
|
||||
margin: 1rem;
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
&-controls {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
|
||||
&-saved {
|
||||
color: green;
|
||||
padding-left: 1rem;
|
||||
line-height: var(--button-size-default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
width: 100%;
|
||||
border-top: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-bottom: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
position: relative;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
&--container-header-title {
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
padding-left: calc((32px - var(--font-size-6)) / 2);
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
padding-left: calc((32px - var(--font-size-6)) / 2);
|
||||
}
|
||||
|
||||
&-close-button {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
aspect-ratio: 1;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-content {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 32px;
|
||||
background: transparent;
|
||||
border: 2px solid var(--color-text-button-primary);
|
||||
color: var(--color-text-base) !important;
|
||||
font-family: var(--font-base);
|
||||
vertical-align: baseline;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
padding: calc((32px - var(--font-size-6)) / 2);
|
||||
}
|
||||
|
||||
&-save-button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 32px;
|
||||
border-top: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
cursor: pointer;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-6) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
text-transform: uppercase !important;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&-x-button {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
top: 0;
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
&-blurred-background {
|
||||
position: fixed;
|
||||
inset: 0 0 0 0;
|
||||
z-index: 2000000;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
&-center-floating-container {
|
||||
background: var(--color-background-base);
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
position: fixed;
|
||||
top: 50vh;
|
||||
left: 50vw;
|
||||
transform: translate(-50%, -50%);
|
||||
min-height: 320px;
|
||||
min-width: 300px;
|
||||
max-height: 90vh;
|
||||
max-width: 90vw;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&-link {
|
||||
display: inline-block;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
color: var(--color-text-link) !important;
|
||||
line-height: var(--line-height-heading) !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
white-space: normal !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&-grid-col-2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.twitch-notes-settings-container {
|
||||
border: 0;
|
||||
font: inherit;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
position: fixed;
|
||||
z-index: var(--z-index-balloon);
|
||||
inset: auto 0 0 auto;
|
||||
margin: 0 69px 48px 0;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-balloon {
|
||||
display: inline-block;
|
||||
max-width: 90vw;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
border-radius: 0.6rem !important;
|
||||
background-color: var(--color-background-base) !important;
|
||||
box-shadow: var(--shadow-elevation-2) !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-popover {
|
||||
white-space: normal;
|
||||
width: 32rem;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-header {
|
||||
display: flex !important;
|
||||
-webkit-box-align: center !important;
|
||||
align-items: center !important;
|
||||
position: relative !important;
|
||||
padding-left: 1rem !important;
|
||||
padding-right: 1rem !important;
|
||||
background-color: var(--color-background-base) !important;
|
||||
min-height: 4rem;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-header-left-element {
|
||||
left: 0 !important;
|
||||
margin-right: 0.5rem !important;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-header-center-element {
|
||||
-webkit-box-align: center !important;
|
||||
align-items: center !important;
|
||||
display: flex !important;
|
||||
text-align: center !important;
|
||||
-webkit-box-flex: 1 !important;
|
||||
flex-grow: 1 !important;
|
||||
-webkit-box-pack: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-header-center-element-content {
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-alt) !important;
|
||||
font-size: var(--font-size-5) !important;
|
||||
font-weight: var(--font-weight-semibold) !important;
|
||||
}
|
||||
|
||||
|
||||
.twitch-notes-settings-header-right-element {
|
||||
right: 0 !important;
|
||||
margin-left: 0.5rem !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-close-button {
|
||||
cursor: default;
|
||||
text-transform: none;
|
||||
text-indent: 0;
|
||||
text-shadow: none;
|
||||
letter-spacing: normal;
|
||||
text-rendering: auto;
|
||||
appearance: auto;
|
||||
writing-mode: horizontal-tb !important;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
font: inherit;
|
||||
border: none;
|
||||
font-size: var(--button-text-default);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
vertical-align: middle;
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
border-radius: var(--border-radius-medium);
|
||||
height: calc(var(--button-size-default) - 1rem);
|
||||
width: calc(var(--button-size-default) - 1rem);
|
||||
background-color: var(--color-background-button-text-default);
|
||||
color: var(--color-fill-button-icon);
|
||||
}
|
||||
|
||||
.twitch-notes-settings-scrollable-area {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
max-height: 478px;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-content {
|
||||
box-sizing: content-box;
|
||||
min-width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: inherit !important;
|
||||
margin: 1rem;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-option-line {
|
||||
position: relative !important;
|
||||
width: calc(100% - 2rem) !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-option-line-button {
|
||||
border-radius: var(--border-radius-medium);
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-option-line-button:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
background-color: var(--color-background-interactable-hover);
|
||||
}
|
||||
|
||||
.twitch-notes-settings-option-line-button-container {
|
||||
display: flex !important;
|
||||
-webkit-box-align: center !important;
|
||||
align-items: center !important;
|
||||
position: relative !important;
|
||||
padding: 0.5rem !important;
|
||||
}
|
||||
|
||||
.twitch-notes-settings-option-line-button-container-content {
|
||||
-webkit-box-flex: 1 !important;
|
||||
flex-grow: 1 !important;
|
||||
}
|
||||
|
||||
.twitch-note-settings-separator {
|
||||
border-top: 1px solid var(--color-border-base);
|
||||
margin-top: 1rem !important;
|
||||
margin-left: 0.5rem !important;
|
||||
margin-right: 0.5rem !important;
|
||||
padding-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.twitch-notes-x-button {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
top: 0;
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.twitch-notes-blurred-background {
|
||||
position: fixed;
|
||||
inset: 0 0 0 0;
|
||||
z-index: 2000000;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.twitch-notes-center-floating-container {
|
||||
background: var(--color-background-base);
|
||||
border: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
padding: 4rem 2rem 2rem;
|
||||
position: fixed;
|
||||
top: 50vh;
|
||||
left: 50vw;
|
||||
transform: translate(-50%, -50%);
|
||||
max-height: 90vh;
|
||||
max-width: 90vw;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.twitch-notes-user-list-user {
|
||||
padding: 1rem;
|
||||
border-bottom: var(--border-width-default) solid var(--color-border-base) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.twitch-notes-user-list-user[data-active] {
|
||||
background: #772ce833;
|
||||
}
|
||||
|
||||
@@ -1,94 +1,18 @@
|
||||
import NoteStorage from "./NoteStorage";
|
||||
import { getCloseButtonSVG } from "./HTMLTemplates";
|
||||
import openAllNoteListWindow from "./openAllNoteListWindow";
|
||||
import openClearDataWindow from "./openClearDataWindow";
|
||||
import openImportNotesWindow from "./openImprtNotesWindow";
|
||||
// import openImportNotesWindow from "./openImprtNotesWindow";
|
||||
import createChatSettingsLine from "./chatSettingsLine";
|
||||
import { HTMLBuilderBlock } from "./types";
|
||||
import {HTMLBuilderBlock} from "./types";
|
||||
import HTMLBuilder from "./HTMLBuilder";
|
||||
import TwitchCloseButton from "./HTMLElements/TwitchCloseButton";
|
||||
|
||||
export default function toggleSettingsList() {
|
||||
const settingsWindow = document.querySelector('.twitch-notes-settings-container') as HTMLElement;
|
||||
if (!settingsWindow) {
|
||||
const settingsContainer: HTMLBuilderBlock = {
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-container',
|
||||
content: [{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-balloon',
|
||||
content: [{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-popover',
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-header',
|
||||
content: [
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-header-left-element',
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-header-center-element',
|
||||
content: [{
|
||||
element: 'p',
|
||||
class: 'twitch-notes-settings-header-center-element-content',
|
||||
content: ['Twitch Notes Settings']
|
||||
}]
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-header-right-element',
|
||||
content: [{
|
||||
element: 'button',
|
||||
class: 'twitch-notes-settings-close-button',
|
||||
content: [getCloseButtonSVG()],
|
||||
mouseClickEvent: () => toggleSettingsList(),
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-scrollable-area',
|
||||
content: [{
|
||||
element: 'div',
|
||||
class: 'twitch-notes-settings-content',
|
||||
content: [
|
||||
createChatSettingsLine('Export Notes', () => {
|
||||
NoteStorage.exportNotes();
|
||||
toggleSettingsList();
|
||||
}),
|
||||
createChatSettingsLine('Import Notes',() => {
|
||||
openImportNotesWindow();
|
||||
toggleSettingsList();
|
||||
}),
|
||||
createChatSettingsLine('Clear Data',() => {
|
||||
openClearDataWindow();
|
||||
toggleSettingsList();
|
||||
}),
|
||||
{
|
||||
element: 'div',
|
||||
class: 'twitch-note-settings-separator',
|
||||
},
|
||||
createChatSettingsLine('View All Notes',() => {
|
||||
openAllNoteListWindow();
|
||||
toggleSettingsList();
|
||||
}),
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
const settingsContainerElement = new HTMLBuilder(settingsContainer);
|
||||
|
||||
document.body.appendChild(settingsContainerElement.getElement());
|
||||
return;
|
||||
} else {
|
||||
if (settingsWindow) {
|
||||
settingsWindow.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
14
src/types.ts
14
src/types.ts
@@ -1,24 +1,14 @@
|
||||
import {CustomHTMLElement} from "./CustomHTMLElement";
|
||||
|
||||
export type CustomHTMLElementConstructor = {
|
||||
class?: string | string[],
|
||||
id?: string,
|
||||
css?: Partial<CSSStyleDeclaration>,
|
||||
attributes?: {[key: string]: string},
|
||||
body?: string | HTMLElement,
|
||||
customBody?: CustomHTMLElement,
|
||||
}
|
||||
|
||||
export type HTMLBuilderBlock = {
|
||||
element: 'div' | 'span' | 'button' | 'a' | 'p' | 'strong' | 'em' | 'input' | 'img',
|
||||
id?: string,
|
||||
class?: string | string[],
|
||||
style?: Partial<CSSStyleDeclaration>,
|
||||
attributes?: {[key: string]: string},
|
||||
content?: (HTMLBuilderBlock | string)[],
|
||||
content?: (HTMLBuilderBlock | string | HTMLElement)[],
|
||||
mouseClickEvent?: Function,
|
||||
mouseMoveEvent?: Function,
|
||||
mouseDownEvent?: Function,
|
||||
mouseUpEvent?: Function,
|
||||
keyUpEvent?: Function,
|
||||
changeListener?: Function,
|
||||
}
|
||||
Reference in New Issue
Block a user