Skip to content

Commit ff90a85

Browse files
committed
Adding: Live Code Preview
1 parent 2520217 commit ff90a85

File tree

7 files changed

+82
-6
lines changed

7 files changed

+82
-6
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# OrionChat
2-
OrionChat is a web-based chat interface that simplifies interactions with multiple AI model providers.
2+
OrionChat is a free and open-source web-based chat interface that simplifies interactions with various generative AI providers.
3+
34
It provides a unified platform for chatting and exploring multiple large language models (LLMs), including:
45

56
- 🌐 OpenAI (GPTs and beyond)
@@ -64,6 +65,16 @@ Some companies offer free API access. Check their terms and conditions before yo
6465
- **Anthropic:** [Anthropic API key](https://console.anthropic.com/settings/keys)
6566
- **DeepSeek:** [DeepSeek API Key](https://platform.deepseek.com/api_keys)
6667
- **Hyperbolic:** [Hyperbolic API Key](https://app.hyperbolic.xyz/settings#api-key)
68+
69+
### Live Code Preview for HTML/CSS/JS
70+
71+
OrionChat can now render HTML, CSS, and JavaScript code snippets directly within the chat interface.
72+
![Live Code Preview Screenshot](imgs/screenshot_code_preview.jpg "Live Code Preview Screenshot")
73+
74+
When the AI generates a code block containing these languages, a "Preview" button will appear, allowing you to instantly
75+
see the visual result without having to download the code.
76+
77+
6778
# Special Commands
6879
Use special commands to perform an action quickly and easily.
6980

css/chat.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ code.hljs::-webkit-scrollbar-track {
551551
margin-top: -33px;
552552
}
553553

554-
.copy-btn, .down-btn, .see_info {
554+
.copy-btn, .down-btn, .see_info, .preview-btn {
555555
padding: 3px 5px;
556556
color: var(--copy-btn-color);
557557
background-color: transparent;
@@ -562,9 +562,12 @@ code.hljs::-webkit-scrollbar-track {
562562
}
563563

564564

565-
.btn-group .copy-btn, .btn-group .down-btn {
565+
.btn-group .copy-btn, .btn-group .down-btn,.preview-btn {
566566
background-color: var(--copy-btn-bg);
567567
}
568+
.preview-btn{
569+
border: 1px solid #FFEB3B;
570+
}
568571

569572

570573
.btn-ft-group .copy-btn, .see_info {

experiments/preview/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<script src="../../js/preview.js?v=1.0.2"></script>
4+
</html>

imgs/screenshot_code_preview.jpg

25.1 KB
Loading

index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</script>
1212
<link rel="icon" href="favicon.png">
1313
<link rel="stylesheet" href="css/highlight_js/themes/github-dark-dimmed.css?v=1.0.3">
14-
<link rel="stylesheet" href="css/chat.css?v=3.2.1">
14+
<link rel="stylesheet" href="css/chat.css?v=3.2.4">
1515
<link rel="manifest" href="manifest.json">
1616
<meta property="og:type" content="article">
1717
<meta property="og:title" content="OrionChat">
@@ -77,7 +77,7 @@
7777
<script src="js/4devs.js?v=1.0.1"></script>
7878
<script src="js/prompts.js?v=1.1.0"></script>
7979
<script src="js/tools_list.js?v=1.2.0"></script>
80-
<script src="js/script.js?v=3.2.3"></script>
80+
<script src="js/script.js?v=3.2.6"></script>
8181
<script src="js/search_chats.js?v=0.0.3"></script>
8282
<script src="js/voice_rec.js?v=1.0.6"></script>
8383
<script src="js/nuggets.js?v=0.0.1"></script>

js/preview.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
let preview = localStorage.getItem('preview');
2+
if (preview) {
3+
document.open();
4+
document.write(preview);
5+
document.close();
6+
}

js/script.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ const language_extension = {
168168
"python": "py",
169169
"markdown": "md",
170170
"javascript": "js",
171+
"js": "js",
171172
"java": "java",
172173
"c": "c",
173174
"cpp": "cpp",
@@ -887,6 +888,7 @@ function enableCopyForCode(enable_down_too = true) {
887888

888889
document.querySelectorAll('pre code').forEach(block => {
889890
let block_group = block.previousElementSibling;
891+
890892
let has_copy_btn = false;
891893
if (block_group) {
892894
has_copy_btn = block_group.querySelector(".copy-btn");
@@ -899,10 +901,19 @@ function enableCopyForCode(enable_down_too = true) {
899901
button.innerText = 'Copy';
900902
button.title = "Copy code";
901903
const btn_down = button.cloneNode(false);
904+
const btn_preview = button.cloneNode(false);
902905
btn_down.className = 'down-btn';
903906
btn_down.innerText = 'Down';
904907
btn_down.title = "Download code";
908+
909+
btn_preview.className = 'preview-btn';
910+
btn_preview.innerText = 'Preview';
911+
btn_preview.title = "Preview code";
905912
div_ele.append(button);
913+
if(block.classList.contains('html')) {
914+
btn_preview.setAttribute('onclick', "savePreviewCode(event)");
915+
div_ele.append(btn_preview)
916+
}
906917
if (enable_down_too) {
907918
div_ele.append(btn_down);
908919
}
@@ -3505,6 +3516,47 @@ function goNuggets(){
35053516
document.location.href = 'experiments/nuggets.html';
35063517
}
35073518

3519+
3520+
3521+
3522+
function savePreviewCode(event){
3523+
let chat_box = event.target.parentElement.parentElement.parentElement;
3524+
let html_target = event.target.parentElement.parentElement;
3525+
let html_code_to_preview = document.createElement('div');
3526+
html_code_to_preview.innerHTML = html_target.querySelector(".html").innerText;
3527+
let css_elements = html_code_to_preview.querySelectorAll("[rel='stylesheet']");
3528+
let js_elements = html_code_to_preview.querySelectorAll('script[src]');
3529+
let css_idx = 0;
3530+
let js_idx = 0;
3531+
chat_box.querySelectorAll(".css").forEach(css=>{
3532+
let css_ele = css_elements[css_idx] ?? '';
3533+
if(css_ele){
3534+
let style_tag = document.createElement('style');
3535+
style_tag.innerHTML = css.innerText;
3536+
css_ele.after(style_tag);
3537+
css_ele.remove();
3538+
3539+
}
3540+
css_idx++;
3541+
});
3542+
3543+
chat_box.querySelectorAll(".language-javascript").forEach(js=>{
3544+
let js_ele = js_elements[js_idx] ?? '';
3545+
if(js_ele){
3546+
let script_tag = document.createElement('script');
3547+
script_tag.textContent = js.innerText;
3548+
js_ele.after(script_tag);
3549+
js_ele.remove();
3550+
3551+
}
3552+
js_idx++;
3553+
});
3554+
localStorage.setItem('preview', html_code_to_preview.innerHTML);
3555+
window.open('experiments/preview','_blank');
3556+
3557+
}
3558+
3559+
35083560
let theme_toggle_button = document.querySelector("#theme_toggle");
35093561
theme_toggle_button.onclick = () => {
35103562
themeToggle();
@@ -3527,4 +3579,4 @@ let new_url = document.URL;
35273579
new_url = new_url.split('?')[0];
35283580
new_url = new_url.split("#")[0];
35293581
new_url += "#" + chat_id;
3530-
history.pushState({url: new_url}, '', new_url);
3582+
history.pushState({url: new_url}, '', new_url);

0 commit comments

Comments
 (0)