discord-html-transcripts-fix 1.3.0 → 1.6.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.
@@ -16,6 +16,7 @@ async function SystemMessage({ message, context }) {
16
16
  const author = message.author;
17
17
  const authorName = author?.displayName ?? author?.username ?? 'Unknown';
18
18
  const color = message.member?.roles?.color?.hexColor;
19
+ const authorId = author?.id;
19
20
  const ctx = context || {};
20
21
 
21
22
  switch (message.type) {
@@ -25,12 +26,31 @@ async function SystemMessage({ message, context }) {
25
26
 
26
27
  case discord_js_1.MessageType.ChannelPinnedMessage: {
27
28
  const refId = message.reference?.messageId;
28
- return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "pin", children: [
29
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
30
- ' ',
31
- (0, jsx_runtime_1.jsx)("span", { "data-i18n": "pinned", children: t(ctx, 'pinned', 'pinned a message to this channel.') }),
32
- refId ? (0, jsx_runtime_1.jsx)("i", { "data-goto": refId, className: "dht-jump", role: "button", tabIndex: 0, children: " (jump)" }) : null,
33
- ] }, message.id));
29
+ // Discord renders this as: "{user} pinned {a message} to this channel."
30
+ // where "a message" is the clickable jump link. The i18n key `pinned`
31
+ // accepts a `{message}` placeholder; if absent (legacy dict), we fall
32
+ // back to flat text + a trailing " (jump)".
33
+ const template = t(ctx, 'pinned', 'pinned {message} to this channel.');
34
+ const linkLabel = t(ctx, 'pinnedLink', 'a message');
35
+ const linkEl = refId
36
+ ? (0, jsx_runtime_1.jsx)("i", { "data-goto": refId, className: "dht-jump", role: "button", tabIndex: 0, children: linkLabel })
37
+ : (0, jsx_runtime_1.jsx)("strong", { children: linkLabel });
38
+ const parts = template.includes('{message}') ? template.split('{message}') : null;
39
+ return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "pin", children: parts
40
+ ? [
41
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
42
+ ' ',
43
+ parts[0],
44
+ linkEl,
45
+ parts[1],
46
+ ]
47
+ : [
48
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
49
+ ' ',
50
+ (0, jsx_runtime_1.jsx)("span", { "data-i18n": "pinned", children: template }),
51
+ refId ? (0, jsx_runtime_1.jsx)("i", { "data-goto": refId, className: "dht-jump", role: "button", tabIndex: 0, children: " (jump)" }) : null,
52
+ ]
53
+ }, message.id));
34
54
  }
35
55
 
36
56
  case discord_js_1.MessageType.GuildBoost:
@@ -38,7 +58,7 @@ async function SystemMessage({ message, context }) {
38
58
  case discord_js_1.MessageType.GuildBoostTier2:
39
59
  case discord_js_1.MessageType.GuildBoostTier3:
40
60
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
41
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
61
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
42
62
  ' ',
43
63
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "boosted", children: t(ctx, 'boosted', 'boosted the server!') }),
44
64
  ] }, message.id));
@@ -48,7 +68,7 @@ async function SystemMessage({ message, context }) {
48
68
  const refId = message.reference?.messageId;
49
69
  const label = message.content || 'New thread';
50
70
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "thread", children: [
51
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
71
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
52
72
  ' ',
53
73
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "threadStarted", children: t(ctx, 'threadStarted', 'started a thread:') }),
54
74
  ' ',
@@ -60,7 +80,7 @@ async function SystemMessage({ message, context }) {
60
80
 
61
81
  case discord_js_1.MessageType.ChannelNameChange:
62
82
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
63
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
83
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
64
84
  ' ',
65
85
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "changedChannelName", children: t(ctx, 'changedChannelName', 'changed the channel name:') }),
66
86
  ' ',
@@ -69,7 +89,7 @@ async function SystemMessage({ message, context }) {
69
89
 
70
90
  case discord_js_1.MessageType.ChannelIconChange:
71
91
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
72
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
92
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
73
93
  ' ',
74
94
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "changedChannelIcon", children: t(ctx, 'changedChannelIcon', 'changed the channel icon.') }),
75
95
  ] }, message.id));
