mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
Compare commits
2 Commits
2c17c83253
...
a822d94317
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a822d94317 | ||
|
|
db6915f53f |
@@ -113,11 +113,12 @@ main {
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* Message footer for own messages (time below bubble) */
|
||||
/* Message footer for own messages (name + time above bubble) */
|
||||
.message-footer {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
padding-right: 0.5rem;
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.message-footer.own {
|
||||
@@ -129,6 +130,13 @@ main {
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.message-footer .message-sender.own {
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
color: #084298;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
/* Message action buttons container */
|
||||
.message-actions {
|
||||
display: flex;
|
||||
@@ -680,6 +688,12 @@ main {
|
||||
border-left-color: #084298;
|
||||
}
|
||||
|
||||
/* Large Emoji for emoji-only messages */
|
||||
.emoji-large {
|
||||
font-size: 2.5rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Clickable Links in Messages */
|
||||
.message-link {
|
||||
color: #0d6efd;
|
||||
|
||||
@@ -728,6 +728,7 @@ function createMessageElement(msg) {
|
||||
wrapper.innerHTML = `
|
||||
<div class="message-container">
|
||||
<div class="message-footer own">
|
||||
<span class="message-sender own">${escapeHtml(msg.sender)}</span>
|
||||
<span class="message-time">${time}</span>
|
||||
</div>
|
||||
<div class="message own">
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
function processMessageContent(content) {
|
||||
if (!content) return '';
|
||||
|
||||
// Check if content (minus mentions) is emoji-only BEFORE any processing
|
||||
const emojiOnlyInfo = checkEmojiOnlyContent(content);
|
||||
|
||||
// First escape HTML to prevent XSS
|
||||
let processed = escapeHtml(content);
|
||||
|
||||
@@ -27,9 +30,58 @@ function processMessageContent(content) {
|
||||
// 4. Convert URLs to links (and images to thumbnails)
|
||||
processed = processUrls(processed);
|
||||
|
||||
// 5. If emoji-only, enlarge the emoji
|
||||
if (emojiOnlyInfo.isEmojiOnly) {
|
||||
processed = enlargeEmoji(processed, emojiOnlyInfo.hasMention);
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if content is emoji-only (excluding @[mentions])
|
||||
* @param {string} text - Raw message content
|
||||
* @returns {object} - { isEmojiOnly: boolean, hasMention: boolean }
|
||||
*/
|
||||
function checkEmojiOnlyContent(text) {
|
||||
const hasMention = /@\[[^\]]+\]/.test(text);
|
||||
|
||||
// Remove @[...] patterns
|
||||
const withoutMentions = text.replace(/@\[[^\]]+\]/g, '').trim();
|
||||
|
||||
if (!withoutMentions) {
|
||||
return { isEmojiOnly: false, hasMention };
|
||||
}
|
||||
|
||||
// Check if remaining is only emoji (using Unicode Extended_Pictographic)
|
||||
// Matches emoji, modifiers, skin tones, ZWJ sequences, variation selectors, and whitespace
|
||||
const emojiRegex = /^[\p{Extended_Pictographic}\p{Emoji_Modifier}\p{Emoji_Modifier_Base}\p{Emoji_Component}\uFE0F\u200D\s]+$/u;
|
||||
const isEmojiOnly = emojiRegex.test(withoutMentions);
|
||||
|
||||
return { isEmojiOnly, hasMention };
|
||||
}
|
||||
|
||||
/**
|
||||
* Enlarge emoji in processed HTML
|
||||
* @param {string} html - Processed HTML with mention badges
|
||||
* @param {boolean} hasMention - Whether content has mentions
|
||||
* @returns {string} - HTML with enlarged emoji
|
||||
*/
|
||||
function enlargeEmoji(html, hasMention) {
|
||||
if (hasMention) {
|
||||
// Add line break after mention badge, then wrap emoji in large class
|
||||
// Pattern: closing </span> of mention badge, optional whitespace, then emoji
|
||||
html = html.replace(
|
||||
/(<\/span>)\s*([\p{Extended_Pictographic}\p{Emoji_Modifier}\p{Emoji_Modifier_Base}\p{Emoji_Component}\uFE0F\u200D\s]+)$/u,
|
||||
'$1<br><span class="emoji-large">$2</span>'
|
||||
);
|
||||
} else {
|
||||
// Just wrap everything in large emoji class
|
||||
html = `<span class="emoji-large">${html}</span>`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert @[Username] mentions to styled badges
|
||||
* @param {string} text - HTML-escaped text
|
||||
@@ -77,8 +129,8 @@ function processChannelLinks(text) {
|
||||
* @returns {string} - Text with styled quotes
|
||||
*/
|
||||
function processQuotes(text) {
|
||||
// Match »...« pattern (guillemets)
|
||||
const quotePattern = /»([^«]+)«/g;
|
||||
// Match »...« pattern (guillemets) including optional trailing whitespace
|
||||
const quotePattern = /»([^«]+)«\s*/g;
|
||||
|
||||
return text.replace(quotePattern, (_match, quoted) => {
|
||||
// Display without guillemets (styling is enough) + line break after
|
||||
|
||||
Reference in New Issue
Block a user