diff --git a/docs/README.md b/docs/README.md
index ddb7208..1a1bcc7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -25,7 +25,7 @@ Your web application, titled **"Unity Chat U1 6.6"**, provides an interactive ch
- **Speech Recognition:** Users can dictate messages through voice input, which captures speech and translates it into textual inputs in real-time.
- **Message Handling:**
- - **Markdown Support:** AI-generated responses utilize Markdown, enhanced with syntax highlighting (via PrismJS) for clarity in code snippets.
+ - **Markdown Support:** AI-generated responses utilize Markdown, enhanced with syntax highlighting (via highlight.js) for clarity in code snippets.
- **Image Embedding:** Automatically embeds images generated by Pollinations based on AI conversation content.
- **Editing and Regeneration:** Users can edit their messages or regenerate AI responses conveniently from within the chat interface.
@@ -88,7 +88,7 @@ Your web application, titled **"Unity Chat U1 6.6"**, provides an interactive ch
---
## **Technical Stack & Dependencies**
-- **Frontend:** HTML, CSS, JavaScript, Bootstrap 5, Font Awesome, PrismJS, Marked.js
+- **Frontend:** HTML, CSS, JavaScript, Bootstrap 5, Font Awesome, highlight.js, Marked.js
- **Backend:** Node.js (Express), cors, fs for file operations
- **Speech & Multimedia:** Web Speech API for speech synthesis and recognition
- **Persistent Storage:** Local Storage and server-side JSON file storage (`userData.json`)
diff --git a/index.html b/index.html
index 98ae4c8..b33a062 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,7 @@
-
+
@@ -466,14 +466,8 @@
Voice Chat
});
}
-
-
-
-
-
-
-
-
+
+
diff --git a/js/chat/chat-init.js b/js/chat/chat-init.js
index 57b89a5..d82bcfb 100644
--- a/js/chat/chat-init.js
+++ b/js/chat/chat-init.js
@@ -13,10 +13,10 @@ document.addEventListener("DOMContentLoaded", () => {
if (newTitle && newTitle !== currentSession.name) Storage.renameSession(currentSession.id, newTitle);
}
};
- const highlightAllCodeBlocks = () => {
- if (!window.Prism) return;
- chatBox.querySelectorAll("pre code").forEach(block => Prism.highlightElement(block));
- };
+ const highlightAllCodeBlocks = () => {
+ if (!window.hljs) return;
+ chatBox.querySelectorAll("pre code").forEach(block => hljs.highlightElement(block));
+ };
const appendMessage = ({ role, content, index, imageUrls = [], audioUrls = [] }) => {
const container = document.createElement("div");
container.classList.add("message");
diff --git a/js/chat/chat-storage.js b/js/chat/chat-storage.js
index 30c9d80..d72f5ec 100644
--- a/js/chat/chat-storage.js
+++ b/js/chat/chat-storage.js
@@ -25,15 +25,15 @@ document.addEventListener("DOMContentLoaded", () => {
}
}
}
- function highlightAllCodeBlocks() {
- if (!window.Prism) {
- return;
- }
- const codeBlocks = chatBox.querySelectorAll("pre code");
- codeBlocks.forEach((block) => {
- Prism.highlightElement(block);
- });
- }
+ function highlightAllCodeBlocks() {
+ if (!window.hljs) {
+ return;
+ }
+ const codeBlocks = chatBox.querySelectorAll("pre code");
+ codeBlocks.forEach((block) => {
+ hljs.highlightElement(block);
+ });
+ }
function appendMessage({ role, content, index, imageUrls = [], audioUrls = [] }) {
const container = document.createElement("div");
container.classList.add("message");
diff --git a/js/ui/ui.js b/js/ui/ui.js
index aef62c3..846d68c 100644
--- a/js/ui/ui.js
+++ b/js/ui/ui.js
@@ -31,20 +31,27 @@ document.addEventListener("DOMContentLoaded", () => {
const clearUserDataBtn = document.getElementById("clear-user-data-btn");
const toggleSimpleModeBtn = document.getElementById("toggle-simple-mode");
- let themeLinkElement = document.getElementById("theme-link");
- if (!themeLinkElement) {
- themeLinkElement = document.createElement("link");
- themeLinkElement.id = "theme-link";
- themeLinkElement.rel = "stylesheet";
- document.head.appendChild(themeLinkElement);
- }
+ let themeLinkElement = document.getElementById("theme-link");
+ if (!themeLinkElement) {
+ themeLinkElement = document.createElement("link");
+ themeLinkElement.id = "theme-link";
+ themeLinkElement.rel = "stylesheet";
+ document.head.appendChild(themeLinkElement);
+ }
+ let hljsThemeLink = document.getElementById("hljs-theme-link");
+ if (!hljsThemeLink) {
+ hljsThemeLink = document.createElement("link");
+ hljsThemeLink.id = "hljs-theme-link";
+ hljsThemeLink.rel = "stylesheet";
+ document.head.appendChild(hljsThemeLink);
+ }
- const allThemes = [
- { value: "light", label: "Light", file: "themes/light.css" },
- { value: "dark", label: "Dark", file: "themes/dark.css" },
- { value: "hacker", label: "Hacker", file: "themes/hacker.css" },
- { value: "oled", label: "OLED Dark", file: "themes/oled.css" },
- { value: "subtle-light", label: "Subtle Light", file: "themes/subtle_light.css" },
+ const allThemes = [
+ { value: "light", label: "Light", file: "themes/light.css" },
+ { value: "dark", label: "Dark", file: "themes/dark.css" },
+ { value: "hacker", label: "Hacker", file: "themes/hacker.css" },
+ { value: "oled", label: "OLED Dark", file: "themes/oled.css" },
+ { value: "subtle-light", label: "Subtle Light", file: "themes/subtle_light.css" },
{ value: "burple", label: "Burple", file: "themes/burple.css" },
{ value: "pretty-pink", label: "Pretty Pink", file: "themes/pretty_pink.css" },
{ value: "nord", label: "Nord", file: "themes/nord.css" },
@@ -61,9 +68,42 @@ document.addEventListener("DOMContentLoaded", () => {
{ value: "ocean-breeze", label: "Ocean Breeze", file: "themes/ocean_breeze.css" },
{ value: "vintage-paper", label: "Vintage Paper", file: "themes/vintage_paper.css" },
{ value: "honeycomb", label: "Honeycomb", file: "themes/honeycomb.css" },
- { value: "rainbow-throwup", label: "Rainbow Throwup", file: "themes/rainbow_throwup.css" },
- { value: "serenity", label: "Serenity", file: "themes/serenity.css" }
- ];
+ { value: "rainbow-throwup", label: "Rainbow Throwup", file: "themes/rainbow_throwup.css" },
+ { value: "serenity", label: "Serenity", file: "themes/serenity.css" }
+ ];
+
+ const hljsThemeMap = {
+ light: "github",
+ dark: "github-dark",
+ hacker: "a11y-dark",
+ oled: "atom-one-dark",
+ "subtle-light": "atom-one-light",
+ burple: "atom-one-dark",
+ "pretty-pink": "github",
+ nord: "nord",
+ "solarized-light": "solarized-light",
+ "solarized-dark": "solarized-dark",
+ "gruvbox-light": "gruvbox-light",
+ "gruvbox-dark": "gruvbox-dark",
+ cyberpunk: "atom-one-dark",
+ dracula: "dracula",
+ monokai: "monokai",
+ "material-dark": "atom-one-dark",
+ "material-light": "atom-one-light",
+ "pastel-dream": "github",
+ "ocean-breeze": "github",
+ "vintage-paper": "github",
+ honeycomb: "github",
+ "rainbow-throwup": "github",
+ serenity: "atom-one-light"
+ };
+
+ const HLJS_BASE = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/";
+
+ function updateHighlightTheme(themeValue) {
+ const hlTheme = hljsThemeMap[themeValue] || "github-dark";
+ hljsThemeLink.href = `${HLJS_BASE}${hlTheme}.min.css`;
+ }
function populateThemeDropdowns() {
themeSelect.innerHTML = "";
@@ -88,8 +128,9 @@ document.addEventListener("DOMContentLoaded", () => {
const savedTheme = localStorage.getItem("selectedTheme") || "dark";
themeSelect.value = savedTheme;
themeSelectSettings.value = savedTheme;
- const found = allThemes.find(t => t.value === savedTheme);
- themeLinkElement.href = found ? found.file : "themes/dark.css";
+ const found = allThemes.find(t => t.value === savedTheme);
+ themeLinkElement.href = found ? found.file : "themes/dark.css";
+ updateHighlightTheme(savedTheme);
}
loadUserTheme();
@@ -97,8 +138,9 @@ document.addEventListener("DOMContentLoaded", () => {
localStorage.setItem("selectedTheme", newThemeValue);
themeSelect.value = newThemeValue;
themeSelectSettings.value = newThemeValue;
- const found = allThemes.find(t => t.value === newThemeValue);
- themeLinkElement.href = found ? found.file : "";
+ const found = allThemes.find(t => t.value === newThemeValue);
+ themeLinkElement.href = found ? found.file : "";
+ updateHighlightTheme(newThemeValue);
}
themeSelect.addEventListener("change", () => {
diff --git a/package-lock.json b/package-lock.json
index 1bf7421..c4a3179 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,9 +6,20 @@
"": {
"name": "unity-chat",
"devDependencies": {
+ "highlight.js": "^11.11.1",
"marked": "^11.2.0"
}
},
+ "node_modules/highlight.js": {
+ "version": "11.11.1",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
+ "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/marked": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-11.2.0.tgz",
diff --git a/package.json b/package.json
index 0b0fdb4..fc72598 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"test": "node tests/run-all.mjs"
},
"devDependencies": {
+ "highlight.js": "^11.11.1",
"marked": "^11.2.0"
}
}
-