@@ -78,7 +98,7 @@ async function SystemMessage({ message, context }) {
78
98
  case discord_js_1.MessageType.ContextMenuCommand: {
79
99
  const cmd = message.interaction?.commandName ? '/' + message.interaction.commandName : 'a command';
80
100
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
81
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
101
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
82
102
  ' ',
83
103
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "usedCommand", children: t(ctx, 'usedCommand', 'used') }),
84
104
  ' ',
@@ -88,7 +108,7 @@ async function SystemMessage({ message, context }) {
88
108
 
89
109
  case discord_js_1.MessageType.Call:
90
110
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
91
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
111
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
92
112
  ' ',
93
113
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "startedCall", children: t(ctx, 'startedCall', 'started a call.') }),
94
114
  ] }, message.id));
@@ -97,7 +117,7 @@ async function SystemMessage({ message, context }) {
97
117
  const followText = t(ctx, 'addedFollow', 'added {target} to follow this channel.');
98
118
  const parts = followText.split('{target}');
99
119
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
100
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
120
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
101
121
  ' ',
102
122
  parts[0],
103
123
  (0, jsx_runtime_1.jsxs)("span", { className: "dht-mention dht-mention--channel", children: ['#', message.content || 'channel'] }),
@@ -107,7 +127,7 @@ async function SystemMessage({ message, context }) {
107
127
 
108
128
  case discord_js_1.MessageType.RecipientRemove:
109
129
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "leave", children: [
110
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
130
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
111
131
  ' ',
112
132
  (0, jsx_runtime_1.jsx)("span", { "data-i18n": "left", children: t(ctx, 'left', 'left.') }),
113
133
  ] }, message.id));
@@ -132,34 +152,34 @@ async function SystemMessage({ message, context }) {
132
152
  }
133
153
  case discord_js_1.MessageType.StageStart:
134
154
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
135
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
155
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
136
156
  ' started a stage: ',
137
157
  (0, jsx_runtime_1.jsx)("strong", { children: message.content || '' })
138
158
  ] }, message.id));
139
159
  case discord_js_1.MessageType.StageEnd:
140
160
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "leave", children: [
141
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
161
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
142
162
  ' ended the stage.'
143
163
  ] }, message.id));
144
164
  case discord_js_1.MessageType.StageSpeaker:
145
165
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
146
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
166
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
147
167
  ' is now a speaker.'
148
168
  ] }, message.id));
149
169
  case discord_js_1.MessageType.StageRaiseHand:
150
170
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "call", children: [
151
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
171
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
152
172
  ' requested to speak.'
153
173
  ] }, message.id));
154
174
  case discord_js_1.MessageType.StageTopic:
155
175
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "edit", children: [
156
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
176
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
157
177
  ' changed the stage topic: ',
158
178
  (0, jsx_runtime_1.jsx)("strong", { children: message.content || '' })
159
179
  ] }, message.id));
160
180
  case discord_js_1.MessageType.GuildApplicationPremiumSubscription:
161
181
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
162
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
182
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
163
183
  ' subscribed ',
164
184
  (0, jsx_runtime_1.jsx)("strong", { children: message.applicationId ? `app ${message.applicationId}` : 'an app' }),
165
185
  ' to this server.'
