cordis/client/webapp/elements/message-resource.ts

88 lines
3.8 KiB
TypeScript

import * as moment from 'moment';
import ClientController from "../client-controller";
import { Message, Member } from '../data-types';
import IState from './require/elements-state';
import ElementsUtil from './require/elements-util';
import { $, $$, $$$, $$$$ } from './require/q-module';
class ShouldNeverHappenError extends Error {
constructor(...args: any[]) {
super(...args);
this.name = 'ShouldNeverHappenError';
}
}
export default function createResourceMessage(state: IState, server: ClientController, message: Message): HTMLElement {
const { document } = state;
$.setDocument(document);
if (!message.resourceId || !message.resourceName) {
throw new ShouldNeverHappenError('Message is not a resource message');
}
let memberInfo: {
roleColor: string | null,
displayName: string,
avatarResourceId: string | null
};
if (message.member instanceof Member) {
memberInfo = {
roleColor: message.member.roleColor,
displayName: message.member.displayName,
avatarResourceId: message.member.avatarResourceId
};
} else {
memberInfo = {
roleColor: null,
displayName: 'Unknown Member',
avatarResourceId: null
};
}
let nameStyle = memberInfo.roleColor ? 'color: ' + memberInfo.roleColor : '';
let element = $.create({ class: 'message', 'meta-id': message.id, 'meta-member-id': message.member.id, 'meta-server-id': server.id, content: [
{ class: 'member-avatar', content: { tag: 'img', src: './img/loading.svg', alt: memberInfo.displayName } },
{ class: 'right', content: [
{ class: 'header', content: [
{ class: 'member-name', style: nameStyle, content: memberInfo.displayName },
{ class: 'timestamp', content: moment(message.sent).calendar(ElementsUtil.calendarFormats) }
] },
{ class: 'content resource', content: [
{ tag: 'img', class: 'icon', src: './img/file-icon.png' }, // TODO: SVG based on content-type
{ class: 'text', content: [
{ class: 'filename', content: message.resourceName },
{ class: 'download-status', content: 'Click to Download' },
] }
] },
{ class: 'content text', content: ElementsUtil.parseMessageText(message.text ?? '') }
] }
] }) as HTMLElement;
$$$(element, '.resource').addEventListener('click', ElementsUtil.createDownloadListener({
server: server, resourceId: message.resourceId, resourceName: message.resourceName,
downloadStartFunc: () => {
$$$(element, '.resource .download-status').innerText = 'Downloading...';
},
downloadFailFunc: async () => {
$$$(element, '.resource .download-status').innerText = 'Error Downloading. Click to Try Again';
await ElementsUtil.shakeElement($$$(element, '.resource .download-status'), 400);
},
writeStartFunc: () => {
$$$(element, '.resource .download-status').innerText = 'Writing...';
},
writeFailFunc: async () => {
$$$(element, '.resource .download-status').innerText = 'Error Writing. Click to Try Again';
await ElementsUtil.shakeElement($$$(element, '.resource .download-status'), 400);
},
successFunc: (downloadPath) => {
$$$(element, '.resource .download-status').innerText = 'Click to Open in Explorer';
}
}));
(async () => {
($$$(element, '.member-avatar img') as HTMLImageElement).src =
await ElementsUtil.getImageBufferFromResourceFailSoftly(server, memberInfo.avatarResourceId);
})();
return element;
}