discord-message-transcript 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/core/clientManager.d.ts +3 -0
- package/dist/core/clientManager.js +9 -0
- package/dist/core/componentHelpers.d.ts +3 -0
- package/dist/core/componentHelpers.js +175 -0
- package/dist/core/componentToJson.d.ts +3 -0
- package/dist/core/componentToJson.js +174 -0
- package/dist/core/error.d.ts +3 -0
- package/dist/core/error.js +7 -0
- package/dist/core/fetchMessages.d.ts +7 -0
- package/dist/core/fetchMessages.js +169 -0
- package/dist/core/getMentions.d.ts +3 -0
- package/dist/core/getMentions.js +99 -0
- package/dist/core/imageToBase64.d.ts +1 -0
- package/dist/core/imageToBase64.js +30 -0
- package/dist/core/mappers.d.ts +8 -0
- package/dist/core/mappers.js +101 -0
- package/dist/core/markdown.d.ts +2 -0
- package/dist/core/markdown.js +175 -0
- package/dist/core/output.d.ts +4 -0
- package/dist/core/output.js +28 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +120 -0
- package/dist/renderers/html/clientRenderer.d.ts +0 -0
- package/dist/renderers/html/clientRenderer.js +73 -0
- package/dist/renderers/html/css.d.ts +11 -0
- package/dist/renderers/html/css.js +663 -0
- package/dist/renderers/html/html copy.d.ts +19 -0
- package/dist/renderers/html/html copy.js +371 -0
- package/dist/renderers/html/html-backup.d.ts +19 -0
- package/dist/renderers/html/html-backup.js +371 -0
- package/dist/renderers/html/html.d.ts +19 -0
- package/dist/renderers/html/html.js +415 -0
- package/dist/renderers/html/html2.d.ts +8 -0
- package/dist/renderers/html/html2.js +233 -0
- package/dist/renderers/html/js.d.ts +4 -0
- package/dist/renderers/html/js.js +174 -0
- package/dist/renderers/json/json.d.ts +16 -0
- package/dist/renderers/json/json.js +55 -0
- package/dist/types/types copy.d.ts +284 -0
- package/dist/types/types copy.js +35 -0
- package/dist/types/types.d.ts +137 -0
- package/dist/types/types.js +7 -0
- package/package.json +45 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { CustomError } from "../../core/error";
|
|
2
|
+
import { markdownToHTML } from "../../core/markdown";
|
|
3
|
+
import { JsonButtonStyle, JsonComponentType } from "../../types/types";
|
|
4
|
+
import { ACTIONROW_CSS, ATTACHMENT_CSS, BUTTON_CSS, COMPONENTS_CSS, COMPONENTSV2_CSS, DEFAULT_CSS, EMBED_CSS, MESSAGE_CSS } from "./css";
|
|
5
|
+
const COUNT_UNIT = ["KB", "MB", "GB", "TB"];
|
|
6
|
+
const BUTTON_COLOR = ["black", "#5865f2", "gray", "lime", "red", "black", "#5865f2"];
|
|
7
|
+
export class Html {
|
|
8
|
+
guild;
|
|
9
|
+
channel;
|
|
10
|
+
messages;
|
|
11
|
+
options;
|
|
12
|
+
dateFormat;
|
|
13
|
+
constructor(data, options) {
|
|
14
|
+
this.guild = data.guild;
|
|
15
|
+
this.channel = data.channel;
|
|
16
|
+
this.messages = data.messages;
|
|
17
|
+
this.options = options;
|
|
18
|
+
try {
|
|
19
|
+
this.dateFormat = new Intl.DateTimeFormat(options.localDate, {
|
|
20
|
+
timeZone: options.timeZone,
|
|
21
|
+
day: '2-digit',
|
|
22
|
+
month: '2-digit',
|
|
23
|
+
year: 'numeric',
|
|
24
|
+
hour: '2-digit',
|
|
25
|
+
minute: '2-digit',
|
|
26
|
+
second: '2-digit'
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new CustomError("[discord-message-transcript] Invalid LocalDate and/or TimeZone.");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
headerBuilder() {
|
|
34
|
+
return `
|
|
35
|
+
<div style="display: flex; gap: 1.5rem; align-items: center;">
|
|
36
|
+
${this.channel.img ? `<img src="${this.channel.img}" style="width: 7rem; height: 7rem; border-radius: 50%;">` : ""}
|
|
37
|
+
<div style="display: flex; flex-direction: column; justify-content: center; gap: 1.25rem;">
|
|
38
|
+
${this.guild ? `<div id="guild" class="line">
|
|
39
|
+
<h4>Guild: </h4>
|
|
40
|
+
<h4 style="font-weight: normal;">${this.guild.name}</h4>
|
|
41
|
+
</div>` : ""}
|
|
42
|
+
${this.channel.parent ? `<div id="category" class="line">
|
|
43
|
+
<h4>Category: </h4>
|
|
44
|
+
<h4 style="font-weight: normal;">${this.channel.parent.name}</h4>
|
|
45
|
+
</div>` : ""}
|
|
46
|
+
<div id="channel" class="line">
|
|
47
|
+
<h4>Channel: </h4>
|
|
48
|
+
<h4 style="font-weight: normal;">${this.channel.name}</h4>
|
|
49
|
+
</div>
|
|
50
|
+
${this.channel.topic ? `<div id="topic" class="line">
|
|
51
|
+
<h4>Topic: </h4>
|
|
52
|
+
<h4 style="font-weight: normal;">${this.channel.topic}</h4>
|
|
53
|
+
</div>` : ""}
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
messagesBuilder() {
|
|
59
|
+
return this.messages.map(message => {
|
|
60
|
+
const date = new Date(message.createdTimestamp);
|
|
61
|
+
message.content = markdownToHTML(message.content, message.mentions, this.dateFormat);
|
|
62
|
+
message.attachments;
|
|
63
|
+
return `
|
|
64
|
+
<div class="messageDiv" id="${message.id}>
|
|
65
|
+
${message.references && message.references.messageId ?
|
|
66
|
+
`<div class="messageReply" data-id="${message.references.messageId}">
|
|
67
|
+
<svg class="messageReplySvg"><use href="#reply-icon"></use></svg>
|
|
68
|
+
<img class="messageReplyImg">
|
|
69
|
+
${message.author.bot ? `<p class="badgeReply">APP</p>` : ""}
|
|
70
|
+
<div class="messageReplyText"></div>
|
|
71
|
+
</div>` : ""}
|
|
72
|
+
<div class="messageBotton">
|
|
73
|
+
<img src="${message.author.avatarURL}" class="messageImg">
|
|
74
|
+
<div class="messageDivRight">
|
|
75
|
+
<div class="messageUser">
|
|
76
|
+
<h3 class="messageUsername" style="color: ${message.member?.displayHexColor ?? "#dbdee1"}">${message.member?.displayName ?? message.author.displayName}</h3>
|
|
77
|
+
${message.author.bot ? `<p class="badge">APP</p>` : ""}
|
|
78
|
+
${message.author.system ? `<p class="badge">SYSTEM</p>` : ""}
|
|
79
|
+
${message.author.guildTag ? `<p class="badgeTag">${message.author.guildTag}</p>` : ""}
|
|
80
|
+
<p class="messageTimeStamp">${this.dateFormat.format(date)}</p>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="messageContent"">${message.content}</div>
|
|
83
|
+
${message.embeds.length > 0 ? this.embedBuilder(message, message.embeds) : ""}
|
|
84
|
+
${message.attachments.length > 0 ? this.attachmentBuilder(message.attachments) : ""}
|
|
85
|
+
${message.components.length > 0 ? this.componentBuilder(message, message.components) : ""}
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
`;
|
|
90
|
+
}).join("");
|
|
91
|
+
}
|
|
92
|
+
toHTML() {
|
|
93
|
+
return `
|
|
94
|
+
<!DOCTYPE html>
|
|
95
|
+
<html lang="pt-BR"></html>
|
|
96
|
+
<head>
|
|
97
|
+
<meta charset="UTF-8" />
|
|
98
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
99
|
+
<title>${this.options.fileName}</title>
|
|
100
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/styles/atom-one-dark.min.css">
|
|
101
|
+
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/highlight.min.js"></script>
|
|
102
|
+
<style>
|
|
103
|
+
${DEFAULT_CSS}
|
|
104
|
+
${MESSAGE_CSS}
|
|
105
|
+
${this.options.includeEmbeds ? EMBED_CSS : ""}
|
|
106
|
+
${this.options.includeButtons || this.options.includeComponents ? ACTIONROW_CSS : ""}
|
|
107
|
+
${this.options.includeAttachments || this.options.includeV2Components ? ATTACHMENT_CSS : ""}
|
|
108
|
+
${this.options.includeButtons || this.options.includeV2Components ? BUTTON_CSS : ""}
|
|
109
|
+
${this.options.includeComponents ? COMPONENTS_CSS : ""}
|
|
110
|
+
${this.options.includeV2Components ? COMPONENTSV2_CSS : ""}
|
|
111
|
+
</style>
|
|
112
|
+
</head>
|
|
113
|
+
<body>
|
|
114
|
+
${this.svgBuilder()}
|
|
115
|
+
<header>
|
|
116
|
+
${this.headerBuilder()}
|
|
117
|
+
</header>
|
|
118
|
+
<main style="display: flex; flex-direction: column; gap: 1.75rem; padding: 2.25rem;">
|
|
119
|
+
${this.messagesBuilder()}
|
|
120
|
+
</main>
|
|
121
|
+
<footer>
|
|
122
|
+
<br>
|
|
123
|
+
<h2>Transcript generated by <a href="https://github.com/HenriqueMairesse/discord-channel-transcript">discord-channel-transcript</a></h2>
|
|
124
|
+
</footer>
|
|
125
|
+
<script>
|
|
126
|
+
document.addEventListener('click', function (event) {
|
|
127
|
+
const spoiler = event.target.closest('.spoilerMsg, .spoilerAttachment');
|
|
128
|
+
if (spoiler && !spoiler.classList.contains('revealed')) {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
event.stopPropagation();
|
|
131
|
+
spoiler.classList.add('revealed');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const selectorInput = event.target.closest('.selectorInput');
|
|
135
|
+
document.querySelectorAll('.selector').forEach(selector => {
|
|
136
|
+
if (!selector.contains(event.target)) {
|
|
137
|
+
selector.classList.remove('active');
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (selectorInput) {
|
|
142
|
+
const selector = selectorInput.closest('.selector');
|
|
143
|
+
if (selector) {
|
|
144
|
+
selector.classList.toggle('active');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
document.addEventListener('DOMContentLoaded', function (event) {
|
|
149
|
+
hljs.highlightAll();
|
|
150
|
+
|
|
151
|
+
});
|
|
152
|
+
</script>
|
|
153
|
+
</body>
|
|
154
|
+
</html>
|
|
155
|
+
`;
|
|
156
|
+
}
|
|
157
|
+
embedBuilder(message, embeds) {
|
|
158
|
+
return embeds.map(embed => {
|
|
159
|
+
const embedAuthor = embed.author ? (embed.author.url ? `<a class="embedHeaderRightAuthorName" href="${embed.author.url}" target="_blank">${embed.author.name}</a>` : `<p class="embedHeaderRightAuthorName">${embed.author.name}</p>`) : "";
|
|
160
|
+
const embedTitle = embed.title ? (embed.url ? `<a class="embedHeaderRightTitle" href="${embed.url}" target="_blank">${embed.title}</a>` : `<p class="embedHeaderRightTitle">${embed.title}</p>`) : "";
|
|
161
|
+
return embed.type != "poll_result" ? `
|
|
162
|
+
<div class="embed" style="${embed.hexColor ? `border-left-color: ${embed.hexColor}` : ''}">
|
|
163
|
+
${embed.author || embed.title || embed.thumbnail ? `
|
|
164
|
+
<div class="embedHeader">
|
|
165
|
+
<div class="embedHeaderRight">
|
|
166
|
+
${embed.author ? `
|
|
167
|
+
<div class="embedHeaderRightAuthor">
|
|
168
|
+
${embed.author.iconURL ? `<img class="embedHeaderRightAuthorImg" src="${embed.author.iconURL}">` : ""}
|
|
169
|
+
${embedAuthor}
|
|
170
|
+
</div>` : ""}
|
|
171
|
+
${embedTitle}
|
|
172
|
+
</div>
|
|
173
|
+
${embed.thumbnail ? `<img class="embedHeaderThumbnail" src="${embed.thumbnail.url}">` : ""}
|
|
174
|
+
</div>` : ""}
|
|
175
|
+
${embed.description ? `<div class="embedDescription">${markdownToHTML(embed.description, message.mentions, this.dateFormat)}</div>` : ""}
|
|
176
|
+
${embed.fields && embed.fields.length > 0 ? `
|
|
177
|
+
<div class="embedFields">
|
|
178
|
+
${embed.fields.map(field => `
|
|
179
|
+
<div class="embedFieldsField" style="${field.inline ? 'display: inline-block;' : ''}">
|
|
180
|
+
<p class="embedFieldsFieldTitle">${field.name}</p>
|
|
181
|
+
<p class="embedFieldsFieldValue">${markdownToHTML(field.value, message.mentions, this.dateFormat)}</p>
|
|
182
|
+
</div>`).join("")}
|
|
183
|
+
</div>` : ""}
|
|
184
|
+
${embed.image ? `
|
|
185
|
+
<div class="embedImage">
|
|
186
|
+
<img src="${embed.image.url}">
|
|
187
|
+
</div>` : ""}
|
|
188
|
+
${embed.footer || embed.timestamp ? `
|
|
189
|
+
<div class="embedFooter">
|
|
190
|
+
${embed.footer?.iconURL ? `<img class="embedFooterImg" src="${embed.footer.iconURL}">` : ""}
|
|
191
|
+
${embed.footer?.text || embed.timestamp ? `<p class="embedFooterText">${embed.footer?.text ?? ''}${embed.footer?.text && embed.timestamp ? ' | ' : ''}${embed.timestamp ? this.dateFormat.format(new Date(embed.timestamp)) : ''}</p>` : ""}
|
|
192
|
+
</div>` : ""}
|
|
193
|
+
</div>
|
|
194
|
+
` : ``;
|
|
195
|
+
}).join("");
|
|
196
|
+
}
|
|
197
|
+
attachmentBuilder(attachments) {
|
|
198
|
+
return attachments.map(attachment => {
|
|
199
|
+
let html = "";
|
|
200
|
+
if (attachment.contentType?.startsWith('image/')) {
|
|
201
|
+
html = `<img class="attachmentImage" src="${attachment.url}">`;
|
|
202
|
+
}
|
|
203
|
+
else if (attachment.contentType?.startsWith('video/')) {
|
|
204
|
+
html = `<video class="attachmentVideo" controls src="${attachment.url}"></video>`;
|
|
205
|
+
}
|
|
206
|
+
else if (attachment.contentType?.startsWith('audio/')) {
|
|
207
|
+
html = `<audio class="attachmentAudio" controls src="${attachment.url}"></audio>`;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
let fileSize = attachment.size / 1024;
|
|
211
|
+
let count = 0;
|
|
212
|
+
while (fileSize > 512 && count < COUNT_UNIT.length - 1) {
|
|
213
|
+
fileSize = fileSize / 1024;
|
|
214
|
+
count++;
|
|
215
|
+
}
|
|
216
|
+
html = `
|
|
217
|
+
<div class="attachmentFile">
|
|
218
|
+
<div class="attachmentFileInfo">
|
|
219
|
+
<p class="attachmentFileName">${attachment.name ?? 'attachment'}</p>
|
|
220
|
+
<div class="attachmentFileSize">${fileSize.toFixed(2)} ${COUNT_UNIT[count]}</div>
|
|
221
|
+
</div>
|
|
222
|
+
<a class="attachmentDownload" href="${attachment.url}" target="_blank">
|
|
223
|
+
<svg class="attachmentDownloadIcon"><use href="#download-icon"></use></svg>
|
|
224
|
+
</a>
|
|
225
|
+
</div>
|
|
226
|
+
`;
|
|
227
|
+
}
|
|
228
|
+
return this.spoilerAttachmentBuilder(attachment.spoiler, html);
|
|
229
|
+
}).join("");
|
|
230
|
+
}
|
|
231
|
+
componentBuilder(message, components) {
|
|
232
|
+
return components.map(component => {
|
|
233
|
+
switch (component.type) {
|
|
234
|
+
case JsonComponentType.ActionRow: {
|
|
235
|
+
if (!component.components[0])
|
|
236
|
+
return "";
|
|
237
|
+
return `
|
|
238
|
+
<div class="actionRow">
|
|
239
|
+
${component.components[0].type == JsonComponentType.Button ? component.components.map(button => {
|
|
240
|
+
return button.type == JsonComponentType.Button ? this.buttonBuilder(button) : "";
|
|
241
|
+
}).join("") : this.selectorBuilder(component.components[0])}
|
|
242
|
+
</div>
|
|
243
|
+
`;
|
|
244
|
+
}
|
|
245
|
+
case JsonComponentType.Container: {
|
|
246
|
+
const html = `
|
|
247
|
+
<div class="container" style="${component.hexAccentColor ? `border-left-color: ${component.hexAccentColor}` : ''}">
|
|
248
|
+
${this.componentBuilder(message, component.components)}
|
|
249
|
+
</div>
|
|
250
|
+
`;
|
|
251
|
+
return this.spoilerAttachmentBuilder(component.spoiler, html);
|
|
252
|
+
}
|
|
253
|
+
case JsonComponentType.File: {
|
|
254
|
+
let fileSize = (component.size ?? 0) / 1024;
|
|
255
|
+
let count = 0;
|
|
256
|
+
while (fileSize > 512 && count < COUNT_UNIT.length - 1) {
|
|
257
|
+
fileSize = fileSize / 1024;
|
|
258
|
+
count++;
|
|
259
|
+
}
|
|
260
|
+
const html = `
|
|
261
|
+
<div class="attachmentFile">
|
|
262
|
+
<div class="attachmentFileInfo">
|
|
263
|
+
<p class="attachmentFileName">${component.fileName ?? 'file'}</p>
|
|
264
|
+
<div class="attachmentFileSize">${fileSize.toFixed(2)} ${COUNT_UNIT[count]}</div>
|
|
265
|
+
</div>
|
|
266
|
+
<a class="attachmentDownload" href="${component.url ?? ''}" target="_blank">
|
|
267
|
+
<svg class="attachmentDownloadIcon"><use href="#download-icon"></use></svg>
|
|
268
|
+
</a>
|
|
269
|
+
</div>
|
|
270
|
+
`;
|
|
271
|
+
return this.spoilerAttachmentBuilder(component.spoiler, html);
|
|
272
|
+
}
|
|
273
|
+
case JsonComponentType.MediaGallery: {
|
|
274
|
+
return `
|
|
275
|
+
<div class="mediaGallery">
|
|
276
|
+
${component.items.map(image => {
|
|
277
|
+
return `
|
|
278
|
+
<div class="mediaGalleryItem">
|
|
279
|
+
${this.spoilerAttachmentBuilder(image.spoiler, `<img class="mediaGalleryImg" src="${image.media.url}">`)}
|
|
280
|
+
</div>
|
|
281
|
+
`;
|
|
282
|
+
}).join("")}
|
|
283
|
+
</div>
|
|
284
|
+
`;
|
|
285
|
+
}
|
|
286
|
+
case JsonComponentType.Section: {
|
|
287
|
+
return `
|
|
288
|
+
<div class="section">
|
|
289
|
+
<div class="sectionLeft">
|
|
290
|
+
${this.componentBuilder(message, component.components)}
|
|
291
|
+
</div>
|
|
292
|
+
<div class="sectionRight">
|
|
293
|
+
${component.accessory.type == JsonComponentType.Button ? this.buttonBuilder(component.accessory)
|
|
294
|
+
: component.accessory.type == JsonComponentType.Thumbnail ? this.spoilerAttachmentBuilder(component.accessory.spoiler, `
|
|
295
|
+
<img class="sectionThumbnail" src="${component.accessory.media.url}">
|
|
296
|
+
`) : ""}
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
`;
|
|
300
|
+
}
|
|
301
|
+
case JsonComponentType.Separator: {
|
|
302
|
+
return `<hr>`;
|
|
303
|
+
}
|
|
304
|
+
case JsonComponentType.TextDisplay: {
|
|
305
|
+
return markdownToHTML(component.content, message.mentions, this.dateFormat);
|
|
306
|
+
}
|
|
307
|
+
default:
|
|
308
|
+
return ``;
|
|
309
|
+
}
|
|
310
|
+
}).join("");
|
|
311
|
+
}
|
|
312
|
+
buttonBuilder(button) {
|
|
313
|
+
return `
|
|
314
|
+
<div class="button" style="background-color: ${BUTTON_COLOR[button.style]}">
|
|
315
|
+
${button.style == JsonButtonStyle.Link ? `
|
|
316
|
+
<a class="buttonLink" href="${button.url}" target="_blank">
|
|
317
|
+
${button.emoji ? `<p class="buttonEmoji">${button.emoji}</p>` : ""}
|
|
318
|
+
${button.label ? `<p class="buttonLabel">${button.label}</p>` : ""}
|
|
319
|
+
<svg class="buttonLinkIcon"><use href="#link-icon"></use></svg>
|
|
320
|
+
</a>` : `
|
|
321
|
+
${button.emoji ? `<p class="buttonEmoji">${button.emoji}</p>` : ""}
|
|
322
|
+
${button.label ? `<p class="buttonLabel">${button.label}</p>` : ""}
|
|
323
|
+
`}
|
|
324
|
+
</div>
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
selectorBuilder(selector) {
|
|
328
|
+
return `
|
|
329
|
+
<div class="selector">
|
|
330
|
+
<div class="selectorInput">
|
|
331
|
+
<p class="selectorInputText">${selector.placeholder}</p>
|
|
332
|
+
</div>
|
|
333
|
+
<div class="selectorOptionMenu">
|
|
334
|
+
${selector.type == JsonComponentType.StringSelect ? selector.options.map(option => {
|
|
335
|
+
return `
|
|
336
|
+
<div class="selectorOption">
|
|
337
|
+
${option.emoji ? `<p class="selectorOptionEmoji">${option.emoji}</p>` : ""}
|
|
338
|
+
<div class="selectorOptionRight">
|
|
339
|
+
<p class="selectorOptionTitle">${option.label}</p>
|
|
340
|
+
${option.description ? `<p class="selectorOptionDesc">${option.description}</p>` : ""}
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
`;
|
|
344
|
+
}).join("") : ""}
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
`;
|
|
348
|
+
}
|
|
349
|
+
spoilerAttachmentBuilder(spoiler, html) {
|
|
350
|
+
return spoiler ? `<div class="spoilerAttachment"><div class="spoilerAttachmentOverlay">SPOILER</div><div class="spoilerAttachmentContent">${html}</div></div>` : html;
|
|
351
|
+
}
|
|
352
|
+
svgBuilder() {
|
|
353
|
+
return `
|
|
354
|
+
<svg style="display: none;">
|
|
355
|
+
<defs>
|
|
356
|
+
<symbol id="reply-icon" viewBox="0 0 16 16" fill="none">
|
|
357
|
+
<g transform="rotate(90 8 8)">
|
|
358
|
+
<path d="M6 2V9C6 11.5 8.5 14 11 14H14" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
|
359
|
+
</g>
|
|
360
|
+
</symbol>
|
|
361
|
+
${this.options.includeAttachments ? `<symbol id="download-icon" viewBox="0 -960 960 960">
|
|
362
|
+
<path d="m720-120 160-160-56-56-64 64v-167h-80v167l-64-64-56 56 160 160ZM560 0v-80h320V0H560ZM240-160q-33 0-56.5-23.5T160-240v-560q0-33 23.5-56.5T240-880h280l240 240v121h-80v-81H480v-200H240v560h240v80H240Zm0-80v-560 560Z"/>
|
|
363
|
+
</symbol> ` : ""}
|
|
364
|
+
${this.options.includeButtons ? `<symbol id="link-icon" viewBox="0 -960 960 960" fill="#e3e3e3">
|
|
365
|
+
<path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"/>
|
|
366
|
+
</symbol>` : ""}
|
|
367
|
+
</defs>
|
|
368
|
+
</svg>
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { JsonData, JsonDataChannel, JsonDataGuild, JsonMessage, TranscriptOptions } from "../../types/types";
|
|
2
|
+
export declare class Html {
|
|
3
|
+
guild: JsonDataGuild | null;
|
|
4
|
+
channel: JsonDataChannel;
|
|
5
|
+
messages: JsonMessage[];
|
|
6
|
+
options: TranscriptOptions;
|
|
7
|
+
dateFormat: Intl.DateTimeFormat;
|
|
8
|
+
constructor(data: JsonData, options: TranscriptOptions);
|
|
9
|
+
private headerBuilder;
|
|
10
|
+
private messagesBuilder;
|
|
11
|
+
toHTML(): string;
|
|
12
|
+
private embedBuilder;
|
|
13
|
+
private attachmentBuilder;
|
|
14
|
+
private componentBuilder;
|
|
15
|
+
private buttonBuilder;
|
|
16
|
+
private selectorBuilder;
|
|
17
|
+
private spoilerAttachmentBuilder;
|
|
18
|
+
private svgBuilder;
|
|
19
|
+
}
|