@@ -168,7 +188,7 @@ async function SystemMessage({ message, context }) {
168
188
  case discord_js_1.MessageType.RoleSubscriptionPurchase: {
169
189
  const roleName = message.roleSubscriptionData?.tierName || message.content || 'a role';
170
190
  return ((0, jsx_runtime_1.jsxs)("discord-system-message", { id: `m-${message.id}`, type: "boost", children: [
171
- (0, jsx_runtime_1.jsx)(Highlight, { color, children: authorName }),
191
+ (0, jsx_runtime_1.jsx)(Highlight, { color, userId: authorId, children: authorName }),
172
192
  ' ',
173
193
  t(ctx, 'roleSubPurchased', 'subscribed to {role}!').replace('{role}', roleName),
174
194
  ] }, message.id));
@@ -193,9 +213,16 @@ async function SystemMessage({ message, context }) {
193
213
  }
194
214
  }
195
215
 
196
- function Highlight({ children, color }) {
216
+ function Highlight({ children, color, userId }) {
197
217
  const safe = typeof color === 'string' && /^#[0-9a-fA-F]{3,8}$/.test(color) ? color : 'white';
198
- return (0, jsx_runtime_1.jsx)("i", { style: { color: safe }, children: children });
218
+ const props = { style: { color: safe } };
219
+ // Wire up the user popup the same way mentions and message authors do.
220
+ if (typeof userId === 'string' && userId) {
221
+ props.className = 'dht-sys-author';
222
+ props['data-mention-type'] = 'user';
223
+ props['data-mention-id'] = userId;
224
+ }
225
+ return (0, jsx_runtime_1.jsx)("i", Object.assign({}, props, { children }));
199
226
  }
200
227
 
201
228
  const allJoinMessages = [
@@ -252,11 +279,12 @@ function pickJoinMessage(seed) {
252
279
 
253
280
  function JoinMessage({ member, fallbackUser, seed, context }) {
254
281
  const template = pickJoinMessage(seed);
282
+ const uid = member?.id || fallbackUser?.id;
255
283
  return template
256
284
  .split('{user}')
257
285
  .flatMap((item, i) => [
258
286
  item,
259
- (0, jsx_runtime_1.jsx)(Highlight, { color: member?.roles?.color?.hexColor, children: member?.nickname ?? fallbackUser.displayName ?? fallbackUser.username }, i),
287
+ (0, jsx_runtime_1.jsx)(Highlight, { color: member?.roles?.color?.hexColor, userId: uid, children: member?.nickname ?? fallbackUser.displayName ?? fallbackUser.username }, i),
260
288
  ])
261
289
  .slice(0, -1);
262
290
  }
@@ -48,15 +48,35 @@ async function DiscordMessages(_a) {
48
48
  dateSeps[idx] && (0, jsx_runtime_1.jsx)("div", { className: "dht-date-sep", children: dateSeps[idx] }, `sep-${idx}`),
49
49
  (0, jsx_runtime_1.jsx)(message_1.default, { message: message, context: Object.assign({ messages, channel, callbacks }, options) }, message.id)
50
50
  ]),
51
- (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center', width: '100%' }, children: [
52
- options.footerText
53
- ? options.footerText.replaceAll('{number}', messages.length.toString()).replaceAll('{s}', messages.length > 1 ? 's' : '')
54
- : `Exported ${messages.length} message${messages.length > 1 ? 's' : ''}.`,
55
- ' ',
56
- options.poweredBy
57
- ? (0, jsx_runtime_1.jsxs)("span", { style: { textAlign: 'center' }, children: ["Powered by ", (0, jsx_runtime_1.jsx)("a", { href: "https://github.com/ItzDerock/discord-html-transcripts", style: { color: 'lightblue' }, children: "discord-html-transcripts" }), "."] })
58
- : null
59
- ] })
51
+ renderLegacyFooter(messages, options),
60
52
  ] }));
61
53
  }
54
+
55
+ // Legacy "Exported X message(s). Powered by …" line. The new stats footer
56
+ // (see renderStatsFooter in generator/index.js) already shows the message
57
+ // count, so this line is suppressed by default and only renders when:
58
+ // - options.statsFooter === false (caller opted out of the new footer), or
59
+ // - options.footerText is explicitly set to a string, or
60
+ // - options.poweredBy === true (caller wants the credit link).
61
+ function renderLegacyFooter(messages, options) {
62
+ const statsDisabled = options.statsFooter === false ||
63
+ (options.statsFooter && options.statsFooter.enabled === false);
64
+ const customText = (typeof options.footerText === 'string' && options.footerText.length > 0)
65
+ ? options.footerText.replaceAll('{number}', messages.length.toString()).replaceAll('{s}', messages.length > 1 ? 's' : '')
66
+ : null;
67
+ const wantsPowered = !!options.poweredBy;
68
+ // Default render only if stats footer is off AND no custom text was set.
69
+ const defaultText = statsDisabled && !customText
70
+ ? `Exported ${messages.length} message${messages.length > 1 ? 's' : ''}.`
71
+ : null;
72
+ const shown = customText || defaultText;
73
+ if (!shown && !wantsPowered) return null;
74
+ return (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center', width: '100%' }, children: [
75
+ shown,
76
+ shown && wantsPowered ? ' ' : null,
77
+ wantsPowered
78
+ ? (0, jsx_runtime_1.jsxs)("span", { style: { textAlign: 'center' }, children: ["Powered by ", (0, jsx_runtime_1.jsx)("a", { href: "https://github.com/ItzDerock/discord-html-transcripts", style: { color: 'lightblue' }, children: "discord-html-transcripts" }), "."] })
79
+ : null
80
+ ] });
81
+ }
62
82
  //# sourceMappingURL=transcript.js.map