import * as electronRemote from '@electron/remote'; const electronConsole = electronRemote.getGlobal('console') as Console; import Logger from '../../../logger/logger'; const LOG = Logger.create(__filename, electronConsole); import BaseElements from './require/base-elements'; import ElementsUtil from './require/elements-util'; import Elements from '../elements'; import { $, $$, $$$, $$$$ } from './require/q-module'; import IState from './require/elements-state'; import ClientController from '../client-controller'; export default function createServerListServer(state: IState, server: ClientController) { const { document, ui, actions } = state; $.setDocument(document); let element = $.create({ class: 'server', 'meta-id': server.id, 'meta-name': server.id, content: [ { class: 'pill' }, { tag: 'img', src: './img/loading.svg', alt: 'server' }, // src is set later by script.js ] }) as HTMLElement; // Hover over for name + connection info (async () => { try { let serverData = await server.grabMetadata(); let serverIcon = await server.fetchResource(serverData.icon_resource_id); let serverIconSrc = await ElementsUtil.getImageBufferSrc(serverIcon); ($$$(element, 'img') as HTMLImageElement).src = serverIconSrc; element.setAttribute('meta-name', serverData.name); let contextElement = $.create({ class: 'context', content: { class: 'info', content: [ BaseElements.TAB_LEFT, { class: 'content server' } // populated later ] } }) as HTMLElement; // TODO: future: update the status in real-time with the update-member event element.addEventListener('mouseenter', async () => { $.clearChildren($$$(contextElement, '.content')); $$$(contextElement, '.content').appendChild($.create({ class: 'name', content: element.getAttribute('meta-name') })); document.body.appendChild(contextElement); ElementsUtil.alignContextElement(contextElement, element, { left: 'right', centerY: 'centerY' }); (async () => { let connection = await server.fetchConnectionInfo(); let connectionElement = $.create({ class: 'connection ' + connection.status, content: [ { class: 'status-circle' }, { class: 'display-name', content: connection.displayName } ] }); $$$(contextElement, '.content').appendChild(connectionElement); ElementsUtil.alignContextElement(contextElement, element, { left: 'right', centerY: 'centerY' }); })(); }); element.addEventListener('mouseleave', () => { if (contextElement.parentElement) { contextElement.parentElement.removeChild(contextElement); } }); } catch (e) { LOG.error('Error fetching server icon', e); ($$$(element, 'img') as HTMLImageElement).src = './img/error.png'; } })(); element.addEventListener('click', async () => { if (element.classList.contains('active')) return; ui.setActiveServer(server); // Connection information (async () => { await actions.fetchAndUpdateConnection(server); })(); // Server Channel Name (async () => { // Explicitly not using a withPotentialError to make this simpler try { let serverData = await server.grabMetadata(); ui.updateServerName(server, serverData.name); } catch (e) { LOG.error('Error fetching server name', e); ui.updateServerName(server, 'ERROR'); } })(); // Server Channel List (async () => { await actions.fetchAndUpdateChannels(server); })(); // Server Members (async () => { await actions.fetchAndUpdateMembers(server); })(); }); element.addEventListener('contextmenu', (e) => { let contextMenu = Elements.createServerContextMenu(server); document.body.appendChild(contextMenu); let relativeTo = { x: e.pageX, y: e.pageY }; ElementsUtil.alignContextElement(contextMenu, relativeTo, { top: 'centerY', left: 'centerX' }); }); return element; }