Update.
This commit is contained in:
parent
fef652eb36
commit
58e9d92656
@ -4,6 +4,11 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Chat Hub</title>
|
<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>
|
<style>
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -110,6 +115,7 @@
|
|||||||
.channel-list {
|
.channel-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-item,
|
.channel-item,
|
||||||
@ -239,6 +245,12 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chat-messages {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Chat Header */
|
/* Chat Header */
|
||||||
.chat-header {
|
.chat-header {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@ -304,6 +316,7 @@
|
|||||||
|
|
||||||
.message-content {
|
.message-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-header {
|
.message-header {
|
||||||
@ -328,6 +341,50 @@
|
|||||||
word-wrap: break-word;
|
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 {
|
.message-actions {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -602,10 +659,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- Sidebar Component -->
|
|
||||||
<chat-sidebar></chat-sidebar>
|
<chat-sidebar></chat-sidebar>
|
||||||
|
|
||||||
<!-- Main Chat Area -->
|
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<chat-header></chat-header>
|
<chat-header></chat-header>
|
||||||
<chat-messages></chat-messages>
|
<chat-messages></chat-messages>
|
||||||
@ -613,7 +668,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal Component -->
|
|
||||||
<chat-modal></chat-modal>
|
<chat-modal></chat-modal>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -622,6 +676,17 @@
|
|||||||
const WS_URL = `${window.location.protocol.replace("http", "ws")}//${window.location.host}/ws`;
|
const WS_URL = `${window.location.protocol.replace("http", "ws")}//${window.location.host}/ws`;
|
||||||
const currentUser = {{ current_user | tojson }};
|
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
|
// Global Event Bus
|
||||||
class EventBus {
|
class EventBus {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -992,12 +1057,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Helper Functions
|
// Helper Functions
|
||||||
function escapeHtml(text) {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.textContent = text;
|
|
||||||
return div.innerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatTime(timestamp) {
|
function formatTime(timestamp) {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@ -1280,14 +1339,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
createMessage(message) {
|
createMessage(message) {
|
||||||
const isOwn =
|
|
||||||
currentUser &&
|
|
||||||
message.author?.id === currentUser.id;
|
|
||||||
const author = message.author || {
|
const author = message.author || {
|
||||||
username: message.username,
|
username: message.username,
|
||||||
avatar_color: message.avatar_b,
|
avatar_color: message.avatar_b,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Parse and sanitize markdown content
|
||||||
|
const sanitizedHtmlContent = DOMPurify.sanitize(marked.parse(message.content));
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="message" data-message-id="${message.id || message.uid}">
|
<div class="message" data-message-id="${message.id || message.uid}">
|
||||||
<div class="message-avatar" style="background: #${author.avatar_color}">
|
<div class="message-avatar" style="background: #${author.avatar_color}">
|
||||||
@ -1298,7 +1357,7 @@
|
|||||||
<span class="message-author">${author.username}</span>
|
<span class="message-author">${author.username}</span>
|
||||||
<span class="message-timestamp">${formatTime(message.timestamp || message.created_at)}</span>
|
<span class="message-timestamp">${formatTime(message.timestamp || message.created_at)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-text">${escapeHtml(message.content)}</div>
|
<div class="message-text">${sanitizedHtmlContent}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -1359,7 +1418,7 @@
|
|||||||
<textarea
|
<textarea
|
||||||
class="message-input"
|
class="message-input"
|
||||||
id="messageInput"
|
id="messageInput"
|
||||||
placeholder="Type a message..."
|
placeholder="Type a message... (Markdown supported)"
|
||||||
rows="1"
|
rows="1"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="input-actions">
|
<div class="input-actions">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user