Update.
This commit is contained in:
parent
fef652eb36
commit
58e9d92656
@ -4,6 +4,11 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Chat Hub</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@ -110,6 +115,7 @@
|
||||
.channel-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.channel-item,
|
||||
@ -239,6 +245,12 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
chat-messages {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* Chat Header */
|
||||
.chat-header {
|
||||
padding: 1rem;
|
||||
@ -304,6 +316,7 @@
|
||||
|
||||
.message-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.message-header {
|
||||
@ -328,6 +341,50 @@
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Markdown Content Styling */
|
||||
.message-text p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-text a {
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
.message-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.message-text pre {
|
||||
background: var(--surface-light);
|
||||
border-radius: 4px;
|
||||
padding: 1rem;
|
||||
margin: 0.5rem 0;
|
||||
overflow-x: auto;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.message-text code:not(pre > code) {
|
||||
background: var(--surface-light);
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
|
||||
.message-text blockquote {
|
||||
border-left: 4px solid var(--border);
|
||||
padding-left: 1rem;
|
||||
margin: 0.5rem 0;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
|
||||
.message-text ul, .message-text ol {
|
||||
padding-left: 1.5rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.message-actions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
@ -602,10 +659,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<!-- Sidebar Component -->
|
||||
<chat-sidebar></chat-sidebar>
|
||||
|
||||
<!-- Main Chat Area -->
|
||||
<div class="main-content">
|
||||
<chat-header></chat-header>
|
||||
<chat-messages></chat-messages>
|
||||
@ -613,7 +668,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Component -->
|
||||
<chat-modal></chat-modal>
|
||||
|
||||
<script>
|
||||
@ -622,6 +676,17 @@
|
||||
const WS_URL = `${window.location.protocol.replace("http", "ws")}//${window.location.host}/ws`;
|
||||
const currentUser = {{ current_user | tojson }};
|
||||
|
||||
// Configure Markdown parser and syntax highlighting
|
||||
marked.setOptions({
|
||||
highlight: function(code, lang) {
|
||||
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
|
||||
return hljs.highlight(code, { language, ignoreIllegals: true }).value;
|
||||
},
|
||||
langPrefix: 'hljs language-', // for CSS classes
|
||||
gfm: true,
|
||||
breaks: true,
|
||||
});
|
||||
|
||||
// Global Event Bus
|
||||
class EventBus {
|
||||
constructor() {
|
||||
@ -992,12 +1057,6 @@
|
||||
});
|
||||
|
||||
// Helper Functions
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement("div");
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function formatTime(timestamp) {
|
||||
const date = new Date(timestamp);
|
||||
const now = new Date();
|
||||
@ -1280,14 +1339,14 @@
|
||||
}
|
||||
|
||||
createMessage(message) {
|
||||
const isOwn =
|
||||
currentUser &&
|
||||
message.author?.id === currentUser.id;
|
||||
const author = message.author || {
|
||||
username: message.username,
|
||||
avatar_color: message.avatar_b,
|
||||
};
|
||||
|
||||
// Parse and sanitize markdown content
|
||||
const sanitizedHtmlContent = DOMPurify.sanitize(marked.parse(message.content));
|
||||
|
||||
return `
|
||||
<div class="message" data-message-id="${message.id || message.uid}">
|
||||
<div class="message-avatar" style="background: #${author.avatar_color}">
|
||||
@ -1298,7 +1357,7 @@
|
||||
<span class="message-author">${author.username}</span>
|
||||
<span class="message-timestamp">${formatTime(message.timestamp || message.created_at)}</span>
|
||||
</div>
|
||||
<div class="message-text">${escapeHtml(message.content)}</div>
|
||||
<div class="message-text">${sanitizedHtmlContent}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -1359,7 +1418,7 @@
|
||||
<textarea
|
||||
class="message-input"
|
||||
id="messageInput"
|
||||
placeholder="Type a message..."
|
||||
placeholder="Type a message... (Markdown supported)"
|
||||
rows="1"
|
||||
></textarea>
|
||||
<div class="input-actions">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user