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,231 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = AudioPlayer;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const FileAudioIcon_1 = __importDefault(require("./icons/FileAudioIcon"));
10
+ const audioCache = new Map();
11
+ function AudioPlayer({ url, filename, filesize }) {
12
+ const audioRef = react_1.default.useRef(null);
13
+ const [isPlaying, setIsPlaying] = react_1.default.useState(false);
14
+ const [currentTime, setCurrentTime] = react_1.default.useState(0);
15
+ const [duration, setDuration] = react_1.default.useState(0);
16
+ const [isMuted, setIsMuted] = react_1.default.useState(false);
17
+ const [volume, setVolume] = react_1.default.useState(1);
18
+ const volTrackRef = react_1.default.useRef(null);
19
+ const draggingRef = react_1.default.useRef(false);
20
+ const [showVolPopover, setShowVolPopover] = react_1.default.useState(false);
21
+ const hideTimeoutRef = react_1.default.useRef(null);
22
+ const popoverContainerRef = react_1.default.useRef(null);
23
+ const popoverRef = react_1.default.useRef(null);
24
+ const cancelHide = () => {
25
+ if (hideTimeoutRef.current !== null) {
26
+ window.clearTimeout(hideTimeoutRef.current);
27
+ hideTimeoutRef.current = null;
28
+ }
29
+ };
30
+ const scheduleHide = (ms = 260) => {
31
+ cancelHide();
32
+ hideTimeoutRef.current = window.setTimeout(() => {
33
+ hideTimeoutRef.current = null;
34
+ setShowVolPopover(false);
35
+ }, ms);
36
+ };
37
+ react_1.default.useEffect(() => {
38
+ return () => {
39
+ cancelHide();
40
+ };
41
+ }, []);
42
+ react_1.default.useEffect(() => {
43
+ if (!showVolPopover)
44
+ return;
45
+ const onMove = (e) => {
46
+ const el = popoverContainerRef.current;
47
+ const pop = popoverRef.current;
48
+ if (!el && !pop)
49
+ return;
50
+ let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity;
51
+ const addRect = (r) => {
52
+ if (!r)
53
+ return;
54
+ left = Math.min(left, r.left);
55
+ top = Math.min(top, r.top);
56
+ right = Math.max(right, r.right);
57
+ bottom = Math.max(bottom, r.bottom);
58
+ };
59
+ addRect(el ? el.getBoundingClientRect() : null);
60
+ addRect(pop ? pop.getBoundingClientRect() : null);
61
+ const expand = 20;
62
+ const inside = e.clientX >= left - expand && e.clientX <= right + expand && e.clientY >= top - expand && e.clientY <= bottom + expand;
63
+ if (inside) {
64
+ cancelHide();
65
+ }
66
+ else {
67
+ scheduleHide(400);
68
+ }
69
+ };
70
+ window.addEventListener("mousemove", onMove);
71
+ return () => window.removeEventListener("mousemove", onMove);
72
+ }, [showVolPopover]);
73
+ const handleVolPointer = (clientY) => {
74
+ const el = volTrackRef.current;
75
+ if (!el || !audioRef.current)
76
+ return;
77
+ const rect = el.getBoundingClientRect();
78
+ const y = clientY - rect.top;
79
+ const pct = 1 - y / rect.height;
80
+ const v = Math.max(0, Math.min(1, pct));
81
+ audioRef.current.volume = v;
82
+ audioRef.current.muted = v === 0;
83
+ setVolume(v);
84
+ setIsMuted(v === 0);
85
+ };
86
+ const onGlobalMouseMove = (e) => {
87
+ if (!draggingRef.current)
88
+ return;
89
+ handleVolPointer(e.clientY);
90
+ };
91
+ const onGlobalMouseUp = () => {
92
+ draggingRef.current = false;
93
+ window.removeEventListener("mousemove", onGlobalMouseMove);
94
+ window.removeEventListener("mouseup", onGlobalMouseUp);
95
+ };
96
+ const startDrag = (ev) => {
97
+ draggingRef.current = true;
98
+ handleVolPointer(ev.clientY);
99
+ window.addEventListener("mousemove", onGlobalMouseMove);
100
+ window.addEventListener("mouseup", onGlobalMouseUp);
101
+ };
102
+ const startTouchDrag = (touch) => {
103
+ draggingRef.current = true;
104
+ handleVolPointer(touch.clientY);
105
+ const onTouchMove = (e) => handleVolPointer(e.touches[0].clientY);
106
+ const onTouchEnd = () => {
107
+ draggingRef.current = false;
108
+ window.removeEventListener("touchmove", onTouchMove);
109
+ window.removeEventListener("touchend", onTouchEnd);
110
+ };
111
+ window.addEventListener("touchmove", onTouchMove);
112
+ window.addEventListener("touchend", onTouchEnd);
113
+ };
114
+ const formatTime = (seconds) => {
115
+ if (!isFinite(seconds))
116
+ return "0:00";
117
+ const mins = Math.floor(seconds / 60);
118
+ const secs = Math.floor(seconds % 60);
119
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
120
+ };
121
+ const togglePlay = () => {
122
+ if (audioRef.current) {
123
+ if (isPlaying) {
124
+ audioRef.current.pause();
125
+ }
126
+ else {
127
+ audioRef.current.play().catch((err) => {
128
+ console.error("Playback failed:", err);
129
+ setIsPlaying(false);
130
+ });
131
+ }
132
+ }
133
+ };
134
+ const handlePlay = () => setIsPlaying(true);
135
+ const handlePause = () => setIsPlaying(false);
136
+ const handleTimeUpdate = () => {
137
+ if (audioRef.current)
138
+ setCurrentTime(audioRef.current.currentTime);
139
+ };
140
+ const handleLoadedMetadata = () => {
141
+ if (audioRef.current)
142
+ setDuration(audioRef.current.duration);
143
+ };
144
+ const handleEnded = () => setIsPlaying(false);
145
+ react_1.default.useEffect(() => {
146
+ let a = audioCache.get(url);
147
+ if (!a) {
148
+ a = new Audio(url);
149
+ audioCache.set(url, a);
150
+ }
151
+ audioRef.current = a;
152
+ setVolume(a.volume);
153
+ setIsMuted(a.muted);
154
+ setIsPlaying(!a.paused);
155
+ if (isFinite(a.duration) && a.duration > 0)
156
+ setDuration(a.duration);
157
+ setCurrentTime(a.currentTime);
158
+ a.addEventListener("timeupdate", handleTimeUpdate);
159
+ a.addEventListener("loadedmetadata", handleLoadedMetadata);
160
+ a.addEventListener("ended", handleEnded);
161
+ a.addEventListener("play", handlePlay);
162
+ a.addEventListener("pause", handlePause);
163
+ const handleVolumeChangeEvent = () => {
164
+ if (audioRef.current) {
165
+ setVolume(audioRef.current.volume);
166
+ setIsMuted(audioRef.current.muted);
167
+ }
168
+ };
169
+ a.addEventListener("volumechange", handleVolumeChangeEvent);
170
+ return () => {
171
+ a.removeEventListener("timeupdate", handleTimeUpdate);
172
+ a.removeEventListener("loadedmetadata", handleLoadedMetadata);
173
+ a.removeEventListener("ended", handleEnded);
174
+ a.removeEventListener("play", handlePlay);
175
+ a.removeEventListener("pause", handlePause);
176
+ a.removeEventListener("volumechange", handleVolumeChangeEvent);
177
+ audioRef.current = null;
178
+ };
179
+ }, [url]);
180
+ const handleSliderChange = (e) => {
181
+ const newTime = parseFloat(e.target.value);
182
+ if (audioRef.current) {
183
+ audioRef.current.currentTime = newTime;
184
+ setCurrentTime(newTime);
185
+ }
186
+ };
187
+ const handleVolumeChange = (e) => {
188
+ if (audioRef.current) {
189
+ audioRef.current.volume = parseFloat(e.target.value);
190
+ }
191
+ };
192
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full max-w-[520px] bg-[#1e1f22] border border-[#111214] rounded-lg p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)(FileAudioIcon_1.default, { className: "h-10 w-8 flex-shrink-0" }), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("a", { href: url, download: true, className: "text-[15px] font-medium text-[#00a8fc] truncate hover:underline block", children: filename }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#b5bac1]", children: filesize })] })] }), (0, jsx_runtime_1.jsx)("a", { href: url, download: true, className: "ml-2 p-1 hover:bg-[#23252b] rounded transition-colors flex-shrink-0", title: "Download", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "#b5bac1", d: "M12 2a1 1 0 0 1 1 1v10.59l3.3-3.3a1 1 0 1 1 1.4 1.42l-5 5a1 1 0 0 1-1.4 0l-5-5a1 1 0 1 1 1.4-1.42l3.3 3.3V3a1 1 0 0 1 1-1ZM3 20a1 1 0 1 0 0 2h18a1 1 0 1 0 0-2H3Z" }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: togglePlay, className: "p-2 hover:bg-[#23252b] rounded transition-colors flex-shrink-0", title: isPlaying ? "Pause" : "Play", children: isPlaying ? ((0, jsx_runtime_1.jsx)("svg", { className: "controlIcon_cf09d8", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M6 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H6ZM15 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-3Z", className: "" }) })) : ((0, jsx_runtime_1.jsx)("svg", { className: "controlIcon_cf09d8", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M9.25 3.35C7.87 2.45 6 3.38 6 4.96v14.08c0 1.58 1.87 2.5 3.25 1.61l10.85-7.04a1.9 1.9 0 0 0 0-3.22L9.25 3.35Z", className: "" }) })) }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-[#b5bac1] min-w-[60px]", children: [formatTime(currentTime), " / ", formatTime(duration)] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 relative h-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute left-0 right-0 top-1/2 transform -translate-y-1/2 h-1 bg-[#23252b] rounded" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute left-0 top-1/2 transform -translate-y-1/2 h-1 bg-[#7c5cff] rounded pointer-events-none", style: { width: `${duration > 0 ? (currentTime / duration) * 100 : 0}%` } }), (0, jsx_runtime_1.jsx)("input", { type: "range", min: 0, max: duration || 0, value: currentTime, onChange: handleSliderChange, className: "absolute left-0 top-0 w-full h-3 bg-transparent appearance-none cursor-pointer" })] }), (0, jsx_runtime_1.jsxs)("div", { ref: (el) => {
193
+ popoverContainerRef.current = el;
194
+ }, className: "relative flex-shrink-0", onMouseEnter: () => {
195
+ cancelHide();
196
+ setShowVolPopover(true);
197
+ }, onMouseLeave: () => {
198
+ scheduleHide(260);
199
+ }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
200
+ if (audioRef.current) {
201
+ const next = !audioRef.current.muted;
202
+ audioRef.current.muted = next;
203
+ setIsMuted(next);
204
+ }
205
+ }, className: "w-8 h-8 p-1 hover:bg-[#23252b] rounded transition-colors flex items-center justify-center", title: "Toggle mute", children: isMuted ? ((0, jsx_runtime_1.jsx)("svg", { className: "volumeButtonIcon_a8e786", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "100%", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M12 3a1 1 0 0 0-1-1h-.06a1 1 0 0 0-.74.32L5.92 7H3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2.92l4.28 4.68a1 1 0 0 0 .74.32H11a1 1 0 0 0 1-1V3ZM22.7 8.3a1 1 0 0 0-1.4 0L19 10.58l-2.3-2.3a1 1 0 1 0-1.4 1.42L17.58 12l-2.3 2.3a1 1 0 0 0 1.42 1.4L19 13.42l2.3 2.3a1 1 0 0 0 1.4-1.42L20.42 12l2.3-2.3a1 1 0 0 0 0-1.4Z", className: "" }) })) : ((0, jsx_runtime_1.jsx)("svg", { width: "100%", height: "100%", viewBox: "0 0 24 24", fill: "#b5bac1", children: (0, jsx_runtime_1.jsx)("path", { d: "M5 9v6h4l5 5V4L9 9H5z" }) })) }), (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
206
+ popoverRef.current = el;
207
+ }, className: `absolute left-1/2 bottom-full volume-popover transition-opacity flex flex-col items-center z-50`, style: {
208
+ transform: "translate(-50%, -2px)",
209
+ width: 14,
210
+ padding: 2,
211
+ opacity: showVolPopover ? 1 : 0,
212
+ pointerEvents: showVolPopover ? "auto" : "none"
213
+ }, children: (0, jsx_runtime_1.jsx)("div", { ref: (el) => {
214
+ volTrackRef.current = el;
215
+ }, onClick: (e) => handleVolPointer(e.clientY), onMouseDown: (e) => {
216
+ cancelHide();
217
+ startDrag(e.nativeEvent);
218
+ }, onTouchStart: (e) => {
219
+ cancelHide();
220
+ startTouchDrag(e.touches[0]);
221
+ }, className: "relative h-28 overflow-visible cursor-pointer flex items-end justify-center", title: "Volume", style: { width: 10 }, children: (0, jsx_runtime_1.jsx)("div", { style: {
222
+ position: "absolute",
223
+ left: "50%",
224
+ transform: "translateX(-50%)",
225
+ bottom: 0,
226
+ width: 6,
227
+ borderRadius: 6,
228
+ background: "#7c5cff",
229
+ height: `${volume * 100}%`
230
+ } }) }) })] })] })] }));
231
+ }
@@ -0,0 +1,3 @@
1
+ export type { ButtonVariant, ButtonProps } from "../types/ui";
2
+ import type { ButtonProps } from "../types/ui";
3
+ export default function Button({ label, url, variant, disabled, emoji, onClick }: ButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = Button;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const variantStyles = {
6
+ primary: "bg-[#5865F2] hover:bg-[#4752C4] text-white",
7
+ secondary: "bg-[#4E5058] hover:bg-[#6D6F78] text-white",
8
+ success: "bg-[#3BA55D] hover:bg-[#2D7D46] text-white",
9
+ danger: "bg-[#ED4245] hover:bg-[#C03537] text-white",
10
+ link: "bg-transparent hover:bg-[#4E5058] text-[#00AFF4]"
11
+ };
12
+ function Button({ label, url, variant = "primary", disabled = false, emoji, onClick }) {
13
+ const baseStyles = "px-4 py-2 rounded text-sm font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2";
14
+ const variantStyle = variantStyles[variant];
15
+ const handleClick = (e) => {
16
+ if (disabled)
17
+ return;
18
+ if (onClick) {
19
+ onClick(e);
20
+ return;
21
+ }
22
+ if (url) {
23
+ window.open(url, "_blank", "noopener,noreferrer");
24
+ }
25
+ };
26
+ return ((0, jsx_runtime_1.jsxs)("button", { className: `${baseStyles} ${variantStyle}`, onClick: handleClick, disabled: disabled, type: "button", children: [emoji && (0, jsx_runtime_1.jsx)("span", { children: emoji }), label] }));
27
+ }
@@ -0,0 +1,7 @@
1
+ import type { MessageProps } from "../types/message";
2
+ export default function ChannelPinnedMessage({ message, referencedMessage, onOpenPinnedMessages, onNavigateToMessage }: {
3
+ message: MessageProps;
4
+ referencedMessage?: Partial<MessageProps> | null;
5
+ onOpenPinnedMessages: () => void;
6
+ onNavigateToMessage?: (id: string) => void;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = ChannelPinnedMessage;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const PinIcon_1 = __importDefault(require("./icons/PinIcon"));
9
+ function ChannelPinnedMessage({ message, referencedMessage, onOpenPinnedMessages, onNavigateToMessage }) {
10
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 py-1 w-full text-base", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-10 shrink-0 flex items-start justify-start mt-0.5 relative", children: (0, jsx_runtime_1.jsx)("div", { className: "w-10 h-10 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(PinIcon_1.default, { className: "text-[#949BA4]", width: 16, height: 16 }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 text-base", children: [(0, jsx_runtime_1.jsx)("span", { onClick: () => referencedMessage && referencedMessage.id && onNavigateToMessage && onNavigateToMessage(String(referencedMessage.id)), className: "font-semibold text-base hover:underline cursor-pointer", style: { color: message.author.color ?? "#FFFFFF" }, children: message.author.username }), (0, jsx_runtime_1.jsx)("span", { className: "text-[#B5BAC1]", children: " pinned " }), (0, jsx_runtime_1.jsx)("span", { onClick: () => referencedMessage && referencedMessage.id && onNavigateToMessage && onNavigateToMessage(String(referencedMessage.id)), className: "text-white hover:underline cursor-pointer", children: "a message" }), (0, jsx_runtime_1.jsx)("span", { className: "text-[#B5BAC1]", children: " to this channel. " }), (0, jsx_runtime_1.jsx)("span", { className: "text-white hover:underline cursor-pointer", onClick: onOpenPinnedMessages, children: "See all pinned messages." })] })] }));
11
+ }
@@ -0,0 +1,3 @@
1
+ export default function DateSeparator({ date }: {
2
+ date: string;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = DateSeparator;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ function DateSeparator({ date }) {
6
+ let display = date;
7
+ try {
8
+ const d = new Date(date);
9
+ if (!isNaN(d.getTime())) {
10
+ display = d.toLocaleDateString("en-US", {
11
+ month: "long",
12
+ day: "numeric",
13
+ year: "numeric"
14
+ });
15
+ }
16
+ }
17
+ catch (e) { }
18
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full flex items-center my-4", children: [(0, jsx_runtime_1.jsx)("hr", { className: "flex-1 border-t border-[#29292d]" }), (0, jsx_runtime_1.jsx)("span", { className: "mx-4 text-sm text-[#72767D] text-center flex-none", children: display }), (0, jsx_runtime_1.jsx)("hr", { className: "flex-1 border-t border-[#29292d]" })] }));
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { EmbedProps } from "../types/embed";
2
+ export default function Embed({ title, description, url, color, timestamp, author, footer, image, thumbnail, fields, buttons, version, resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId, interaction }: EmbedProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = Embed;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const Button_1 = __importDefault(require("./Button"));
10
+ const date_1 = require("./utils/date");
11
+ const markdown_1 = require("./utils/markdown");
12
+ const messageHelpers_1 = require("./messageHelpers");
13
+ function Embed({ title, description, url, color = null, timestamp = null, author = null, footer = null, image = null, thumbnail = null, fields = [], buttons = [], version = "v1", resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId, interaction }) {
14
+ const [brokenImages, setBrokenImages] = react_1.default.useState(new Set());
15
+ const parseWithContext = (value) => (0, markdown_1.parseMarkdown)(value, resolvedUsers, resolvedRoles, resolvedChannels, channelGuildId);
16
+ const imageUrl = typeof image === "string" ? image : image && image.url ? image.url : null;
17
+ const thumbnailUrl = typeof thumbnail === "string" ? thumbnail : thumbnail && thumbnail.url ? thumbnail.url : null;
18
+ const accent = react_1.default.useMemo(() => {
19
+ if (color === null || color === undefined)
20
+ return "#2b2d31";
21
+ const numColor = typeof color === "number" ? color : typeof color === "string" && /^\d+$/.test(color) ? Number(color) : null;
22
+ if (numColor !== null)
23
+ return `#${numColor.toString(16).padStart(6, "0")}`;
24
+ return color || "#2b2d31";
25
+ }, [color]);
26
+ const embedBg = "#2b2d31";
27
+ const formattedFooter = react_1.default.useMemo(() => {
28
+ if (interaction?.name && interaction?.user?.username && !footer?.text) {
29
+ return {
30
+ text: `Requested by ${interaction.user.username}`,
31
+ iconUrl: footer?.iconUrl
32
+ };
33
+ }
34
+ return footer;
35
+ }, [interaction, footer]);
36
+ const handleImageError = (imgUrl) => {
37
+ if (!imgUrl)
38
+ return;
39
+ setBrokenImages((prev) => new Set([...prev, imgUrl]));
40
+ };
41
+ const renderFieldName = (rawName) => {
42
+ const s = (0, messageHelpers_1.sanitizeMarkdownString)(rawName);
43
+ if (!s || typeof s !== "string")
44
+ return parseWithContext(s);
45
+ if (/__/.test(s)) {
46
+ const nodes = [];
47
+ const regex = /__([\s\S]+?)__/g;
48
+ let lastIndex = 0;
49
+ let m;
50
+ while ((m = regex.exec(s)) !== null) {
51
+ if (m.index > lastIndex) {
52
+ nodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: parseWithContext(s.slice(lastIndex, m.index)) }, `seg-${lastIndex}`));
53
+ }
54
+ nodes.push((0, jsx_runtime_1.jsx)("u", { style: { textDecoration: "underline", textDecorationThickness: "1px" }, children: parseWithContext(m[1]) }, `u-${m.index}`));
55
+ lastIndex = regex.lastIndex;
56
+ }
57
+ if (lastIndex < s.length)
58
+ nodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: parseWithContext(s.slice(lastIndex)) }, `seg-${lastIndex}`));
59
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: nodes.map((n, i) => ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: n }, i))) }));
60
+ }
61
+ return parseWithContext(s);
62
+ };
63
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex w-auto max-w-[432px] my-2 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-1 rounded-l-md", style: { backgroundColor: accent } }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 rounded-r-md px-4 py-3", style: { backgroundColor: embedBg }, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-1 space-y-1.5 min-w-0", children: [author && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [author.iconUrl && !brokenImages.has(author.iconUrl) ? ((0, jsx_runtime_1.jsx)("img", { src: author.iconUrl, alt: "", className: "w-5 h-5 rounded-full", onError: () => handleImageError(author.iconUrl) })) : interaction?.name ? ((0, jsx_runtime_1.jsx)("svg", { className: "text-white", "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M2.06 7.61c-.25.95.31 1.92 1.26 2.18l4.3 1.15c.94.25 1.91-.31 2.17-1.26l1.15-4.3c.25-.94-.31-1.91-1.26-2.17l-4.3-1.15c-.94-.25-1.91.31-2.17 1.26l-1.15 4.3ZM12.98 7.87a2 2 0 0 0 1.75 2.95H20a2 2 0 0 0 1.76-2.95l-2.63-4.83a2 2 0 0 0-3.51 0l-2.63 4.83ZM5.86 13.27a.89.89 0 0 1 1.28 0l.75.77a.9.9 0 0 0 .54.26l1.06.12c.5.06.85.52.8 1.02l-.13 1.08c-.02.2.03.42.14.6l.56.92c.27.43.14 1-.28 1.26l-.9.58a.92.92 0 0 0-.37.48l-.36 1.02a.9.9 0 0 1-1.15.57l-1-.36a.89.89 0 0 0-.6 0l-1 .36a.9.9 0 0 1-1.15-.57l-.36-1.02a.92.92 0 0 0-.37-.48l-.9-.58a.93.93 0 0 1-.28-1.26l.56-.93c.11-.17.16-.38.14-.59l-.12-1.08c-.06-.5.3-.96.8-1.02l1.05-.12a.9.9 0 0 0 .54-.26l.75-.77ZM18.52 13.71a1.1 1.1 0 0 0-2.04 0l-.46 1.24c-.19.5-.57.88-1.07 1.07l-1.24.46a1.1 1.1 0 0 0 0 2.04l1.24.46c.5.19.88.57 1.07 1.07l.46 1.24c.35.95 1.7.95 2.04 0l.46-1.24c.19-.5.57-.88 1.07-1.07l1.24-.46a1.1 1.1 0 0 0 0-2.04l-1.24-.46a1.8 1.8 0 0 1-1.07-1.07l-.46-1.24Z" }) })) : null, author.url ? ((0, jsx_runtime_1.jsx)("a", { href: author.url, className: "text-sm font-semibold text-white hover:underline", children: author.name })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-sm font-semibold text-white", children: author.name }))] })), title &&
64
+ (url ? ((0, jsx_runtime_1.jsx)("a", { href: url, className: "text-sky-400 hover:underline font-semibold text-base block", children: parseWithContext((0, messageHelpers_1.sanitizeMarkdownString)(title)) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-sky-400 font-semibold text-base", children: parseWithContext((0, messageHelpers_1.sanitizeMarkdownString)(title)) }))), description ? ((0, jsx_runtime_1.jsx)("div", { className: "text-[14px] leading-[20px] text-[#DBDEE1] whitespace-pre-line break-words", children: parseWithContext((0, messageHelpers_1.sanitizeMarkdownString)(description)) })) : null, fields.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: `grid gap-x-3 gap-y-2 ${fields.some((f) => f.inline) ? "grid-cols-3" : "grid-cols-1"}`, children: fields.map((field, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: field.inline ? "col-span-1" : "col-span-3", children: [typeof window !== "undefined" && window.location.href.includes("localhost")
65
+ ? (() => {
66
+ try {
67
+ const raw = field.name;
68
+ const sanitized = (0, messageHelpers_1.sanitizeMarkdownString)(raw);
69
+ console.debug &&
70
+ console.debug("Embed field.name raw:", raw, "chars:", Array.from(String(raw || "")).map((c) => c.charCodeAt(0)));
71
+ console.debug &&
72
+ console.debug("Embed field.name sanitized:", sanitized, "chars:", Array.from(String(sanitized || "")).map((c) => c.charCodeAt(0)));
73
+ }
74
+ catch (e) { }
75
+ return null;
76
+ })()
77
+ : null, (0, jsx_runtime_1.jsx)("div", { className: "text-xs font-semibold text-white mb-0.5", children: (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: renderFieldName(field.name) }, `fieldname-${idx}`) }), (0, jsx_runtime_1.jsx)("div", { className: "text-[14px] leading-[20px] text-[#DBDEE1] whitespace-pre-line break-words", children: (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: parseWithContext((0, messageHelpers_1.sanitizeMarkdownString)(field.value)) }, `fieldvalue-${idx}`) })] }, idx))) })), imageUrl && !brokenImages.has(imageUrl) ? ((0, jsx_runtime_1.jsx)("div", { className: "mt-1", children: (0, jsx_runtime_1.jsx)("img", { src: imageUrl, alt: "", className: "rounded w-full object-cover", style: { maxHeight: "320px" }, onError: () => handleImageError(imageUrl) }) })) : null, (formattedFooter?.iconUrl || formattedFooter?.text || timestamp) && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-sm text-[#9ca3af]", children: [formattedFooter?.iconUrl && !brokenImages.has(formattedFooter.iconUrl) ? ((0, jsx_runtime_1.jsx)("img", { src: formattedFooter.iconUrl, alt: "", className: "w-5 h-5 rounded-full", onError: () => handleImageError(formattedFooter.iconUrl) })) : null, (0, jsx_runtime_1.jsxs)("span", { children: [formattedFooter?.text, formattedFooter?.text && timestamp && " • ", timestamp && (0, date_1.formatDate)(timestamp)] })] })), buttons.length > 0 && version === "v2" ? ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2 pt-2", children: buttons.map((btn, idx) => ((0, jsx_runtime_1.jsx)(Button_1.default, { ...btn }, idx))) })) : null] }), thumbnailUrl && !brokenImages.has(thumbnailUrl) ? ((0, jsx_runtime_1.jsx)("div", { className: "shrink-0 ml-2", children: (0, jsx_runtime_1.jsx)("img", { src: thumbnailUrl, alt: "", className: "rounded w-20 h-20 object-cover", onError: () => handleImageError(thumbnailUrl) }) })) : null] }) })] }));
78
+ }
@@ -0,0 +1,2 @@
1
+ import type { ForwardedMessageProps } from "../types/props";
2
+ export default function ForwardedMessage({ message, brokenImages, onImageError, renderContent, defaultAvatar }: ForwardedMessageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = ForwardedMessage;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const AudioPlayer_1 = __importDefault(require("./AudioPlayer"));
9
+ const Embed_1 = __importDefault(require("./Embed"));
10
+ const FileAudioIcon_1 = __importDefault(require("./icons/FileAudioIcon"));
11
+ const FileCodeIcon_1 = __importDefault(require("./icons/FileCodeIcon"));
12
+ const FileDocumentIcon_1 = __importDefault(require("./icons/FileDocumentIcon"));
13
+ const messageHelpers_1 = require("./messageHelpers");
14
+ function ForwardedMessage({ message, brokenImages, onImageError, renderContent, defaultAvatar }) {
15
+ const getAttachmentIcon = (kind) => {
16
+ switch (kind) {
17
+ case "audio":
18
+ return FileAudioIcon_1.default;
19
+ case "code":
20
+ return FileCodeIcon_1.default;
21
+ default:
22
+ return FileDocumentIcon_1.default;
23
+ }
24
+ };
25
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "relative mt-2 pl-3 border-l-4", style: { borderColor: "#242427" }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-xs text-[#949BA4] mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", role: "img", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", viewBox: "0 0 24 24", className: "w-4 h-4", children: (0, jsx_runtime_1.jsx)("path", { fill: "var(--text-muted, #949BA4)", d: "M21.7 7.3a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4-1.4L18.58 9H13a7 7 0 0 0-7 7v4a1 1 0 1 1-2 0v-4a9 9 0 0 1 9-9h5.59l-3.3-3.3a1 1 0 0 1 1.42-1.4l5 5Z" }) }), (0, jsx_runtime_1.jsx)("span", { children: "Forwarded" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0 ml-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "mt-1 text-sm text-[#DBDEE1] break-words", children: message.content ? renderContent(message.content) : null }), message.embeds && message.embeds.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mt-2 space-y-2", children: message.embeds.map((e, i) => ((0, jsx_runtime_1.jsx)(Embed_1.default, { ...e }, `fwd-embed-${i}`))) })), message.attachments && message.attachments.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mt-2 flex flex-col gap-2", children: message.attachments.map((a, i) => {
26
+ const url = typeof a === "string" ? a : a?.url || "";
27
+ let filename = typeof a === "string" ? undefined : a?.filename;
28
+ if (!filename)
29
+ filename = (0, messageHelpers_1.extractFilenameFromUrl)(url) || "file";
30
+ const filesize = typeof a === "string" ? "" : (0, messageHelpers_1.formatFileSize)(a?.size, a?.size_human);
31
+ const imageLike = (0, messageHelpers_1.isImageUrl)(url);
32
+ const audioLike = (0, messageHelpers_1.isAudioUrl)(url);
33
+ const isBroken = brokenImages.has(url);
34
+ if (imageLike && !isBroken) {
35
+ return ((0, jsx_runtime_1.jsx)("div", { className: "mb-2 max-w-[520px]", children: (0, jsx_runtime_1.jsx)("img", { src: url, alt: filename, className: `rounded w-full h-auto ${isBroken ? "image-error" : ""}`, onError: () => onImageError(url) }) }, `fwd-att-${i}`));
36
+ }
37
+ if (audioLike) {
38
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(AudioPlayer_1.default, { url: url, filename: filename, filesize: filesize }) }, `fwd-att-audio-${i}`));
39
+ }
40
+ const kind = (0, messageHelpers_1.getAttachmentKind)(filename, url);
41
+ const Icon = getAttachmentIcon(kind);
42
+ return ((0, jsx_runtime_1.jsx)("div", { className: "group relative inline-block max-w-[520px]", children: (0, jsx_runtime_1.jsxs)("a", { href: url, className: "flex items-center gap-3 px-4 py-3 bg-[#1e1f22] hover:bg-[#23252b] border border-[#111214] rounded-lg transition-colors", target: "_blank", rel: "noreferrer", children: [(0, jsx_runtime_1.jsx)(Icon, { className: "h-10 w-8 flex-shrink-0" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-[15px] font-medium text-[#00a8fc] truncate hover:underline", children: filename }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#b5bac1] mt-1", children: filesize })] }), (0, jsx_runtime_1.jsx)("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity", children: (0, jsx_runtime_1.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { fill: "#b5bac1", d: "M12 2a1 1 0 0 1 1 1v10.59l3.3-3.3a1 1 0 1 1 1.4 1.42l-5 5a1 1 0 0 1-1.4 0l-5-5a1 1 0 1 1 1.4-1.42l3.3 3.3V3a1 1 0 0 1 1-1ZM3 20a1 1 0 1 0 0 2h18a1 1 0 1 0 0-2H3Z" }) }) })] }) }, `fwd-att-${i}`));
43
+ }) }))] })] }));
44
+ }
@@ -0,0 +1,2 @@
1
+ import type { MessageProps } from "../types/message";
2
+ export default function Message(props: MessageProps): import("react/jsx-runtime").JSX.Element;