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 ClientController from '../client-controller'; import { CacheServerData, ServerMetaData } from '../data-types'; import Q from '../q-module'; import UI from '../ui'; import Actions from '../actions'; import createServerContextMenu from './context-menu-srv'; import Controller from '../controller'; export default function createServerListServer(document: Document, q: Q, ui: UI, controller: Controller, server: ClientController) { let element = q.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 () => { let serverData: ServerMetaData | CacheServerData; try { serverData = await server.grabMetadata(); if (!serverData.iconResourceId) throw new Error('server icon not identified yet'); let serverIcon = await server.fetchResource(serverData.iconResourceId); let serverIconSrc = await ElementsUtil.getImageBufferSrc(serverIcon); (q.$$$(element, 'img') as HTMLImageElement).src = serverIconSrc; } catch (e) { LOG.error('Error fetching server icon', e); (q.$$$(element, 'img') as HTMLImageElement).src = './img/error.png'; return; } element.setAttribute('meta-name', serverData.name); let contextElement = q.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 () => { Q.clearChildren(q.$$$(contextElement, '.content')); q.$$$(contextElement, '.content').appendChild(q.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 = q.create({ class: 'connection ' + connection.status, content: [ { class: 'status-circle' }, { class: 'display-name', content: connection.displayName } ] }); q.$$$(contextElement, '.content').appendChild(connectionElement); ElementsUtil.alignContextElement(contextElement, element, { left: 'right', centerY: 'centerY' }); })(); }); element.addEventListener('mouseleave', () => { if (contextElement.parentElement) { contextElement.parentElement.removeChild(contextElement); } }); })(); element.addEventListener('click', async () => { if (element.classList.contains('active')) return; ui.setActiveServer(server); // Connection information (async () => { await Actions.fetchAndUpdateConnection(ui, 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(q, ui, server); })(); // Server Members (async () => { await Actions.fetchAndUpdateMembers(q, ui, server); })(); }); element.addEventListener('contextmenu', (e) => { let contextMenu = createServerContextMenu(document, q, ui, controller, server); document.body.appendChild(contextMenu); let relativeTo = { x: e.pageX, y: e.pageY }; ElementsUtil.alignContextElement(contextMenu, relativeTo, { top: 'centerY', left: 'centerX' }); }); return element; }