cordis/client/webapp/elements/overlay-modify-channel.ts

154 lines
6.4 KiB
TypeScript
Raw Normal View History

2021-10-30 17:26:41 +00:00
import * as electronRemote from '@electron/remote';
const electronConsole = electronRemote.getGlobal('console') as Console;
import Logger from '../../../logger/logger';
2021-11-02 04:29:24 +00:00
const LOG = Logger.create(__filename, electronConsole);
2021-10-30 17:26:41 +00:00
import { Channel } from '../data-types';
import ClientController from '../client-controller.js';
import Globals from '../globals.js';
2021-10-30 17:26:41 +00:00
import BaseElements from './require/base-elements.js';
import ElementsUtil from './require/elements-util.js';
import Q from '../q-module';
export default function createModifyChannelOverlay(document: Document, q: Q, server: ClientController, channel: Channel): HTMLElement {
// See also overlay-create-channel
let element = BaseElements.createOverlay(document, { class: 'content submit-dialog modify-channel', content: [
{ class: 'preview channel-title', content: [
{ class: 'channel-icon', content: BaseElements.TEXT_CHANNEL_ICON },
{ class: 'channel-name', content: channel.name },
{ class: 'channel-flavor-divider' },
{ class: 'channel-flavor-text', content: channel.flavorText || '' }
] },
{ class: 'text-input channel-name', placeholder: 'channel-name', content: channel.name, contenteditable: 'plaintext-only' },
{ class: 'text-input channel-flavor-text', placeholder: 'Flavor Text (optional)', content: channel.flavorText || '', contenteditable: 'plaintext-only' },
{ class: 'lower', content: [
{ class: 'error' },
{ class: 'buttons', content: [
{ class: 'button submit', content: 'Save Changes' }
] }
] }
] });
let newName = channel.name;
let newFlavorText = channel.flavorText;
function updatePreview() {
newName = q.$$$(element, '.text-input.channel-name').innerText;
newFlavorText = q.$$$(element, '.text-input.channel-flavor-text').innerText;
q.$$$(element, '.channel-title .channel-name').innerText = newName;
q.$$$(element, '.channel-title .channel-flavor-text').innerText = newFlavorText;
if (newFlavorText != '') {
q.$$$(element, '.channel-title .channel-flavor-divider').style.visibility = 'visible';
} else {
q.$$$(element, '.channel-title .channel-flavor-divider').style.visibility = 'hidden';
}
}
updatePreview();
let submitting = false;
async function submit() {
if (submitting) return;
submitting = true;
q.$$$(element, '.error').innerText = '';
q.$$$(element, '.button.submit').innerText = 'Submitting...';
q.$$$(element, '.text-input.channel-name').removeAttribute('contenteditable');
q.$$$(element, '.text-input.channel-flavor-text').removeAttribute('contenteditable');
let success = false;
if (newName == channel.name && (newFlavorText || '') == (channel.flavorText || '')) {
success = true; // nothing changed
} else if (newName.length == 0) {
LOG.warn('attempted to set empty channel name');
q.$$$(element, '.error').innerText = 'Channel name cannot be empty';
q.$$$(element, '.button.submit').innerText = 'Try Again';
await ElementsUtil.shakeElement(q.$$$(element, '.button.submit'), 400);
} else if (newName.length > Globals.MAX_CHANNEL_NAME_LENGTH) {
LOG.warn('attempted to set too long channel name');
q.$$$(element, '.error').innerText = 'Channel name is too long. ' + newName.length + ' > ' + Globals.MAX_CHANNEL_NAME_LENGTH;
q.$$$(element, '.button.submit').innerText = 'Try Again';
await ElementsUtil.shakeElement(q.$$$(element, '.button.submit'), 400);
} else if (!(/^[A-Za-z0-9-]+$/.exec(newName))) {
LOG.warn('attempted to set channel name with illegal characters');
q.$$$(element, '.error').innerText = 'Please use only [A-Za-z0-9-]+ in channel name';
q.$$$(element, '.button.submit').innerText = 'Try Again';
await ElementsUtil.shakeElement(q.$$$(element, '.button.submit'), 400);
} else if (newFlavorText != null && newFlavorText.length > Globals.MAX_CHANNEL_FLAVOR_TEXT_LENGTH) {
LOG.warn('attempted to set too long flavor text');
q.$$$(element, '.error').innerText = 'Flavor text is too long. ' + newName.length + ' > ' + Globals.MAX_CHANNEL_NAME_LENGTH;
q.$$$(element, '.button.submit').innerText = 'Try Again';
await ElementsUtil.shakeElement(q.$$$(element, '.button.submit'), 400);
} else {
if (newFlavorText != null && newFlavorText.length == 0) {
newFlavorText = null;
}
try {
await server.updateChannel(channel.id, newName, newFlavorText);
success = true;
} catch (e) {
LOG.error('error updating channel', e);
q.$$$(element, '.error').innerText = 'Error updating channel';
q.$$$(element, '.button.submit').innerText = 'Try Again';
await ElementsUtil.shakeElement(q.$$$(element, '.button.submit'), 400);
}
}
if (success) {
element.removeSelf();
}
q.$$$(element, '.text-input.channel-name').setAttribute('contenteditable', 'plaintext-only');
q.$$$(element, '.text-input.channel-flavor-text').setAttribute('contenteditable', 'plaintext-only');
submitting = false;
}
let textInputs = q.$$$$(element, '.text-input');
for (let textInput of textInputs) {
textInput.addEventListener('input', () => {
updatePreview();
});
}
q.$$$(element, '.text-input.channel-name').addEventListener('keydown', async (e) => {
if (e.key == 'Backspace' || e.key == 'Escape' || e.key == 'F4') {
// these keys are good
} else if (e.key == 'Tab') {
// have to hard-code this one because otherwise, it just picks the beginning of the next input
e.preventDefault();
e.stopPropagation();
q.$$$(element, '.text-input.channel-flavor-text').focus();
ElementsUtil.setCursorToEnd(q.$$$(element, '.text-input.channel-flavor-text'));
} else if (e.key == 'Enter') {
e.preventDefault();
e.stopPropagation();
await submit();
} else if (!/^[A-Za-z0-9-]$/.exec(e.key)) {
e.preventDefault();
e.stopPropagation();
}
});
q.$$$(element, '.text-input.channel-flavor-text').addEventListener('keydown', async (e) => {
if (e.key == 'Tab' && e.shiftKey) {
// have to hard-code this one because otherwise, it just picks the beginning of the next input
e.preventDefault();
e.stopPropagation();
q.$$$(element, '.text-input.channel-name').focus();
ElementsUtil.setCursorToEnd(q.$$$(element, '.text-input.channel-name'));
} else if (e.key == 'Enter') {
e.preventDefault();
e.stopPropagation();
await submit();
}
});
q.$$$(element, '.button.submit').addEventListener('click', async () => {
await submit();
});
return element;
2021-10-30 17:26:41 +00:00
}