transcriptify 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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/src/generateHtml.d.ts +3 -0
  4. package/dist/src/generateHtml.js +303 -0
  5. package/dist/src/index.d.ts +5 -0
  6. package/dist/src/index.js +252 -0
  7. package/dist/src/transcript.d.ts +12 -0
  8. package/dist/src/transcript.js +179 -0
  9. package/dist/src/types/entities.d.ts +30 -0
  10. package/dist/src/types/entities.js +2 -0
  11. package/dist/src/utils/assetManager.d.ts +12 -0
  12. package/dist/src/utils/assetManager.js +295 -0
  13. package/dist/src/utils/authors.d.ts +4 -0
  14. package/dist/src/utils/authors.js +115 -0
  15. package/dist/src/utils/cache.d.ts +16 -0
  16. package/dist/src/utils/cache.js +29 -0
  17. package/dist/src/utils/extractors.d.ts +112 -0
  18. package/dist/src/utils/extractors.js +223 -0
  19. package/dist/src/utils/polls.d.ts +2 -0
  20. package/dist/src/utils/polls.js +91 -0
  21. package/dist/src/utils/transformer.d.ts +6 -0
  22. package/dist/src/utils/transformer.js +78 -0
  23. package/dist/src/utils/user.d.ts +4 -0
  24. package/dist/src/utils/user.js +56 -0
  25. package/dist/src/web/client.d.ts +20 -0
  26. package/dist/src/web/client.js +21 -0
  27. package/dist/src/web/discord-components/AudioPlayer.d.ts +5 -0
  28. package/dist/src/web/discord-components/AudioPlayer.js +231 -0
  29. package/dist/src/web/discord-components/Button.d.ts +3 -0
  30. package/dist/src/web/discord-components/Button.js +27 -0
  31. package/dist/src/web/discord-components/ChannelPinnedMessage.d.ts +7 -0
  32. package/dist/src/web/discord-components/ChannelPinnedMessage.js +11 -0
  33. package/dist/src/web/discord-components/DateSeperator.d.ts +3 -0
  34. package/dist/src/web/discord-components/DateSeperator.js +19 -0
  35. package/dist/src/web/discord-components/Embed.d.ts +2 -0
  36. package/dist/src/web/discord-components/Embed.js +78 -0
  37. package/dist/src/web/discord-components/ForwardedMessage.d.ts +2 -0
  38. package/dist/src/web/discord-components/ForwardedMessage.js +44 -0
  39. package/dist/src/web/discord-components/Message.d.ts +2 -0
  40. package/dist/src/web/discord-components/Message.js +543 -0
  41. package/dist/src/web/discord-components/PinnedMessagesModal.d.ts +6 -0
  42. package/dist/src/web/discord-components/PinnedMessagesModal.js +119 -0
  43. package/dist/src/web/discord-components/PinnedMessagesOverview.d.ts +5 -0
  44. package/dist/src/web/discord-components/PinnedMessagesOverview.js +22 -0
  45. package/dist/src/web/discord-components/Reply.d.ts +2 -0
  46. package/dist/src/web/discord-components/Reply.js +42 -0
  47. package/dist/src/web/discord-components/StickerPreview.d.ts +6 -0
  48. package/dist/src/web/discord-components/StickerPreview.js +40 -0
  49. package/dist/src/web/discord-components/ThemeSwitcher.d.ts +2 -0
  50. package/dist/src/web/discord-components/ThemeSwitcher.js +54 -0
  51. package/dist/src/web/discord-components/Transcript.d.ts +2 -0
  52. package/dist/src/web/discord-components/Transcript.js +174 -0
  53. package/dist/src/web/discord-components/UserJoinMessage.d.ts +3 -0
  54. package/dist/src/web/discord-components/UserJoinMessage.js +33 -0
  55. package/dist/src/web/discord-components/VideoPlayer.d.ts +6 -0
  56. package/dist/src/web/discord-components/VideoPlayer.js +222 -0
  57. package/dist/src/web/discord-components/icons/ChevronDownIcon.d.ts +1 -0
  58. package/dist/src/web/discord-components/icons/ChevronDownIcon.js +7 -0
  59. package/dist/src/web/discord-components/icons/CloseIcon.d.ts +1 -0
  60. package/dist/src/web/discord-components/icons/CloseIcon.js +7 -0
  61. package/dist/src/web/discord-components/icons/ExternalLinkIcon.d.ts +1 -0
  62. package/dist/src/web/discord-components/icons/ExternalLinkIcon.js +7 -0
  63. package/dist/src/web/discord-components/icons/FileAudioIcon.d.ts +1 -0
  64. package/dist/src/web/discord-components/icons/FileAudioIcon.js +7 -0
  65. package/dist/src/web/discord-components/icons/FileCodeIcon.d.ts +1 -0
  66. package/dist/src/web/discord-components/icons/FileCodeIcon.js +7 -0
  67. package/dist/src/web/discord-components/icons/FileDocumentIcon.d.ts +1 -0
  68. package/dist/src/web/discord-components/icons/FileDocumentIcon.js +7 -0
  69. package/dist/src/web/discord-components/icons/PinIcon.d.ts +1 -0
  70. package/dist/src/web/discord-components/icons/PinIcon.js +7 -0
  71. package/dist/src/web/discord-components/icons/VerifiedIcon.d.ts +1 -0
  72. package/dist/src/web/discord-components/icons/VerifiedIcon.js +7 -0
  73. package/dist/src/web/discord-components/index.d.ts +11 -0
  74. package/dist/src/web/discord-components/index.js +24 -0
  75. package/dist/src/web/discord-components/messageHelpers.d.ts +8 -0
  76. package/dist/src/web/discord-components/messageHelpers.js +72 -0
  77. package/dist/src/web/discord-components/themeColors.d.ts +9 -0
  78. package/dist/src/web/discord-components/themeColors.js +320 -0
  79. package/dist/src/web/discord-components/transcriptHelpers.d.ts +19 -0
  80. package/dist/src/web/discord-components/transcriptHelpers.js +120 -0
  81. package/dist/src/web/discord-components/types.d.ts +1 -0
  82. package/dist/src/web/discord-components/types.js +2 -0
  83. package/dist/src/web/discord-components/utils/date.d.ts +3 -0
  84. package/dist/src/web/discord-components/utils/date.js +50 -0
  85. package/dist/src/web/discord-components/utils/markdown.d.ts +11 -0
  86. package/dist/src/web/discord-components/utils/markdown.js +538 -0
  87. package/dist/src/web/discord-components/utils/markdownUtils.d.ts +12 -0
  88. package/dist/src/web/discord-components/utils/markdownUtils.js +140 -0
  89. package/dist/src/web/helpers/avatarHelpers.d.ts +2 -0
  90. package/dist/src/web/helpers/avatarHelpers.js +15 -0
  91. package/dist/src/web/helpers/cdnHelpers.d.ts +5 -0
  92. package/dist/src/web/helpers/cdnHelpers.js +48 -0
  93. package/dist/src/web/helpers/contentHelpers.d.ts +9 -0
  94. package/dist/src/web/helpers/contentHelpers.js +41 -0
  95. package/dist/src/web/helpers/renderContent.d.ts +2 -0
  96. package/dist/src/web/helpers/renderContent.js +15 -0
  97. package/dist/src/web/helpers/scrollHelpers.d.ts +2 -0
  98. package/dist/src/web/helpers/scrollHelpers.js +31 -0
  99. package/dist/src/web/helpers/timestampHelpers.d.ts +6 -0
  100. package/dist/src/web/helpers/timestampHelpers.js +66 -0
  101. package/dist/src/web/hooks/useMessageContent.d.ts +5 -0
  102. package/dist/src/web/hooks/useMessageContent.js +37 -0
  103. package/dist/src/web/index.d.ts +1 -0
  104. package/dist/src/web/index.js +17 -0
  105. package/dist/src/web/types/attachment.d.ts +6 -0
  106. package/dist/src/web/types/attachment.js +2 -0
  107. package/dist/src/web/types/author.d.ts +14 -0
  108. package/dist/src/web/types/author.js +2 -0
  109. package/dist/src/web/types/channel.d.ts +8 -0
  110. package/dist/src/web/types/channel.js +2 -0
  111. package/dist/src/web/types/embed.d.ts +52 -0
  112. package/dist/src/web/types/embed.js +2 -0
  113. package/dist/src/web/types/interaction.d.ts +8 -0
  114. package/dist/src/web/types/interaction.js +2 -0
  115. package/dist/src/web/types/markdown.d.ts +5 -0
  116. package/dist/src/web/types/markdown.js +2 -0
  117. package/dist/src/web/types/message.d.ts +73 -0
  118. package/dist/src/web/types/message.js +2 -0
  119. package/dist/src/web/types/poll.d.ts +11 -0
  120. package/dist/src/web/types/poll.js +2 -0
  121. package/dist/src/web/types/props.d.ts +155 -0
  122. package/dist/src/web/types/props.js +2 -0
  123. package/dist/src/web/types/reaction.d.ts +6 -0
  124. package/dist/src/web/types/reaction.js +2 -0
  125. package/dist/src/web/types/theme.d.ts +14 -0
  126. package/dist/src/web/types/theme.js +2 -0
  127. package/dist/src/web/types/ui.d.ts +10 -0
  128. package/dist/src/web/types/ui.js +2 -0
  129. package/dist/types/download.d.ts +12 -0
  130. package/dist/types/download.js +2 -0
  131. package/dist/types/exportableTranscript.d.ts +169 -0
  132. package/dist/types/exportableTranscript.js +2 -0
  133. package/dist/types/general.d.ts +90 -0
  134. package/dist/types/general.js +2 -0
  135. package/package.json +46 -0
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveChannelNameGlobal = void 0;
4
+ exports.parseDiscordTimestamp = parseDiscordTimestamp;
5
+ exports.formatRelativeTime = formatRelativeTime;
6
+ exports.escapeHtml = escapeHtml;
7
+ exports.splitFencedCodeBlocks = splitFencedCodeBlocks;
8
+ function parseDiscordTimestamp(unixTimestamp, style = "f") {
9
+ const date = new Date(unixTimestamp * 1000);
10
+ const timeOptions = {
11
+ hour: "numeric",
12
+ minute: "2-digit",
13
+ hour12: true
14
+ };
15
+ const shortDateOptions = {
16
+ month: "numeric",
17
+ day: "numeric",
18
+ year: "numeric"
19
+ };
20
+ const longDateOptions = {
21
+ month: "long",
22
+ day: "numeric",
23
+ year: "numeric"
24
+ };
25
+ switch (style) {
26
+ case "t":
27
+ return date.toLocaleTimeString("en-US", timeOptions);
28
+ case "T":
29
+ return date.toLocaleTimeString("en-US", { ...timeOptions, second: "2-digit" });
30
+ case "d":
31
+ return date.toLocaleDateString("en-US", shortDateOptions);
32
+ case "D":
33
+ return date.toLocaleDateString("en-US", longDateOptions);
34
+ case "f":
35
+ return `${date.toLocaleDateString("en-US", longDateOptions)} ${date.toLocaleTimeString("en-US", timeOptions)}`;
36
+ case "F": {
37
+ const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
38
+ const longDate = date.toLocaleDateString("en-US", longDateOptions);
39
+ const time = date.toLocaleTimeString("en-US", timeOptions);
40
+ return `${dayName}, ${longDate} at ${time}`;
41
+ }
42
+ case "R":
43
+ return formatRelativeTime(date);
44
+ default:
45
+ return `${date.toLocaleDateString("en-US", longDateOptions)} ${date.toLocaleTimeString("en-US", timeOptions)}`;
46
+ }
47
+ }
48
+ function formatRelativeTime(date) {
49
+ const now = new Date();
50
+ const diffMs = now.getTime() - date.getTime();
51
+ const diffSeconds = Math.floor(diffMs / 1000);
52
+ const diffMinutes = Math.floor(diffSeconds / 60);
53
+ const diffHours = Math.floor(diffMinutes / 60);
54
+ const diffDays = Math.floor(diffHours / 24);
55
+ const diffMonths = Math.floor(diffDays / 30);
56
+ const diffYears = Math.floor(diffDays / 365);
57
+ if (diffSeconds < 60) {
58
+ return diffSeconds <= 1 ? "1 second ago" : `${diffSeconds} seconds ago`;
59
+ }
60
+ else if (diffMinutes < 60) {
61
+ return diffMinutes === 1 ? "1 minute ago" : `${diffMinutes} minutes ago`;
62
+ }
63
+ else if (diffHours < 24) {
64
+ return diffHours === 1 ? "1 hour ago" : `${diffHours} hours ago`;
65
+ }
66
+ else if (diffDays < 30) {
67
+ return diffDays === 1 ? "1 day ago" : `${diffDays} days ago`;
68
+ }
69
+ else if (diffMonths < 12) {
70
+ return diffMonths === 1 ? "1 month ago" : `${diffMonths} months ago`;
71
+ }
72
+ else {
73
+ return diffYears === 1 ? "1 year ago" : `${diffYears} years ago`;
74
+ }
75
+ }
76
+ function escapeHtml(s) {
77
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
78
+ }
79
+ function splitFencedCodeBlocks(input) {
80
+ const segments = [];
81
+ let idx = 0;
82
+ while (idx < input.length) {
83
+ const start = input.indexOf("```", idx);
84
+ if (start === -1) {
85
+ segments.push({ type: "text", value: input.slice(idx) });
86
+ break;
87
+ }
88
+ if (start > idx) {
89
+ segments.push({ type: "text", value: input.slice(idx, start) });
90
+ }
91
+ const end = input.indexOf("```", start + 3);
92
+ if (end === -1) {
93
+ segments.push({ type: "text", value: input.slice(start) });
94
+ break;
95
+ }
96
+ const fenceBody = input.slice(start + 3, end);
97
+ const lineBreakIndex = fenceBody.indexOf("\n");
98
+ if (lineBreakIndex === -1) {
99
+ const lang = fenceBody.trim();
100
+ segments.push({ type: "code", value: "", lang: lang || undefined });
101
+ }
102
+ else if (fenceBody.startsWith("\n") || fenceBody.startsWith("\r\n")) {
103
+ const code = fenceBody.replace(/^\r?\n/, "");
104
+ segments.push({ type: "code", value: code });
105
+ }
106
+ else {
107
+ const langLine = fenceBody.slice(0, lineBreakIndex).trim();
108
+ const code = fenceBody.slice(lineBreakIndex + 1);
109
+ segments.push({ type: "code", value: code, lang: langLine || undefined });
110
+ }
111
+ idx = end + 3;
112
+ }
113
+ return segments;
114
+ }
115
+ const resolveChannelNameGlobal = (map, id) => {
116
+ if (!map || !id)
117
+ return null;
118
+ const direct = map[id];
119
+ if (direct && direct.name)
120
+ return direct.name;
121
+ const nId = Number(id);
122
+ if (!Number.isNaN(nId)) {
123
+ for (const k of Object.keys(map)) {
124
+ if (Number(k) === nId) {
125
+ const v = map[k];
126
+ if (v && v.name)
127
+ return v.name;
128
+ }
129
+ }
130
+ }
131
+ for (const k of Object.keys(map)) {
132
+ if (String(k).trim() === String(id).trim()) {
133
+ const v = map[k];
134
+ if (v && v.name)
135
+ return v.name;
136
+ }
137
+ }
138
+ return null;
139
+ };
140
+ exports.resolveChannelNameGlobal = resolveChannelNameGlobal;
@@ -0,0 +1,2 @@
1
+ export declare function buildAvatarUrl(userId: string, avatarHash: string): string;
2
+ export declare function getDefaultAvatar(): string;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAvatarUrl = buildAvatarUrl;
4
+ exports.getDefaultAvatar = getDefaultAvatar;
5
+ const cdnHelpers_1 = require("./cdnHelpers");
6
+ function buildAvatarUrl(userId, avatarHash) {
7
+ if (/^https?:\/\//i.test(avatarHash) || /^\.|^\//.test(avatarHash) || /^assets\//.test(avatarHash)) {
8
+ return avatarHash;
9
+ }
10
+ const url = (0, cdnHelpers_1.buildAvatarCdnUrl)(userId, avatarHash);
11
+ return url || avatarHash;
12
+ }
13
+ function getDefaultAvatar() {
14
+ return "/profile/bot.png";
15
+ }
@@ -0,0 +1,5 @@
1
+ export declare function getCdnBase(): string | undefined;
2
+ export declare function getMediaBase(): string | undefined;
3
+ export declare function buildEmojiCdnUrl(id: string, animated: boolean, size?: number): string | undefined;
4
+ export declare function buildStickerCdnUrl(id: string, size?: number): string | undefined;
5
+ export declare function buildAvatarCdnUrl(userId: string, avatarHash: string): string | undefined;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCdnBase = getCdnBase;
4
+ exports.getMediaBase = getMediaBase;
5
+ exports.buildEmojiCdnUrl = buildEmojiCdnUrl;
6
+ exports.buildStickerCdnUrl = buildStickerCdnUrl;
7
+ exports.buildAvatarCdnUrl = buildAvatarCdnUrl;
8
+ function getTranscriptCdnConfig() {
9
+ if (typeof window !== "undefined") {
10
+ return window.__TRANSCRIPT_DATA__;
11
+ }
12
+ return globalThis.__TRANSCRIPT_DATA__;
13
+ }
14
+ function getCdnBase() {
15
+ const data = getTranscriptCdnConfig();
16
+ if (data?.cdnBase && typeof data.cdnBase === "string" && data.cdnBase.length > 0) {
17
+ return data.cdnBase;
18
+ }
19
+ return undefined;
20
+ }
21
+ function getMediaBase() {
22
+ const data = getTranscriptCdnConfig();
23
+ if (data?.mediaBase && typeof data.mediaBase === "string" && data.mediaBase.length > 0) {
24
+ return data.mediaBase;
25
+ }
26
+ return undefined;
27
+ }
28
+ function buildEmojiCdnUrl(id, animated, size = 96) {
29
+ const base = getCdnBase();
30
+ const ext = animated ? "gif" : "webp";
31
+ if (base) {
32
+ return `${base}/emojis/${id}.${ext}?size=${size}&animated=${animated}`;
33
+ }
34
+ return `https://cdn.discordapp.com/emojis/${id}.${ext}?size=${size}&animated=${animated}`;
35
+ }
36
+ function buildStickerCdnUrl(id, size = 160) {
37
+ const base = getMediaBase();
38
+ if (!base)
39
+ return undefined;
40
+ return `${base}/stickers/${id}.webp?size=${size}&quality=lossless`;
41
+ }
42
+ function buildAvatarCdnUrl(userId, avatarHash) {
43
+ const base = getCdnBase();
44
+ if (!base)
45
+ return undefined;
46
+ const ext = avatarHash.startsWith("a_") ? ".gif" : ".png";
47
+ return `${base}/avatars/${userId}/${avatarHash}${ext}?size=128`;
48
+ }
@@ -0,0 +1,9 @@
1
+ import type React from "react";
2
+ import type { ResolvedUsers, ResolvedRoles } from "../types/message";
3
+ export declare function stripDuplicateLinks(content: string, urlsToHide: Set<string>): string;
4
+ export declare function buildEmojiUrl(id: string, animated: boolean): string;
5
+ export declare function extractEmojiUrls(content: string, emojiUrls?: Record<string, string>): Set<string>;
6
+ export declare function renderContent(content: unknown, urlsToHide: Set<string>, emojiUrls?: Record<string, string>, resolvedUsers?: ResolvedUsers, resolvedRoles?: ResolvedRoles, resolvedChannels?: Record<string, {
7
+ name?: string | null;
8
+ guildId?: string | null;
9
+ }>, currentGuildId?: string | null): React.ReactNode;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripDuplicateLinks = stripDuplicateLinks;
4
+ exports.buildEmojiUrl = buildEmojiUrl;
5
+ exports.extractEmojiUrls = extractEmojiUrls;
6
+ exports.renderContent = renderContent;
7
+ const markdown_1 = require("../discord-components/utils/markdown");
8
+ const cdnHelpers_1 = require("./cdnHelpers");
9
+ function stripDuplicateLinks(content, urlsToHide) {
10
+ let result = content;
11
+ urlsToHide.forEach((url) => {
12
+ result = result.split(url).join("");
13
+ });
14
+ return result;
15
+ }
16
+ function buildEmojiUrl(id, animated) {
17
+ const url = (0, cdnHelpers_1.buildEmojiCdnUrl)(id, animated);
18
+ return url || "";
19
+ }
20
+ function extractEmojiUrls(content, emojiUrls) {
21
+ const urls = new Set();
22
+ const emojiTokenRegex = /<(a)?:([^:>]+):(\d+)>/g;
23
+ let match;
24
+ while ((match = emojiTokenRegex.exec(content)) !== null) {
25
+ const animated = !!match[1];
26
+ const id = match[3];
27
+ const token = match[0];
28
+ const src = emojiUrls?.[token] || buildEmojiUrl(id, animated);
29
+ if (src)
30
+ urls.add(src);
31
+ }
32
+ return urls;
33
+ }
34
+ function renderContent(content, urlsToHide, emojiUrls, resolvedUsers, resolvedRoles, resolvedChannels, currentGuildId) {
35
+ if (typeof content === "string") {
36
+ const localHide = extractEmojiUrls(content, emojiUrls);
37
+ const text = stripDuplicateLinks(content, new Set([...urlsToHide, ...localHide]));
38
+ return (0, markdown_1.parseMarkdown)(text, resolvedUsers, resolvedRoles, resolvedChannels, currentGuildId);
39
+ }
40
+ return (0, markdown_1.parseMarkdown)(content, resolvedUsers, resolvedRoles, resolvedChannels, currentGuildId);
41
+ }
@@ -0,0 +1,2 @@
1
+ import type { ResolvedUsers } from "../types/message";
2
+ export declare function renderContent(content: unknown, urlsToHide: Set<string>, emojiUrls?: Record<string, string>, resolvedUsers?: ResolvedUsers): string;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderContent = renderContent;
4
+ const contentHelpers_1 = require("./contentHelpers");
5
+ function renderContent(content, urlsToHide, emojiUrls, resolvedUsers) {
6
+ if (typeof content === "string") {
7
+ return renderMentionsAsString((0, contentHelpers_1.stripDuplicateLinks)(content, new Set([...urlsToHide, ...(0, contentHelpers_1.extractEmojiUrls)(content, emojiUrls)])), resolvedUsers);
8
+ }
9
+ return String(content || "");
10
+ }
11
+ function renderMentionsAsString(text, resolvedUsers) {
12
+ return text.replace(/<@!?(\d+)>/g, (_, id) => {
13
+ return `@${resolvedUsers?.[id]?.displayName || id}`;
14
+ });
15
+ }
@@ -0,0 +1,2 @@
1
+ export declare function scrollToMessage(targetId: string): void;
2
+ export declare function scrollToMessageWithHighlight(targetId: string): void;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scrollToMessage = scrollToMessage;
4
+ exports.scrollToMessageWithHighlight = scrollToMessageWithHighlight;
5
+ function scrollToMessage(targetId) {
6
+ const idStr = String(targetId);
7
+ let el = document.getElementById(idStr);
8
+ if (!el) {
9
+ el = document.querySelector(`[data-message-id="${idStr}"]`);
10
+ }
11
+ if (el) {
12
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
13
+ }
14
+ }
15
+ function scrollToMessageWithHighlight(targetId) {
16
+ const idStr = String(targetId);
17
+ let el = document.getElementById(idStr);
18
+ if (!el) {
19
+ el = document.querySelector(`[data-message-id="${idStr}"]`);
20
+ }
21
+ if (el) {
22
+ document.querySelectorAll(".message-highlight").forEach((e) => {
23
+ e.classList.remove("message-highlight");
24
+ });
25
+ el.classList.add("message-highlight");
26
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
27
+ setTimeout(() => {
28
+ el?.classList.remove("message-highlight");
29
+ }, 2000);
30
+ }
31
+ }
@@ -0,0 +1,6 @@
1
+ export declare function formatFullTimestamp(date: Date): string;
2
+ export declare function formatTagDate(date: Date): string;
3
+ export declare function formatShortTime(date: Date): string;
4
+ export declare function formatShortDateTime(date: Date): string;
5
+ export declare function formatTimeAgo(date: Date): string;
6
+ export declare function formatRelativeTimestamp(date: Date): string;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatFullTimestamp = formatFullTimestamp;
4
+ exports.formatTagDate = formatTagDate;
5
+ exports.formatShortTime = formatShortTime;
6
+ exports.formatShortDateTime = formatShortDateTime;
7
+ exports.formatTimeAgo = formatTimeAgo;
8
+ exports.formatRelativeTimestamp = formatRelativeTimestamp;
9
+ function formatFullTimestamp(date) {
10
+ return date.toLocaleString("en-US", {
11
+ weekday: "long",
12
+ month: "long",
13
+ day: "numeric",
14
+ year: "numeric",
15
+ hour: "numeric",
16
+ minute: "2-digit"
17
+ });
18
+ }
19
+ function formatTagDate(date) {
20
+ return date.toLocaleString("en-US", {
21
+ month: "2-digit",
22
+ day: "2-digit",
23
+ year: "2-digit",
24
+ hour: "numeric",
25
+ minute: "2-digit"
26
+ });
27
+ }
28
+ function formatShortTime(date) {
29
+ return date.toLocaleTimeString([], {
30
+ hour: "numeric",
31
+ minute: "2-digit"
32
+ });
33
+ }
34
+ function formatShortDateTime(date) {
35
+ return date.toLocaleString("en-US", {
36
+ month: "2-digit",
37
+ day: "2-digit",
38
+ year: "numeric",
39
+ hour: "numeric",
40
+ minute: "2-digit"
41
+ });
42
+ }
43
+ function formatTimeAgo(date) {
44
+ const diff = Math.floor((Date.now() - date.getTime()) / 1000);
45
+ if (Math.abs(diff) < 60)
46
+ return `${Math.abs(diff)}s ago`;
47
+ if (Math.abs(diff) < 3600)
48
+ return `${Math.round(Math.abs(diff) / 60)}m ago`;
49
+ if (Math.abs(diff) < 86400)
50
+ return `${Math.round(Math.abs(diff) / 3600)}h ago`;
51
+ return "Yesterday";
52
+ }
53
+ function formatRelativeTimestamp(date) {
54
+ const diff = Math.floor((Date.now() - date.getTime()) / 1000);
55
+ if (Math.abs(diff) < 60)
56
+ return `${Math.abs(diff)}s ago`;
57
+ if (Math.abs(diff) < 3600)
58
+ return `${Math.round(Math.abs(diff) / 60)}m ago`;
59
+ if (Math.abs(diff) < 86400)
60
+ return `${Math.round(Math.abs(diff) / 3600)}h ago`;
61
+ return date.toLocaleString("en-US", {
62
+ month: "2-digit",
63
+ day: "2-digit",
64
+ year: "numeric"
65
+ });
66
+ }
@@ -0,0 +1,5 @@
1
+ import type { UseMessageContentParams } from "../types/props";
2
+ export declare function useMessageContent({ content, attachments, embeds, emojiUrls, resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId }: UseMessageContentParams): {
3
+ renderedContent: import("react").ReactNode;
4
+ urlsToHide: Set<string>;
5
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useMessageContent = useMessageContent;
4
+ const react_1 = require("react");
5
+ const contentHelpers_1 = require("../helpers/contentHelpers");
6
+ function useMessageContent({ content, attachments, embeds, emojiUrls, resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId }) {
7
+ const urlsToHide = (0, react_1.useMemo)(() => {
8
+ const urls = new Set();
9
+ if (attachments) {
10
+ attachments.forEach((a) => {
11
+ if (a?.url)
12
+ urls.add(a.url);
13
+ });
14
+ }
15
+ if (embeds) {
16
+ embeds.forEach((e) => {
17
+ const imgUrl = e?.image?.url || e?.thumbnail?.url;
18
+ const isEmojiEmbed = imgUrl && /cdn\.discordapp\.com\/emojis\//.test(imgUrl) && !e?.title && !e?.description && !e?.author;
19
+ if (!isEmojiEmbed) {
20
+ if (e?.url)
21
+ urls.add(e.url);
22
+ if (e?.image?.url)
23
+ urls.add(e.image.url);
24
+ if (e?.thumbnail?.url)
25
+ urls.add(e.thumbnail.url);
26
+ }
27
+ });
28
+ }
29
+ return urls;
30
+ }, [attachments, embeds]);
31
+ const renderedContent = (0, react_1.useMemo)(() => {
32
+ if (!content)
33
+ return null;
34
+ return (0, contentHelpers_1.renderContent)(content, urlsToHide, emojiUrls, resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId);
35
+ }, [content, urlsToHide, emojiUrls, resolvedUsers]);
36
+ return { renderedContent, urlsToHide };
37
+ }
@@ -0,0 +1 @@
1
+ export * from "./discord-components";
@@ -0,0 +1,17 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./discord-components"), exports);
@@ -0,0 +1,6 @@
1
+ export interface Attachment {
2
+ url: string;
3
+ filename?: string;
4
+ size?: number;
5
+ size_human?: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ export interface Author {
2
+ id?: string;
3
+ name: string;
4
+ username: string;
5
+ avatar: string;
6
+ bot?: boolean;
7
+ verified?: boolean;
8
+ color?: string | null;
9
+ guildTag?: GuildTag | null;
10
+ }
11
+ export interface GuildTag {
12
+ name?: string | null;
13
+ iconUrl?: string | null;
14
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ export interface ChannelInfo {
2
+ name: string;
3
+ id?: string;
4
+ topic?: string;
5
+ guildName?: string;
6
+ type?: "text" | "voice" | "announcement";
7
+ guildId?: string | null;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,52 @@
1
+ export interface EmbedField {
2
+ name: string;
3
+ value: string;
4
+ inline?: boolean;
5
+ }
6
+ export interface EmbedAuthor {
7
+ name: string;
8
+ iconUrl?: string;
9
+ url?: string;
10
+ }
11
+ export interface EmbedFooter {
12
+ text: string;
13
+ iconUrl?: string;
14
+ }
15
+ import type { ButtonProps } from "./ui";
16
+ export interface EmbedProps {
17
+ title?: string;
18
+ description?: string | null;
19
+ url?: string | null;
20
+ color?: string | null;
21
+ timestamp?: string | null;
22
+ author?: EmbedAuthor | null;
23
+ footer?: EmbedFooter | null;
24
+ image?: string | {
25
+ url?: string;
26
+ } | null;
27
+ thumbnail?: string | {
28
+ url?: string;
29
+ } | null;
30
+ fields?: EmbedField[];
31
+ buttons?: ButtonProps[];
32
+ version?: "v1" | "v2";
33
+ resolvedUsers?: Record<string, {
34
+ displayName?: string;
35
+ }>;
36
+ resolvedRoles?: Record<string, {
37
+ name?: string;
38
+ color?: string | number;
39
+ }>;
40
+ resolvedChannels?: Record<string, {
41
+ name?: string | null;
42
+ guildId?: string | null;
43
+ }>;
44
+ channelGuildId?: string | null;
45
+ interaction?: {
46
+ name?: string;
47
+ user?: {
48
+ id?: string;
49
+ username?: string;
50
+ };
51
+ };
52
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ export interface Interaction {
2
+ name?: string;
3
+ user?: InteractionUser;
4
+ }
5
+ export interface InteractionUser {
6
+ id?: string;
7
+ username?: string;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export interface MarkdownToken {
2
+ type: string;
3
+ value?: string;
4
+ meta?: any;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,73 @@
1
+ import type { Attachment } from "./attachment";
2
+ import type { Author } from "./author";
3
+ import type { Interaction } from "./interaction";
4
+ import type { Poll } from "./poll";
5
+ import type { Reaction } from "./reaction";
6
+ export interface MessageProps {
7
+ id: string;
8
+ author: Author;
9
+ compact?: boolean;
10
+ timestamp?: string;
11
+ editedAt?: string | null;
12
+ content?: unknown;
13
+ attachments?: Attachment[];
14
+ embeds?: unknown[];
15
+ buttons?: unknown[];
16
+ actionRows?: unknown[];
17
+ selects?: unknown[];
18
+ stickers?: Sticker[];
19
+ replyTo?: ReplyReference | null;
20
+ forwardedFrom?: ForwardedReference | null;
21
+ forwardedMessage?: Partial<MessageProps> | null;
22
+ reactions?: Reaction[];
23
+ resolvedUsers?: ResolvedUsers;
24
+ resolvedRoles?: ResolvedRoles;
25
+ resolvedChannels?: Record<string, {
26
+ name?: string | null;
27
+ guildId?: string | null;
28
+ }>;
29
+ channelGuildId?: string | null;
30
+ emojiUrls?: Record<string, string>;
31
+ poll?: Poll;
32
+ interaction?: Interaction;
33
+ messageType?: number;
34
+ pinned?: boolean;
35
+ onPinIconClick?: () => void;
36
+ onNavigateToMessage?: (id: string) => void;
37
+ referencedMessage?: Partial<MessageProps> | null;
38
+ referencedMessageId?: string | number | null;
39
+ }
40
+ export interface ReplyReference {
41
+ id: string;
42
+ authorName?: string;
43
+ author?: Partial<Author>;
44
+ preview?: string;
45
+ content?: string;
46
+ timestamp?: string;
47
+ embeds?: unknown[];
48
+ attachments?: unknown[];
49
+ stickers?: unknown[];
50
+ edited?: boolean;
51
+ editedAt?: string;
52
+ }
53
+ export interface ForwardedReference {
54
+ id?: string;
55
+ name?: string;
56
+ }
57
+ export interface Sticker {
58
+ url: string;
59
+ name?: string;
60
+ }
61
+ export interface ResolvedUsers {
62
+ [id: string]: {
63
+ displayName?: string;
64
+ username?: string;
65
+ avatar?: string;
66
+ };
67
+ }
68
+ export interface ResolvedRoles {
69
+ [id: string]: {
70
+ name?: string;
71
+ color?: string;
72
+ };
73
+ }