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 * as fs from 'fs/promises';
|
|
|
|
import * as path from 'path';
|
|
|
|
|
|
|
|
import * as moment from 'moment';
|
|
|
|
|
|
|
|
import * as FileType from 'file-type';
|
|
|
|
|
|
|
|
import Globals from '../globals';
|
|
|
|
import BaseElements from './require/base-elements';
|
|
|
|
import ElementsUtil from './require/elements-util';
|
|
|
|
|
2021-11-07 16:50:30 +00:00
|
|
|
import Q from '../q-module';
|
|
|
|
import UI from '../ui';
|
2021-11-22 02:47:29 +00:00
|
|
|
import GuildsManager from '../guilds-manager';
|
|
|
|
import CombinedGuild from '../guild-combined';
|
2021-10-30 17:26:41 +00:00
|
|
|
|
2021-11-22 02:47:29 +00:00
|
|
|
export interface IAddGuildData {
|
2021-11-07 16:50:30 +00:00
|
|
|
name: string,
|
|
|
|
url: string,
|
|
|
|
cert: string,
|
|
|
|
token: string,
|
|
|
|
expires: number,
|
|
|
|
iconSrc: string
|
2021-10-30 17:26:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getExampleDisplayName(): string {
|
2021-11-07 16:50:30 +00:00
|
|
|
let names = [
|
|
|
|
'gamer69',
|
|
|
|
'exdenoccp',
|
|
|
|
'TiggerEliminator',
|
|
|
|
'FreshDingus',
|
|
|
|
'Wonky Experiment',
|
|
|
|
'TheLegend27'
|
|
|
|
];
|
|
|
|
return names[Math.floor(Math.random() * names.length)];
|
2021-10-30 17:26:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getExampleAvatarPath(): string {
|
2021-11-07 16:50:30 +00:00
|
|
|
let paths = [ // these are relative to the working directory
|
|
|
|
path.join(__dirname, '../img/default-avatars/avatar-airstrip.png'),
|
|
|
|
path.join(__dirname, '../img/default-avatars/avatar-building.png'),
|
|
|
|
path.join(__dirname, '../img/default-avatars/avatar-frog.png'),
|
|
|
|
path.join(__dirname, '../img/default-avatars/avatar-sun.png')
|
|
|
|
];
|
|
|
|
return paths[Math.floor(Math.random() * paths.length)];
|
2021-10-30 17:26:41 +00:00
|
|
|
}
|
|
|
|
|
2021-11-22 02:47:29 +00:00
|
|
|
export default function createAddGuildOverlay(document: Document, q: Q, ui: UI, guildsManager: GuildsManager, addGuildData: IAddGuildData): HTMLElement {
|
|
|
|
let expired = addGuildData.expires < new Date().getTime();
|
2021-11-07 16:50:30 +00:00
|
|
|
|
|
|
|
let displayName = getExampleDisplayName();
|
|
|
|
let avatarPath = getExampleAvatarPath();
|
|
|
|
|
2021-11-22 02:47:29 +00:00
|
|
|
//LOG.debug('addguilddata:', { addGuildData });
|
2021-11-07 16:50:30 +00:00
|
|
|
|
|
|
|
let element = BaseElements.createOverlay(document, {
|
2021-11-22 02:47:29 +00:00
|
|
|
class: 'content add-guild', content: [
|
2021-11-07 16:50:30 +00:00
|
|
|
{ class: 'preview', content: [
|
2021-11-22 02:47:29 +00:00
|
|
|
{ tag: 'img', class: 'icon', src: addGuildData.iconSrc, alt: 'icon' },
|
2021-11-07 16:50:30 +00:00
|
|
|
{ content: [
|
2021-11-22 02:47:29 +00:00
|
|
|
{ class: 'name', content: addGuildData.name },
|
|
|
|
{ class: 'url', content: addGuildData.url },
|
2021-11-07 16:50:30 +00:00
|
|
|
{ class: 'expires',
|
2021-11-22 02:47:29 +00:00
|
|
|
content: (expired ? 'Invite Expired ' : 'Invite Expires ') + moment(addGuildData.expires).fromNow() }
|
2021-11-07 16:50:30 +00:00
|
|
|
] }
|
|
|
|
] },
|
|
|
|
{ class: 'divider' },
|
|
|
|
{ class: 'message-preview message', content: [
|
|
|
|
{ class: 'member-avatar', content: { tag: 'img', src: './img/loading.svg', alt: 'avatar' } },
|
|
|
|
{ class: 'right', content: [
|
|
|
|
{ class: 'header', content: [
|
|
|
|
{ class: 'member-name', content: displayName },
|
|
|
|
{ class: 'timestamp', content: moment().calendar(ElementsUtil.calendarFormats) }
|
|
|
|
] },
|
|
|
|
{ class: 'content text', content: 'Example Message' }
|
|
|
|
] }
|
|
|
|
] },
|
|
|
|
{ class: 'display-name-input', placeholder: 'Display Name',
|
|
|
|
spellcheck: 'false', contenteditable: 'plaintext-only', content: displayName },
|
|
|
|
{ class: 'avatar-input', content: [
|
|
|
|
{ tag: 'label', class: 'avatar-upload-label button', content: [
|
|
|
|
'Select Avatar',
|
|
|
|
{ class: 'avatar-upload', tag: 'input',
|
|
|
|
type: 'file', accept: '.png,.jpg,.jpeg', style: 'display: none;' },
|
|
|
|
] }
|
|
|
|
] },
|
|
|
|
{ class: 'lower', content: [
|
|
|
|
{ class: 'error' },
|
|
|
|
{ class: 'buttons', content: [
|
2021-11-22 02:47:29 +00:00
|
|
|
{ class: 'button submit', content: 'Add Guild' }
|
2021-11-07 16:50:30 +00:00
|
|
|
] }
|
|
|
|
] }
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
let avatarBuff: Buffer | null;
|
|
|
|
let defaultAvatarBuff: Buffer | null;
|
|
|
|
(async () => {
|
|
|
|
try {
|
|
|
|
defaultAvatarBuff = await fs.readFile(avatarPath); // TODO: on error
|
|
|
|
let src = await ElementsUtil.getImageBufferSrc(defaultAvatarBuff);
|
|
|
|
(q.$$$(element, '.member-avatar img') as HTMLImageElement).src = src;
|
|
|
|
avatarBuff = defaultAvatarBuff;
|
|
|
|
} catch (e) {
|
|
|
|
LOG.error('error setting default avatar', e);
|
|
|
|
(q.$$$(element, '.member-avatar img') as HTMLImageElement).src = './img/error.png';
|
|
|
|
defaultAvatarBuff = null;
|
|
|
|
avatarBuff = null;
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
|
|
q.$$$(element, '.avatar-upload').addEventListener('change', async () => {
|
|
|
|
q.$$$(element, '.error').innerText = '';
|
|
|
|
let files = (q.$$$(element, '.avatar-upload') as HTMLInputElement).files;
|
|
|
|
if (!files || files.length == 0) {
|
|
|
|
avatarBuff = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let file = files[0];
|
|
|
|
|
|
|
|
if (file.size > Globals.MAX_AVATAR_SIZE) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Image too large. Max size: ' + ElementsUtil.humanSize(Globals.MAX_AVATAR_SIZE);
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.avatar-upload-label'), 400);
|
|
|
|
(q.$$$(element, '.avatar-upload') as HTMLInputElement).value = '';
|
|
|
|
avatarBuff = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let buff = Buffer.from(await file.arrayBuffer());
|
|
|
|
|
|
|
|
let typeResult = await FileType.fromBuffer(buff);
|
|
|
|
if (!typeResult || !['image/png', 'image/jpeg', 'image/jpg'].includes(typeResult.mime)) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Invalid avatar image (png/jpg only)';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.avatar-upload-label'), 400);
|
|
|
|
avatarBuff = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
let src = await ElementsUtil.getImageBufferSrc(buff);
|
|
|
|
(q.$$$(element, '.member-avatar img') as HTMLImageElement).src = src;
|
|
|
|
avatarBuff = buff;
|
|
|
|
} catch (e) {
|
|
|
|
LOG.warn('unable to create image src from buffer', e);
|
|
|
|
q.$$$(element, '.error').innerText = 'Invalid avatar image';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.avatar-upload-label'), 400);
|
|
|
|
(q.$$$(element, '.avatar-upload') as HTMLInputElement).value = '';
|
|
|
|
avatarBuff = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
q.$$$(element, '.display-name-input').addEventListener('keydown', (e) => {
|
|
|
|
if (e.key == 'Enter') {
|
|
|
|
e.preventDefault();
|
|
|
|
if (e.shiftKey) return; // since the shift key makes newlines other places
|
|
|
|
q.$$$(element, '.button.submit').click();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
q.$$$(element, '.display-name-input').addEventListener('input', () => {
|
|
|
|
q.$$$(element, '.member-name').innerText = q.$$$(element, '.display-name-input').innerText;
|
|
|
|
});
|
|
|
|
|
|
|
|
let submitting = false;
|
|
|
|
q.$$$(element, '.button.submit').addEventListener('click', async () => {
|
|
|
|
if (submitting) return;
|
|
|
|
submitting = true;
|
|
|
|
|
|
|
|
displayName = q.$$$(element, '.display-name-input').innerText;
|
|
|
|
|
|
|
|
q.$$$(element, '.display-name-input').removeAttribute('contenteditable');
|
|
|
|
|
2021-11-22 02:47:29 +00:00
|
|
|
let newGuild: CombinedGuild | null = null;
|
|
|
|
if (addGuildData == null) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Very bad guild file';
|
2021-11-07 16:50:30 +00:00
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
2021-11-22 02:47:29 +00:00
|
|
|
} else if (addGuildData.expires < new Date().getTime()) {
|
2021-11-07 16:50:30 +00:00
|
|
|
q.$$$(element, '.error').innerText = 'Token expired';
|
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
|
|
|
} else if (displayName.length > Globals.MAX_DISPLAY_NAME_LENGTH) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Display name too long: ' + displayName.length + ' > ' + Globals.MAX_DISPLAY_NAME_LENGTH;
|
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
|
|
|
} else if (displayName.length == 0) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Display name is empty';
|
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
|
|
|
} else if (avatarBuff === null) {
|
|
|
|
q.$$$(element, '.error').innerText = 'Unable to parse avatar';
|
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
|
|
|
} else { // NOTE: Avatar size is checked above
|
|
|
|
q.$$$(element, '.submit').innerText = 'Registering...';
|
|
|
|
try {
|
2021-11-22 02:47:29 +00:00
|
|
|
newGuild = await guildsManager.addNewGuild(addGuildData, displayName, avatarBuff);
|
2021-11-07 16:50:30 +00:00
|
|
|
} catch (e) {
|
2021-11-22 02:47:29 +00:00
|
|
|
LOG.warn('error adding new guild: ' + e.message, e); // explicitly not printing stack trace here
|
2021-11-07 16:50:30 +00:00
|
|
|
q.$$$(element, '.error').innerText = e.message;
|
|
|
|
q.$$$(element, '.submit').innerText = 'Try Again';
|
|
|
|
await ElementsUtil.shakeElement(q.$$$(element, '.submit'), 400);
|
2021-11-22 02:47:29 +00:00
|
|
|
newGuild = null;
|
2021-11-07 16:50:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-22 02:47:29 +00:00
|
|
|
if (newGuild !== null) {
|
|
|
|
let guildElement = await ui.addGuild(guildsManager, newGuild);
|
|
|
|
element.removeSelf(); // close the overlay since we got a new guild
|
|
|
|
guildElement.click(); // click on the new guild
|
2021-11-07 16:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
q.$$$(element, '.display-name-input').setAttribute('contenteditable', 'plaintext-only');
|
|
|
|
q.$$$(element, '.display-name-input').focus();
|
|
|
|
|
|
|
|
submitting = false;
|
|
|
|
});
|
|
|
|
|
|
|
|
return element;
|
2021-10-30 17:26:41 +00:00
|
|
|
}
|