discord-html-transcripts-fix 1.0.0 โ 1.2.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/README.md +87 -66
- package/dist/downloader/images.js +60 -85
- package/dist/generator/index.js +197 -36
- package/dist/generator/renderers/attachment.js +27 -36
- package/dist/generator/renderers/components/Container.js +36 -14
- package/dist/generator/renderers/components/Media Gallery.js +24 -18
- package/dist/generator/renderers/components.js +7 -2
- package/dist/generator/renderers/content.js +68 -39
- package/dist/generator/renderers/embed.js +55 -34
- package/dist/generator/renderers/message.js +201 -12
- package/dist/generator/renderers/reply.js +47 -39
- package/dist/generator/renderers/systemMessage.js +138 -43
- package/dist/generator/transcript.js +42 -56
- package/dist/index.js +59 -86
- package/dist/static/client.js +229 -28
- package/dist/types.js +1 -0
- package/dist/utils/buildProfiles.js +141 -29
- package/dist/utils/utils.js +74 -19
- package/package.json +5 -5
|
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.default = DiscordMessage;
|
|
40
40
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
41
|
+
const discord_js_1 = require("discord.js");
|
|
41
42
|
const utils_1 = require("../../utils/utils");
|
|
42
43
|
const attachment_1 = require("./attachment");
|
|
43
44
|
const components_1 = __importDefault(require("./components"));
|
|
@@ -45,15 +46,203 @@ const content_1 = __importStar(require("./content"));
|
|
|
45
46
|
const embed_1 = require("./embed");
|
|
46
47
|
const reply_1 = __importDefault(require("./reply"));
|
|
47
48
|
const systemMessage_1 = __importDefault(require("./systemMessage"));
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
|
|
50
|
+
const FLAG_SUPPRESS_EMBEDS = 1 << 2;
|
|
51
|
+
const FLAG_IS_VOICE_MESSAGE = 1 << 13;
|
|
52
|
+
|
|
53
|
+
function t(context, key, fallback) {
|
|
54
|
+
const dict = context?.i18n?.[context?.lang] || context?.i18n?.en || {};
|
|
55
|
+
return dict[key] || fallback || key;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function DiscordMessage({ message, context }) {
|
|
59
|
+
try {
|
|
60
|
+
if (message.system)
|
|
61
|
+
return (0, jsx_runtime_1.jsx)(systemMessage_1.default, { message: message, context: context });
|
|
62
|
+
|
|
63
|
+
const isCrosspost = message.reference && message.reference.guildId !== message.guild?.id;
|
|
64
|
+
const stickers = message.stickers && message.stickers.size > 0
|
|
65
|
+
? Array.from(message.stickers.values()).map((s) => ({
|
|
66
|
+
id: s.id,
|
|
67
|
+
name: s.name,
|
|
68
|
+
url: s.url || `https://media.discordapp.net/stickers/${s.id}.png`,
|
|
69
|
+
format: s.format,
|
|
70
|
+
}))
|
|
71
|
+
: [];
|
|
72
|
+
const poll = (message.poll && (message.poll.question || (message.poll.answers && message.poll.answers.size))) ? message.poll : null;
|
|
73
|
+
|
|
74
|
+
const flags = (typeof message.flags?.bitfield === 'number') ? message.flags.bitfield : 0;
|
|
75
|
+
const suppressEmbeds = !!(flags & FLAG_SUPPRESS_EMBEDS);
|
|
76
|
+
const isVoice = !!(flags & FLAG_IS_VOICE_MESSAGE);
|
|
77
|
+
|
|
78
|
+
// Forwarded message snapshots (messageSnapshots) โ render before the empty body
|
|
79
|
+
const snapshots = Array.isArray(message.messageSnapshots) ? message.messageSnapshots : [];
|
|
80
|
+
|
|
81
|
+
const isApp = !!(message.author?.bot && message.applicationId);
|
|
82
|
+
|
|
83
|
+
const editedAtIso = message.editedAt instanceof Date ? message.editedAt.toISOString() : null;
|
|
84
|
+
const pinned = !!message.pinned;
|
|
85
|
+
|
|
86
|
+
return ((0, jsx_runtime_1.jsxs)("discord-message", {
|
|
87
|
+
id: `m-${message.id}`,
|
|
88
|
+
timestamp: message.createdAt,
|
|
89
|
+
edited: message.editedAt !== null,
|
|
90
|
+
server: isCrosspost ?? undefined,
|
|
91
|
+
highlight: message.mentions.everyone || pinned,
|
|
92
|
+
profile: message.author.id,
|
|
93
|
+
children: [
|
|
94
|
+
pinned && (0, jsx_runtime_1.jsx)("div", { className: "dht-pinned-indicator", title: "Pinned", children: "๐" }),
|
|
95
|
+
(0, jsx_runtime_1.jsx)(reply_1.default, { message: message, context: context }),
|
|
96
|
+
message.interaction && ((0, jsx_runtime_1.jsx)("discord-command", { slot: "reply", profile: message.interaction.user.id, command: '/' + message.interaction.commandName })),
|
|
97
|
+
isApp && (0, jsx_runtime_1.jsx)("span", { className: "dht-app-badge", "data-i18n": "appBadge", children: t(context, 'appBadge', 'APP') }),
|
|
98
|
+
editedAtIso && (0, jsx_runtime_1.jsx)("span", { className: "dht-edit-marker", title: editedAtIso, "data-edit-iso": editedAtIso, "data-i18n": "edited", "data-i18n-params": JSON.stringify({ time: editedAtIso }), children: '(' + t(context, 'edited', 'edited') + ')' }),
|
|
99
|
+
Array.isArray(message.editHistory) && message.editHistory.length > 0 && renderEditHistory(message.editHistory, context),
|
|
100
|
+
snapshots.length > 0 && renderSnapshots(snapshots, context),
|
|
101
|
+
message.content && ((0, jsx_runtime_1.jsx)(content_1.default, { content: message.content, context: Object.assign({}, context, { type: message.webhookId ? content_1.RenderType.WEBHOOK : content_1.RenderType.NORMAL }) })),
|
|
102
|
+
(0, jsx_runtime_1.jsx)(attachment_1.Attachments, { message: message, context: context }),
|
|
103
|
+
isVoice && renderVoiceIndicator(message, context),
|
|
104
|
+
stickers.length > 0 && renderStickers(stickers),
|
|
105
|
+
poll && renderPoll(poll, context),
|
|
106
|
+
!suppressEmbeds && message.embeds.map((embed, id) => ((0, jsx_runtime_1.jsx)(embed_1.DiscordEmbed, { embed: embed, context: Object.assign({}, context, { index: id, message }) }, id))),
|
|
107
|
+
suppressEmbeds && message.embeds.length > 0 && (0, jsx_runtime_1.jsx)("span", { className: "dht-suppressed", "data-i18n": "suppressedEmbeds", children: t(context, 'suppressedEmbeds', '(embeds hidden)') }),
|
|
108
|
+
message.components.length > 0 && ((0, jsx_runtime_1.jsx)("discord-attachments", { slot: "components", children: message.components.map((component, id) => ((0, jsx_runtime_1.jsx)(components_1.default, { id: id, component: component, context: context }, id))) })),
|
|
109
|
+
message.reactions.cache.size > 0 && ((0, jsx_runtime_1.jsx)("discord-reactions", {
|
|
110
|
+
slot: "reactions",
|
|
111
|
+
children: Array.from(message.reactions.cache.values()).map((reaction, id) => {
|
|
112
|
+
const burst = reaction.burst_count > 0 || (reaction.count_details?.burst > 0);
|
|
113
|
+
return ((0, jsx_runtime_1.jsx)("discord-reaction", {
|
|
114
|
+
name: reaction.emoji?.name || ':unknown:',
|
|
115
|
+
emoji: (0, utils_1.parseDiscordEmoji)(reaction.emoji) || undefined,
|
|
116
|
+
count: reaction.count ?? 0,
|
|
117
|
+
"data-burst": burst ? 'true' : undefined,
|
|
118
|
+
className: burst ? 'dht-reaction--burst' : undefined
|
|
119
|
+
}, `${message.id}r${id}`));
|
|
120
|
+
})
|
|
121
|
+
})),
|
|
122
|
+
message.hasThread && message.thread && renderThread(message.thread, context),
|
|
123
|
+
]
|
|
124
|
+
}, message.id));
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.warn('[discord-html-transcripts-fix] Render failed', message?.id, err?.message || err);
|
|
127
|
+
const safeAuthor = (message?.author?.displayName || message?.author?.username) || 'Unknown';
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)("discord-message", { id: `m-${message?.id}`, children: (0, jsx_runtime_1.jsx)("span", { style: { opacity: 0.6 }, children: `[message from ${safeAuthor} failed to render]` }) }, message?.id));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function renderThread(thread, context) {
|
|
133
|
+
const cta = thread.messageCount
|
|
134
|
+
? `${thread.messageCount} Message${thread.messageCount > 1 ? 's' : ''}`
|
|
135
|
+
: 'View Thread';
|
|
136
|
+
const badges = [];
|
|
137
|
+
if (thread.archived) badges.push((0, jsx_runtime_1.jsx)("span", { className: "dht-thread-badge dht-thread-badge--archived", "data-i18n": "threadArchived", children: t(context, 'threadArchived', 'Archived') }, 'a'));
|
|
138
|
+
if (thread.locked) badges.push((0, jsx_runtime_1.jsx)("span", { className: "dht-thread-badge dht-thread-badge--locked", "data-i18n": "threadLocked", children: t(context, 'threadLocked', 'Locked') }, 'l'));
|
|
139
|
+
return (0, jsx_runtime_1.jsxs)("discord-thread", { slot: "thread", name: thread.name, cta, children: [
|
|
140
|
+
badges,
|
|
141
|
+
thread.lastMessage
|
|
142
|
+
? (0, jsx_runtime_1.jsx)("discord-thread-message", { profile: thread.lastMessage.author.id, children: (0, jsx_runtime_1.jsx)(content_1.default, { content: thread.lastMessage.content.length > 128 ? thread.lastMessage.content.substring(0, 125) + '...' : thread.lastMessage.content, context: Object.assign({}, context, { type: content_1.RenderType.REPLY }) }) })
|
|
143
|
+
: 'Thread messages not saved.'
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function renderStickers(stickers) {
|
|
148
|
+
return (0, jsx_runtime_1.jsx)("div", {
|
|
149
|
+
className: "dht-stickers",
|
|
150
|
+
children: stickers.map((s) => (0, jsx_runtime_1.jsx)("img", {
|
|
151
|
+
src: s.url,
|
|
152
|
+
alt: s.name || 'sticker',
|
|
153
|
+
title: s.name || '',
|
|
154
|
+
className: "dht-sticker"
|
|
155
|
+
}, s.id))
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function renderPoll(poll, context) {
|
|
160
|
+
let totalVotes = 0;
|
|
161
|
+
const answers = poll.answers ? Array.from(poll.answers.values()) : [];
|
|
162
|
+
for (const a of answers) totalVotes += a.voteCount || 0;
|
|
163
|
+
const expires = poll.expiresAt instanceof Date ? poll.expiresAt.toLocaleString('de-DE') : '';
|
|
164
|
+
|
|
165
|
+
return (0, jsx_runtime_1.jsxs)("div", {
|
|
166
|
+
className: "dht-poll",
|
|
167
|
+
children: [
|
|
168
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "dht-poll-q", children: ['๐ ', poll.question?.text || 'Poll'] }),
|
|
169
|
+
(0, jsx_runtime_1.jsx)("div", {
|
|
170
|
+
className: "dht-poll-answers",
|
|
171
|
+
children: answers.map((a, i) => {
|
|
172
|
+
const text = a.text ?? a.media?.text ?? `Option ${i + 1}`;
|
|
173
|
+
const votes = a.voteCount || 0;
|
|
174
|
+
const pct = totalVotes > 0 ? Math.round((votes / totalVotes) * 100) : 0;
|
|
175
|
+
return (0, jsx_runtime_1.jsxs)("div", { className: "dht-poll-a", children: [
|
|
176
|
+
(0, jsx_runtime_1.jsx)("div", { className: "dht-poll-bar", style: { width: pct + '%' } }),
|
|
177
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "dht-poll-line", children: [
|
|
178
|
+
(0, jsx_runtime_1.jsx)("span", { children: String(text) }),
|
|
179
|
+
(0, jsx_runtime_1.jsxs)("span", { className: "dht-poll-pct", children: [votes, ' (', pct, '%)'] })
|
|
180
|
+
] })
|
|
181
|
+
] }, i);
|
|
182
|
+
})
|
|
183
|
+
}),
|
|
184
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "dht-poll-foot", children: [totalVotes, ' votes', expires ? ' ยท ends ' + expires : ''] })
|
|
185
|
+
]
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function renderVoiceIndicator(message, context) {
|
|
190
|
+
const audio = message.attachments?.find?.((a) => typeof a.contentType === 'string' && a.contentType.startsWith('audio/'));
|
|
191
|
+
const duration = audio?.duration_secs || audio?.durationSecs;
|
|
192
|
+
const waveformB64 = audio?.waveform;
|
|
193
|
+
let waveformSvg = null;
|
|
194
|
+
if (typeof waveformB64 === 'string' && waveformB64.length > 0) {
|
|
195
|
+
try {
|
|
196
|
+
const buf = Buffer.from(waveformB64, 'base64');
|
|
197
|
+
const bars = Array.from(buf).slice(0, 100);
|
|
198
|
+
const max = bars.length ? Math.max(1, ...bars) : 1;
|
|
199
|
+
const width = bars.length * 3;
|
|
200
|
+
const rects = bars.map((b, i) => {
|
|
201
|
+
const h = Math.max(2, (b / max) * 20);
|
|
202
|
+
return `<rect x="${i * 3}" y="${(22 - h) / 2}" width="2" height="${h}" rx="1" fill="#5865F2"/>`;
|
|
203
|
+
}).join('');
|
|
204
|
+
waveformSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} 22" width="${width}" height="22">${rects}</svg>`;
|
|
205
|
+
} catch (_e) {}
|
|
206
|
+
}
|
|
207
|
+
return (0, jsx_runtime_1.jsxs)("div", { className: "dht-voice", children: [
|
|
208
|
+
(0, jsx_runtime_1.jsx)("span", { className: "dht-voice-icon", children: '๐ค' }),
|
|
209
|
+
(0, jsx_runtime_1.jsx)("span", { className: "dht-voice-label", "data-i18n": "voiceMessage", children: t(context, 'voiceMessage', 'Voice message') }),
|
|
210
|
+
waveformSvg && (0, jsx_runtime_1.jsx)("span", { className: "dht-voice-wave", dangerouslySetInnerHTML: { __html: waveformSvg } }),
|
|
211
|
+
duration ? (0, jsx_runtime_1.jsxs)("span", { className: "dht-voice-dur", children: [Math.round(duration), 's'] }) : null,
|
|
212
|
+
] });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function renderSnapshots(snapshots, context) {
|
|
216
|
+
return (0, jsx_runtime_1.jsx)("div", {
|
|
217
|
+
className: "dht-forwarded-wrap",
|
|
218
|
+
children: snapshots.map((snap, i) => {
|
|
219
|
+
const m = snap.message || snap;
|
|
220
|
+
const author = m?.author?.displayName || m?.author?.username || 'Unknown';
|
|
221
|
+
const text = m?.content || '';
|
|
222
|
+
return (0, jsx_runtime_1.jsxs)("div", { className: "dht-forwarded", children: [
|
|
223
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "dht-forwarded-head", children: [
|
|
224
|
+
(0, jsx_runtime_1.jsx)("span", { className: "dht-forwarded-icon", children: 'โช๏ธ' }),
|
|
225
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "forwardedFrom", children: t(context, 'forwardedFrom', 'Forwarded from') }),
|
|
226
|
+
(0, jsx_runtime_1.jsx)("strong", { children: ' ' + author }),
|
|
227
|
+
] }),
|
|
228
|
+
text && (0, jsx_runtime_1.jsx)("div", { className: "dht-forwarded-body", children: (0, jsx_runtime_1.jsx)(content_1.default, { content: text, context: Object.assign({}, context, { type: content_1.RenderType.REPLY }) }) }),
|
|
229
|
+
Array.isArray(m?.attachments) && m.attachments.length > 0 && (0, jsx_runtime_1.jsxs)("div", { className: "dht-forwarded-attachments", children: [m.attachments.length, ' attachment(s)'] }),
|
|
230
|
+
] }, i);
|
|
231
|
+
})
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function renderEditHistory(history, context) {
|
|
236
|
+
// Optional feature โ host bot may attach `message.editHistory: [{content, editedAt}, โฆ]`
|
|
237
|
+
return (0, jsx_runtime_1.jsxs)("details", { className: "dht-edit-history", children: [
|
|
238
|
+
(0, jsx_runtime_1.jsx)("summary", { "data-i18n": "editHistoryTitle", children: t(context, 'editHistoryTitle', 'Edit history') }),
|
|
239
|
+
(0, jsx_runtime_1.jsx)("ol", { children: history.map((entry, i) => {
|
|
240
|
+
const when = entry.editedAt instanceof Date ? entry.editedAt.toISOString() : (typeof entry.editedAt === 'string' ? entry.editedAt : '');
|
|
241
|
+
return (0, jsx_runtime_1.jsxs)("li", { children: [
|
|
242
|
+
when && (0, jsx_runtime_1.jsxs)("time", { dateTime: when, children: [t(context, 'editHistoryAt', 'at'), ' ', when] }),
|
|
243
|
+
(0, jsx_runtime_1.jsx)("div", { children: String(entry.content || '') })
|
|
244
|
+
] }, i);
|
|
245
|
+
}) })
|
|
246
|
+
] });
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -1,53 +1,61 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
2
|
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
3
|
+
var ownKeys = function(o){ownKeys = Object.getOwnPropertyNames || function (o){var ar=[];for (var k in o) if (Object.prototype.hasOwnProperty.call(o,k)) ar[ar.length]=k;return ar;};return ownKeys(o);};
|
|
4
|
+
return function (mod){if (mod && mod.__esModule) return mod;var result={};if (mod != null) for (var k=ownKeys(mod), i=0; i<k.length; i++) if (k[i] !== "default") Object.defineProperty(result,k[i],{get:function(){return mod[k[i]];}});Object.defineProperty(result,"default",{value:mod,enumerable:true});return result;};
|
|
34
5
|
})();
|
|
35
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
7
|
exports.default = MessageReply;
|
|
37
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
9
|
const discord_js_1 = require("discord.js");
|
|
39
10
|
const content_1 = __importStar(require("./content"));
|
|
11
|
+
|
|
12
|
+
function t(context, key, fallback) {
|
|
13
|
+
const dict = context?.i18n?.[context?.lang] || context?.i18n?.en || {};
|
|
14
|
+
return dict[key] || fallback || key;
|
|
15
|
+
}
|
|
16
|
+
|
|
40
17
|
async function MessageReply({ message, context }) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
if (!message.reference) return null;
|
|
19
|
+
|
|
20
|
+
const isCrossGuild = message.reference.guildId !== message.guild?.id;
|
|
21
|
+
|
|
22
|
+
// Cross-guild reply: show a placeholder pill instead of silently dropping.
|
|
23
|
+
if (isCrossGuild) {
|
|
24
|
+
return (0, jsx_runtime_1.jsx)("discord-reply", {
|
|
25
|
+
slot: "reply",
|
|
26
|
+
server: true,
|
|
27
|
+
children: (0, jsx_runtime_1.jsx)("em", { "data-i18n": "crossServerReply", children: t(context, 'crossServerReply', 'Message from another server') })
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
46
31
|
const referencedMessage = context.messages.find((m) => m.id === message.reference.messageId);
|
|
47
32
|
if (!referencedMessage)
|
|
48
33
|
return (0, jsx_runtime_1.jsx)("discord-reply", { slot: "reply", children: "Message could not be loaded." });
|
|
49
|
-
|
|
34
|
+
|
|
35
|
+
const isCrossPost = referencedMessage.reference && referencedMessage.reference.guildId !== message.guild?.id;
|
|
50
36
|
const isCommand = referencedMessage.interaction !== null;
|
|
51
|
-
|
|
37
|
+
const author = referencedMessage.member?.nickname ?? referencedMessage.author.displayName ?? referencedMessage.author.username;
|
|
38
|
+
const avatar = referencedMessage.author.avatarURL?.({ size: 32 }) ?? undefined;
|
|
39
|
+
const roleColor = referencedMessage.member?.displayHexColor ?? undefined;
|
|
40
|
+
const op = referencedMessage.author.id === message?.channel?.ownerId && message?.channel?.isThread?.();
|
|
41
|
+
|
|
42
|
+
return ((0, jsx_runtime_1.jsx)("discord-reply", {
|
|
43
|
+
slot: "reply",
|
|
44
|
+
edited: !isCommand && referencedMessage.editedAt !== null,
|
|
45
|
+
attachment: referencedMessage.attachments.size > 0,
|
|
46
|
+
author: author,
|
|
47
|
+
avatar: avatar,
|
|
48
|
+
roleColor: roleColor,
|
|
49
|
+
bot: !isCrossPost && referencedMessage.author.bot,
|
|
50
|
+
verified: referencedMessage.author.flags?.has?.(discord_js_1.UserFlags.VerifiedBot),
|
|
51
|
+
op: op,
|
|
52
|
+
server: isCrossPost ?? undefined,
|
|
53
|
+
command: isCommand,
|
|
54
|
+
children: referencedMessage.content
|
|
55
|
+
? (0, jsx_runtime_1.jsx)("span", { "data-goto": referencedMessage.id, className: "reply-inline", children: (0, jsx_runtime_1.jsx)(content_1.default, { content: referencedMessage.content, context: Object.assign({}, context, { type: content_1.RenderType.REPLY }) }) })
|
|
56
|
+
: isCommand
|
|
57
|
+
? (0, jsx_runtime_1.jsx)("em", { "data-goto": referencedMessage.id, children: "Click to see command." })
|
|
58
|
+
: (0, jsx_runtime_1.jsx)("em", { "data-goto": referencedMessage.id, children: "Click to see attachment." })
|
|
59
|
+
}));
|
|
52
60
|
}
|
|
53
|
-
//# sourceMappingURL=reply.js.map
|
|
61
|
+
//# sourceMappingURL=reply.js.map
|
|
@@ -6,60 +6,145 @@ exports.JoinMessage = JoinMessage;
|
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const discord_js_1 = require("discord.js");
|
|
8
8
|
const utils_1 = require("../../utils/utils");
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
function t(context, key, fallback) {
|
|
11
|
+
const dict = context?.i18n?.[context?.lang] || context?.i18n?.en || {};
|
|
12
|
+
return dict[key] || fallback || key;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function SystemMessage({ message, context }) {
|
|
16
|
+
const author = message.author;
|
|
17
|
+
const authorName = author?.displayName ?? author?.username ?? 'Unknown';
|
|
18
|
+
const color = message.member?.roles?.color?.hexColor;
|
|
19
|
+
const ctx = context || {};
|
|
20
|
+
|
|
11
21
|
switch (message.type) {
|
|
12
22
|
case discord_js_1.MessageType.RecipientAdd:
|
|
13
23
|
case discord_js_1.MessageType.UserJoin:
|
|
14
|
-
return ((0, jsx_runtime_1.jsx)("discord-system-message", { id: `m-${message.id}`, type: "join", children: (0, jsx_runtime_1.jsx)(JoinMessage, { member: message.member, fallbackUser: message.
|
|
24
|
+
return ((0, jsx_runtime_1.jsx)("discord-system-message", { id: `m-${message.id}`, type: "join", children: (0, jsx_runtime_1.jsx)(JoinMessage, { member: message.member, fallbackUser: author, seed: message.id, context: ctx }) }, message.id));
|
|
25
|
+
|
|
15
26
|
case discord_js_1.MessageType.ChannelPinnedMessage:
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "pin", children: [
|
|
27
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "pin", children: [
|
|
28
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
29
|
+
' ',
|
|
30
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "pinned", children: t(ctx, 'pinned', 'pinned a message to this channel.') }),
|
|
31
|
+
(0, jsx_runtime_1.jsx)("i", { "data-goto": message.reference?.messageId, children: " (jump)" }),
|
|
32
|
+
] }, message.id));
|
|
33
|
+
|
|
17
34
|
case discord_js_1.MessageType.GuildBoost:
|
|
18
35
|
case discord_js_1.MessageType.GuildBoostTier1:
|
|
19
36
|
case discord_js_1.MessageType.GuildBoostTier2:
|
|
20
37
|
case discord_js_1.MessageType.GuildBoostTier3:
|
|
21
|
-
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
|
|
38
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
|
|
39
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
40
|
+
' ',
|
|
41
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "boosted", children: t(ctx, 'boosted', 'boosted the server!') }),
|
|
42
|
+
] }, message.id));
|
|
43
|
+
|
|
22
44
|
case discord_js_1.MessageType.ThreadStarterMessage:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
case discord_js_1.MessageType.ThreadCreated:
|
|
46
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "thread", children: [
|
|
47
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
48
|
+
' ',
|
|
49
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "threadStarted", children: t(ctx, 'threadStarted', 'started a thread:') }),
|
|
50
|
+
' ',
|
|
51
|
+
(0, jsx_runtime_1.jsx)("i", { "data-goto": message.reference?.messageId, children: message.content || 'New thread' }),
|
|
52
|
+
] }, message.id));
|
|
53
|
+
|
|
28
54
|
case discord_js_1.MessageType.ChannelNameChange:
|
|
55
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
|
|
56
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
57
|
+
' ',
|
|
58
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "changedChannelName", children: t(ctx, 'changedChannelName', 'changed the channel name:') }),
|
|
59
|
+
' ',
|
|
60
|
+
(0, jsx_runtime_1.jsx)("strong", { children: message.content }),
|
|
61
|
+
] }, message.id));
|
|
62
|
+
|
|
29
63
|
case discord_js_1.MessageType.ChannelIconChange:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
case discord_js_1.MessageType.Reply:
|
|
64
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
|
|
65
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
66
|
+
' ',
|
|
67
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "changedChannelIcon", children: t(ctx, 'changedChannelIcon', 'changed the channel icon.') }),
|
|
68
|
+
] }, message.id));
|
|
69
|
+
|
|
37
70
|
case discord_js_1.MessageType.ChatInputCommand:
|
|
38
|
-
case discord_js_1.MessageType.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
case discord_js_1.MessageType.
|
|
50
|
-
|
|
71
|
+
case discord_js_1.MessageType.ContextMenuCommand: {
|
|
72
|
+
const cmd = message.interaction?.commandName ? '/' + message.interaction.commandName : 'a command';
|
|
73
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
|
|
74
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
75
|
+
' ',
|
|
76
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "usedCommand", children: t(ctx, 'usedCommand', 'used') }),
|
|
77
|
+
' ',
|
|
78
|
+
(0, jsx_runtime_1.jsx)("strong", { children: cmd }),
|
|
79
|
+
] }, message.id));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case discord_js_1.MessageType.Call:
|
|
83
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
|
|
84
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
85
|
+
' ',
|
|
86
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "startedCall", children: t(ctx, 'startedCall', 'started a call.') }),
|
|
87
|
+
] }, message.id));
|
|
88
|
+
|
|
89
|
+
case discord_js_1.MessageType.ChannelFollowAdd:
|
|
90
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
|
|
91
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
92
|
+
' ',
|
|
93
|
+
t(ctx, 'addedFollow', 'added {target} to follow this channel.').replace('{target}', message.content || ''),
|
|
94
|
+
] }, message.id));
|
|
95
|
+
|
|
96
|
+
case discord_js_1.MessageType.RecipientRemove:
|
|
97
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "leave", children: [
|
|
98
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
99
|
+
' ',
|
|
100
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "left", children: t(ctx, 'left', 'left.') }),
|
|
101
|
+
] }, message.id));
|
|
102
|
+
|
|
103
|
+
case discord_js_1.MessageType.AutoModerationAction: {
|
|
104
|
+
// Discord packs detail into the first embed: matched_keyword, blocked_content, channel_id, rule_name
|
|
105
|
+
const e = message.embeds?.[0];
|
|
106
|
+
const ruleName = e?.fields?.find?.((f) => /rule/i.test(f.name))?.value || e?.title || '';
|
|
107
|
+
const blocked = e?.description || '';
|
|
108
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
|
|
109
|
+
(0, jsx_runtime_1.jsx)("span", { "data-i18n": "autoModBlocked", children: t(ctx, 'autoModBlocked', 'AutoMod blocked a message.') }),
|
|
110
|
+
ruleName && (0, jsx_runtime_1.jsxs)("span", { className: "dht-automod-rule", children: [' ยท ', (0, utils_1.escapeHtml)(ruleName)] }),
|
|
111
|
+
blocked && (0, jsx_runtime_1.jsx)("blockquote", { className: "dht-automod-content", children: blocked }),
|
|
112
|
+
] }, message.id));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case discord_js_1.MessageType.RoleSubscriptionPurchase: {
|
|
116
|
+
const roleName = message.roleSubscriptionData?.tierName || message.content || 'a role';
|
|
117
|
+
return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
|
|
118
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
|
|
119
|
+
' ',
|
|
120
|
+
t(ctx, 'roleSubPurchased', 'subscribed to {role}!').replace('{role}', roleName),
|
|
121
|
+
] }, message.id));
|
|
122
|
+
}
|
|
123
|
+
|
|
51
124
|
case discord_js_1.MessageType.GuildIncidentReportRaid:
|
|
52
125
|
case discord_js_1.MessageType.GuildIncidentReportFalseAlarm:
|
|
53
|
-
case discord_js_1.MessageType.
|
|
126
|
+
case discord_js_1.MessageType.GuildIncidentAlertModeEnabled:
|
|
127
|
+
case discord_js_1.MessageType.GuildIncidentAlertModeDisabled:
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: (0, jsx_runtime_1.jsx)("span", { "data-i18n": "serverAlert", children: t(ctx, 'serverAlert', 'Server safety alert.') }) }, message.id));
|
|
129
|
+
|
|
54
130
|
case discord_js_1.MessageType.PollResult:
|
|
131
|
+
return ((0, jsx_runtime_1.jsx)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: (0, jsx_runtime_1.jsx)("span", { "data-i18n": "pollEnded", children: t(ctx, 'pollEnded', 'A poll ended.') }) }, message.id));
|
|
132
|
+
|
|
133
|
+
// These render through the normal pipeline
|
|
134
|
+
case discord_js_1.MessageType.Default:
|
|
135
|
+
case discord_js_1.MessageType.Reply:
|
|
55
136
|
return undefined;
|
|
137
|
+
|
|
56
138
|
default:
|
|
57
139
|
return undefined;
|
|
58
140
|
}
|
|
59
141
|
}
|
|
142
|
+
|
|
60
143
|
function Highlight({ children, color }) {
|
|
61
|
-
|
|
144
|
+
const safe = typeof color === 'string' && /^#[0-9a-fA-F]{3,8}$/.test(color) ? color : 'white';
|
|
145
|
+
return (0, jsx_runtime_1.jsx)("i", { style: { color: safe }, children: children });
|
|
62
146
|
}
|
|
147
|
+
|
|
63
148
|
const allJoinMessages = [
|
|
64
149
|
'{user} just joined the server - glhf!',
|
|
65
150
|
'{user} just joined. Everyone, look busy!',
|
|
@@ -92,24 +177,34 @@ const allJoinMessages = [
|
|
|
92
177
|
"We've been expecting you {user}",
|
|
93
178
|
"It's dangerous to go alone, take {user}!",
|
|
94
179
|
"{user} has joined the server! It's super effective!",
|
|
95
|
-
'Cheers, love! {user} is here!',
|
|
96
180
|
'{user} is here, as the prophecy foretold.',
|
|
97
181
|
"{user} has arrived. Party's over.",
|
|
98
182
|
'Ready player {user}',
|
|
99
183
|
'{user} is here to kick butt and chew bubblegum. And {user} is all out of gum.',
|
|
100
184
|
"Hello. Is it {user} you're looking for?",
|
|
101
185
|
];
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
186
|
+
|
|
187
|
+
// Deterministic โ seed off message.id so the message text stays stable across re-renders.
|
|
188
|
+
function pickJoinMessage(seed) {
|
|
189
|
+
if (!seed) return allJoinMessages[0];
|
|
190
|
+
try {
|
|
191
|
+
// Hash snowflake โ index. BigInt safe for snowflakes.
|
|
192
|
+
let n = 0;
|
|
193
|
+
for (let i = 0; i < seed.length; i++) n = (n * 31 + seed.charCodeAt(i)) >>> 0;
|
|
194
|
+
return allJoinMessages[n % allJoinMessages.length];
|
|
195
|
+
} catch (_e) {
|
|
196
|
+
return allJoinMessages[0];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function JoinMessage({ member, fallbackUser, seed, context }) {
|
|
201
|
+
const template = pickJoinMessage(seed);
|
|
202
|
+
return template
|
|
105
203
|
.split('{user}')
|
|
106
|
-
.flatMap((item, i) =>
|
|
107
|
-
var _a, _b, _c;
|
|
108
|
-
return [
|
|
204
|
+
.flatMap((item, i) => [
|
|
109
205
|
item,
|
|
110
|
-
(0, jsx_runtime_1.jsx)(Highlight, { color:
|
|
111
|
-
]
|
|
112
|
-
})
|
|
206
|
+
(0, jsx_runtime_1.jsx)(Highlight, { color: member?.roles?.color?.hexColor, children: member?.nickname ?? fallbackUser.displayName ?? fallbackUser.username }, i),
|
|
207
|
+
])
|
|
113
208
|
.slice(0, -1);
|
|
114
209
|
}
|
|
115
|
-
//# sourceMappingURL=systemMessage.js.map
|
|
210
|
+
//# sourceMappingURL=systemMessage.js.map
|