misuzu/assets/misuzu.js/messages/actbtn.js
2024-01-30 23:47:02 +00:00

90 lines
2.4 KiB
JavaScript

#include watcher.js
const MszMessagesActionButton = function(button, stateless) {
if(!(button instanceof Element))
throw 'button must be an element';
const stateful = !stateless;
const pub = {};
const icon = button.querySelector('.js-messages-button-icon i');
const label = button.querySelector('.js-messages-button-label');
const update = () => {
if(stateful) {
icon.className = button.dataset[`${button.dataset.state}Ico`];
label.textContent = button.dataset[`${button.dataset.state}Str`];
}
};
pub.update = update;
const stateWatcher = new MszWatcher;
const getState = () => button.dataset.state !== 'inactive';
const setState = state => {
button.dataset.state = state ? 'active' : 'inactive';
update();
stateWatcher.call(getState());
};
if(stateful) {
pub.getState = getState;
pub.setState = setState;
pub.watchState = handler => { stateWatcher.watch(handler, getState()); };
pub.unwatchState = handler => { stateWatcher.unwatch(handler); };
}
let clickAction;
const click = async () => {
if(clickAction !== undefined) {
if(stateful) {
const result = await clickAction(getState());
if(typeof result === 'boolean')
setState(result);
} else
await clickAction();
}
};
pub.click = click;
button.addEventListener('click', () => click());
update();
pub.setAction = action => {
if(typeof action !== 'function')
throw 'action must be a function';
clickAction = action;
};
let preventEnable = false;
pub.getEnabled = () => !button.disabled;
pub.setEnabled = state => {
if(!preventEnable)
button.disabled = !state;
};
pub.disableWith = async callback => {
if(typeof callback !== 'function')
throw 'callback must be a function';
if(preventEnable)
throw 'preventEnable is true';
preventEnable = true;
const wasDisabled = button.disabled;
button.disabled = true;
try {
return await callback();
} finally {
button.disabled = wasDisabled;
preventEnable = false;
}
};
pub.setHidden = state => {
button.hidden = state;
};
return pub;
};