148 lines
4.0 KiB
TypeScript
148 lines
4.0 KiB
TypeScript
|
import { hexToString, storeHex } from '../common/convert';
|
||
|
import { IcyNetUser } from '../server/types/user';
|
||
|
import { $ } from './utils/dom';
|
||
|
|
||
|
export class Picker {
|
||
|
private _fn?: (color: number) => void;
|
||
|
private _color: number = 0x000000;
|
||
|
private _colorHistory: number[] = [];
|
||
|
|
||
|
private _wrapper = $('<div class="controls__wrapper">');
|
||
|
private _content = $('<div class="controls">');
|
||
|
private _colorsEl = $('<div class="controls__colors">');
|
||
|
private _colorHistoryEl = $('<div class="controls__colors-history">');
|
||
|
private _user = $('<a href="/login">');
|
||
|
|
||
|
private _colorInput = $('<input type="color">') as HTMLInputElement;
|
||
|
private _placebtn = $('<button class="btn btn-primary btn-place">');
|
||
|
private _palettebtn = $('<button class="btn btn-palette">');
|
||
|
private _clearbtn = $('<button class="btn btn-palette">');
|
||
|
|
||
|
get element() {
|
||
|
return this._wrapper;
|
||
|
}
|
||
|
|
||
|
public place() {
|
||
|
if (this._fn) {
|
||
|
this._storeColor(this._color);
|
||
|
this._fn(this._color);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public pickPalette(index: number) {
|
||
|
if (this._colorHistory && this._colorHistory.length) {
|
||
|
this._setColor(this._colorHistory[index]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public initialize() {
|
||
|
this._placebtn.innerText = 'Place';
|
||
|
this._palettebtn.innerText = '>>';
|
||
|
this._clearbtn.innerText = 'Clear';
|
||
|
this._user.innerText = 'Log in';
|
||
|
this._wrapper.append(this._content);
|
||
|
this._content.append(this._colorsEl);
|
||
|
this._colorsEl.append(this._colorInput);
|
||
|
this._colorsEl.append(this._palettebtn);
|
||
|
this._colorsEl.append(this._colorHistoryEl);
|
||
|
this._colorsEl.append(this._clearbtn);
|
||
|
this._content.append(this._placebtn);
|
||
|
this._content.append(this._user);
|
||
|
|
||
|
this._placebtn.setAttribute('disabled', 'true');
|
||
|
this._placebtn.addEventListener('click', (ev) => {
|
||
|
ev.preventDefault();
|
||
|
this.place();
|
||
|
});
|
||
|
|
||
|
this._colorInput.addEventListener('input', (ev) => {
|
||
|
this._color = storeHex(this._colorInput.value);
|
||
|
});
|
||
|
|
||
|
this._palettebtn.addEventListener('click', () => {
|
||
|
this._storeColor(this._color);
|
||
|
});
|
||
|
|
||
|
this._clearbtn.addEventListener('click', () => {
|
||
|
this._colorHistory.length = 0;
|
||
|
this._colorHistoryEl.innerHTML = '';
|
||
|
this._preserveHistory();
|
||
|
});
|
||
|
|
||
|
this._colorHistory = this._getHistory();
|
||
|
if (this._colorHistory.length) {
|
||
|
this._setColor(this._colorHistory[0]);
|
||
|
this._drawColorList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public setLoggedIn(user: IcyNetUser): void {
|
||
|
if (!user) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._placebtn.removeAttribute('disabled');
|
||
|
this._user.innerText = `Logged in as ${user.username}, click here to log out`;
|
||
|
this._user.setAttribute('href', '/logout');
|
||
|
}
|
||
|
|
||
|
public registerOnPlace(fn: (color: number) => void): void {
|
||
|
this._fn = fn;
|
||
|
}
|
||
|
|
||
|
private _setColor(color: number): void {
|
||
|
this._color = color;
|
||
|
this._colorInput.value = hexToString(color);
|
||
|
}
|
||
|
|
||
|
private _drawColorList(): void {
|
||
|
this._colorHistoryEl.innerHTML = '';
|
||
|
this._colorHistory.map((item) => {
|
||
|
const str = hexToString(item);
|
||
|
const colEl = $(
|
||
|
`<div class="btn controls__color" style="background-color: ${str};">`,
|
||
|
);
|
||
|
colEl.addEventListener('click', () => {
|
||
|
this._colorInput.value = str;
|
||
|
this._color = item;
|
||
|
});
|
||
|
this._colorHistoryEl.append(colEl);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private _storeColor(color: number): void {
|
||
|
if (this._colorHistory.includes(color)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._colorHistory.unshift(color);
|
||
|
if (this._colorHistory.length > 10) {
|
||
|
this._colorHistory.length = 10;
|
||
|
}
|
||
|
|
||
|
this._drawColorList();
|
||
|
this._preserveHistory();
|
||
|
}
|
||
|
|
||
|
private _preserveHistory(): void {
|
||
|
if (window.localStorage) {
|
||
|
if (!this._colorHistory.length) {
|
||
|
window.localStorage.removeItem('colors');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
window.localStorage.setItem('colors', this._colorHistory.join('|'));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private _getHistory(): number[] {
|
||
|
if (window.localStorage) {
|
||
|
const list = window.localStorage.getItem('colors')?.split('|');
|
||
|
if (list?.length) {
|
||
|
return list.map((item) => Number(item));
|
||
|
}
|
||
|
}
|
||
|
return [];
|
||
|
}
|
||
|
}
|