mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-18 20:17:50 +00:00
enhanced
This commit is contained in:
parent
a631f73da1
commit
70291fcd8e
@ -1 +1 @@
|
||||
Subproject commit 1437b2c40d28e40b2e9965fac399e30f46f1e1a2
|
||||
Subproject commit 205ec5b01536b3c1647f15fbd3220d55b809e2bb
|
3911
web/dist/assets/index-156a33f2.js
vendored
3911
web/dist/assets/index-156a33f2.js
vendored
File diff suppressed because one or more lines are too long
8
web/dist/assets/index-16450776.css
vendored
Normal file
8
web/dist/assets/index-16450776.css
vendored
Normal file
File diff suppressed because one or more lines are too long
8
web/dist/assets/index-4cfc40d0.css
vendored
8
web/dist/assets/index-4cfc40d0.css
vendored
File diff suppressed because one or more lines are too long
3906
web/dist/assets/index-cafbd2e3.js
vendored
Normal file
3906
web/dist/assets/index-cafbd2e3.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
web/dist/index.html
vendored
6
web/dist/index.html
vendored
@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LoLLMS WebUI</title>
|
||||
<script type="module" crossorigin src="/assets/index-156a33f2.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-4cfc40d0.css">
|
||||
<script type="module" crossorigin src="/assets/index-cafbd2e3.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-16450776.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LoLLMS WebUI</title>
|
||||
</head>
|
||||
|
42
web/package-lock.json
generated
42
web/package-lock.json
generated
@ -21,7 +21,9 @@
|
||||
"markdown-it-emoji": "^2.0.2",
|
||||
"markdown-it-implicit-figures": "^0.11.0",
|
||||
"markdown-it-math": "^4.1.1",
|
||||
"markdown-it-mathjax": "^2.0.0",
|
||||
"markdown-it-multimd-table": "^4.2.3",
|
||||
"mathjax": "^3.2.2",
|
||||
"mermaid": "^9.0.0",
|
||||
"papaparse": "^5.4.1",
|
||||
"prismjs": "^1.29.0",
|
||||
@ -1123,11 +1125,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -1866,14 +1868,14 @@
|
||||
"integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ=="
|
||||
},
|
||||
"node_modules/engine.io-client": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz",
|
||||
"integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==",
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz",
|
||||
"integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.2.1",
|
||||
"ws": "~8.11.0",
|
||||
"ws": "~8.17.1",
|
||||
"xmlhttprequest-ssl": "~2.0.0"
|
||||
}
|
||||
},
|
||||
@ -2234,9 +2236,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@ -2815,11 +2817,21 @@
|
||||
"ascii2mathml": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-mathjax": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-mathjax/-/markdown-it-mathjax-2.0.0.tgz",
|
||||
"integrity": "sha512-Fafv7TnMENccWYTNjMZzV4BzONPxpK9Mknr1iMEK6m7PI5a5UTCOFctPzx7Nhv81fFzYEY8WHDkSu9n43fTV9g=="
|
||||
},
|
||||
"node_modules/markdown-it-multimd-table": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-4.2.3.tgz",
|
||||
"integrity": "sha512-KepCr2OMJqm7IT6sOIbuqHGe+NERhgy66XMrc5lo6dHW7oaPzMDtYwR1EGwK16/blb6mCSg4jqityOe0o/H7HA=="
|
||||
},
|
||||
"node_modules/mathjax": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-3.2.2.tgz",
|
||||
"integrity": "sha512-Bt+SSVU8eBG27zChVewOicYs7Xsdt40qm4+UpHyX7k0/O9NliPc+x77k1/FEsPsjKPZGJvtRZM1vO+geW0OhGw=="
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
@ -3986,15 +3998,15 @@
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
|
@ -23,7 +23,9 @@
|
||||
"markdown-it-emoji": "^2.0.2",
|
||||
"markdown-it-implicit-figures": "^0.11.0",
|
||||
"markdown-it-math": "^4.1.1",
|
||||
"markdown-it-mathjax": "^2.0.0",
|
||||
"markdown-it-multimd-table": "^4.2.3",
|
||||
"mathjax": "^3.2.2",
|
||||
"mermaid": "^9.0.0",
|
||||
"papaparse": "^5.4.1",
|
||||
"prismjs": "^1.29.0",
|
||||
|
@ -1,35 +1,5 @@
|
||||
<template>
|
||||
<div class="bg-bg-light-tone-panel dark:bg-bg-dark-tone-panel p-2 rounded-lg shadow-sm">
|
||||
<div class="flex flex-row bg-bg-light-tone-panel dark:bg-bg-dark-tone-panel p-2 rounded-lg shadow-sm">
|
||||
<span class="text-2xl">{{ language }}</span>
|
||||
<button @click="copyCode" title="copy"
|
||||
:class="isCopied ? 'bg-green-500' : 'bg-bg-dark-tone-panel dark:bg-bg-dark-tone'"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
|
||||
<i data-feather="copy"></i>
|
||||
</button>
|
||||
<button v-if="['function', 'python', 'sh', 'shell', 'bash', 'cmd', 'powershell', 'latex', 'mermaid', 'graphviz', 'dot', 'javascript', 'html', 'html5', 'svg'].includes(language)" ref="btn_code_exec" @click="executeCode" title="execute"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200"
|
||||
:class="isExecuting?'bg-green-500':''">
|
||||
<i data-feather="play-circle"></i>
|
||||
</button>
|
||||
<button v-if="['airplay', 'mermaid', 'graphviz', 'dot', 'javascript', 'html', 'html5', 'svg', 'css'].includes(language)" ref="btn_code_exec_in_new_tab" @click="executeCode_in_new_tab" title="execute"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200"
|
||||
:class="isExecuting?'bg-green-500':''">
|
||||
<i data-feather="airplay"></i>
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolder" title="open code project folder"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
|
||||
<i data-feather="folder"></i>
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolderVsCode" title="open code project folder in vscode"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
|
||||
<img src="@/assets/vscode_black.svg" width="25" height="25">
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openVsCode" title="open code in vscode"
|
||||
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
|
||||
<img src="@/assets/vscode.svg" width="25" height="25">
|
||||
</button>
|
||||
</div>
|
||||
<pre class="hljs p-1 rounded-md break-all grid grid-cols-1">
|
||||
<div class="code-container">
|
||||
<div
|
||||
@ -41,6 +11,41 @@
|
||||
</div>
|
||||
|
||||
</pre>
|
||||
<div class="flex flex-row bg-bg-light-tone-panel dark:bg-bg-dark-tone-panel p-2 rounded-lg shadow-sm">
|
||||
<span class="text-2xl mr-2">{{ language }}</span>
|
||||
<button @click="copyCode"
|
||||
:title="isCopied ? 'Copied!' : 'Copy code'"
|
||||
:class="isCopied ? 'bg-green-500' : ''"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
>
|
||||
<i data-feather="copy"></i>
|
||||
</button>
|
||||
<button v-if="['function', 'python', 'sh', 'shell', 'bash', 'cmd', 'powershell', 'latex', 'mermaid', 'graphviz', 'dot', 'javascript', 'html', 'html5', 'svg'].includes(language)" ref="btn_code_exec" @click="executeCode" title="execute"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
:class="isExecuting?'bg-green-500':''">
|
||||
<i data-feather="play-circle"></i>
|
||||
</button>
|
||||
<button v-if="['airplay', 'mermaid', 'graphviz', 'dot', 'javascript', 'html', 'html5', 'svg', 'css'].includes(language)" ref="btn_code_exec_in_new_tab" @click="executeCode_in_new_tab" title="execute"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
:class="isExecuting?'bg-green-500':''">
|
||||
<i data-feather="airplay"></i>
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolder" title="open code project folder"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
>
|
||||
<i data-feather="folder"></i>
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openFolderVsCode" title="open code project folder in vscode"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
>
|
||||
<img src="@/assets/vscode_black.svg" width="25" height="25">
|
||||
</button>
|
||||
<button v-if="['python', 'latex', 'html'].includes(language)" @click="openVsCode" title="open code in vscode"
|
||||
class="px-2 py-1 mr-2 mb-2 text-left text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white transition-colors duration-200"
|
||||
>
|
||||
<img src="@/assets/vscode.svg" width="25" height="25">
|
||||
</button>
|
||||
</div>
|
||||
<span v-if="executionOutput" class="text-2xl">Execution output</span>
|
||||
<pre class="hljs mt-0 p-1 rounded-md break-all grid grid-cols-1" v-if="executionOutput">
|
||||
<div class="container h-[200px] overflow-x-auto break-all scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="break-all container w-full" >
|
||||
<div class="break-all container w-full">
|
||||
<div ref="mdRender" class="markdown-content">
|
||||
<div v-for="(item, index) in markdownItems" :key="index">
|
||||
<code-block
|
||||
@ -10,6 +10,7 @@
|
||||
:discussion_id="discussion_id"
|
||||
:message_id="message_id"
|
||||
:client_id="client_id"
|
||||
@update-code="updateCode(index, $event)"
|
||||
></code-block>
|
||||
<div v-else v-html="item.html"></div>
|
||||
</div>
|
||||
@ -18,12 +19,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {nextTick, ref, onMounted, watch } from 'vue';
|
||||
import { nextTick, ref, onMounted, watch } from 'vue';
|
||||
import feather from 'feather-icons';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
import emoji from 'markdown-it-emoji';
|
||||
import anchor from 'markdown-it-anchor';
|
||||
import MarkdownItMath from 'markdown-it-math';
|
||||
import MarkdownItMultimdTable from 'markdown-it-multimd-table';
|
||||
import implicitFigures from 'markdown-it-implicit-figures';
|
||||
import 'highlight.js/styles/tomorrow-night-blue.css';
|
||||
@ -31,8 +31,7 @@ import 'highlight.js/styles/tokyo-night-dark.css';
|
||||
import attrs from 'markdown-it-attrs';
|
||||
import CodeBlock from './CodeBlock.vue';
|
||||
import hljs from 'highlight.js';
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
import mathjax from 'markdown-it-mathjax';
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
@ -42,6 +41,7 @@ function escapeHtml(unsafe) {
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'MarkdownRenderer',
|
||||
props: {
|
||||
@ -49,11 +49,11 @@ export default {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "http://localhost:9600",
|
||||
},
|
||||
},
|
||||
client_id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
markdownText: {
|
||||
type: String,
|
||||
required: true,
|
||||
@ -88,13 +88,7 @@ export default {
|
||||
figcaption: true,
|
||||
})
|
||||
.use(attrs)
|
||||
.use(MarkdownItMath, {
|
||||
inlineOpen: '$',
|
||||
inlineClose: '$',
|
||||
blockOpen: '$$',
|
||||
blockClose: '$$',
|
||||
})
|
||||
.use(MarkdownItMultimdTable,{
|
||||
.use(MarkdownItMultimdTable, {
|
||||
enableRowspan: true,
|
||||
enableColspan: true,
|
||||
enableGridTables: true,
|
||||
@ -106,44 +100,43 @@ export default {
|
||||
multilineCellEndMarker: '<|',
|
||||
multilineCellPadding: ' ',
|
||||
multilineCellJoiner: '\n',
|
||||
});
|
||||
})
|
||||
.use(mathjax({
|
||||
inlineMath: [['$', '$'], ['\\(', '\\)']],
|
||||
blockMath: [['$$', '$$'], ['\\[', '\\]']]
|
||||
}));
|
||||
|
||||
const markdownItems = ref([]);
|
||||
const updateMarkdown = () => {
|
||||
if (props.markdownText) {
|
||||
let tokens = md.parse(props.markdownText, {});
|
||||
let cumulated = [];
|
||||
markdownItems.value = []
|
||||
markdownItems.value = [];
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].type !== 'fence') {
|
||||
cumulated.push(tokens[i]);
|
||||
}
|
||||
else{
|
||||
if(cumulated.length>0){
|
||||
markdownItems.value.push(
|
||||
{
|
||||
} else {
|
||||
if (cumulated.length > 0) {
|
||||
markdownItems.value.push({
|
||||
type: 'html',
|
||||
html: md.renderer.render(cumulated, md.options, {}),
|
||||
});
|
||||
cumulated = []
|
||||
cumulated = [];
|
||||
}
|
||||
markdownItems.value.push(
|
||||
{
|
||||
type: 'code',
|
||||
language: escapeHtml(tokens[i].info),
|
||||
code: tokens[i].content,
|
||||
}
|
||||
)
|
||||
markdownItems.value.push({
|
||||
type: 'code',
|
||||
language: escapeHtml(tokens[i].info),
|
||||
code: tokens[i].content,
|
||||
});
|
||||
}
|
||||
}
|
||||
if(cumulated.length>0){
|
||||
markdownItems.value.push(
|
||||
{
|
||||
if (cumulated.length > 0) {
|
||||
markdownItems.value.push({
|
||||
type: 'html',
|
||||
html: md.renderer.render(cumulated, md.options, {}),
|
||||
});
|
||||
cumulated = []
|
||||
cumulated = [];
|
||||
}
|
||||
|
||||
} else {
|
||||
markdownItems.value = [];
|
||||
}
|
||||
@ -151,14 +144,25 @@ export default {
|
||||
feather.replace();
|
||||
});
|
||||
};
|
||||
watch(() => props.markdownText, updateMarkdown);
|
||||
onMounted(updateMarkdown);
|
||||
return { markdownItems };
|
||||
},
|
||||
|
||||
const updateCode = (index, newCode) => {
|
||||
markdownItems.value[index].code = newCode;
|
||||
};
|
||||
|
||||
watch(() => props.markdownText, updateMarkdown);
|
||||
onMounted(() => {
|
||||
updateMarkdown();
|
||||
nextTick(() => {
|
||||
if (window.MathJax) {
|
||||
window.MathJax.typesetPromise();
|
||||
}
|
||||
});
|
||||
});
|
||||
return { markdownItems, updateCode };
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Your existing styles */
|
||||
</style>
|
||||
|
||||
|
@ -31,141 +31,7 @@
|
||||
<div class="flex-grow ">
|
||||
|
||||
</div>
|
||||
<!-- MESSAGE CONTROLS -->
|
||||
<div class="flex-row justify-end mx-2">
|
||||
<div class="invisible group-hover:visible flex flex-row ">
|
||||
<!-- MESSAGE CONTROLS -->
|
||||
<!-- EDIT CONFIRMATION -->
|
||||
<div v-if="editMsgMode" class="flex items-center duration-75">
|
||||
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||
title="Cancel edit" type="button" @click.stop="editMsgMode = false">
|
||||
<i data-feather="x"></i>
|
||||
</button>
|
||||
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2"
|
||||
title="Update message" type="button" @click.stop="updateMessage">
|
||||
<i data-feather="check"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div v-if="!editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Edit message" @click.stop="editMsgMode = true">
|
||||
<i data-feather="edit"></i>
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer hover:border-2"
|
||||
title="Add generic block" @click.stop="addBlock('')">
|
||||
<img :src="code_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer hover:border-2"
|
||||
title="Add python block" @click.stop="addBlock('python')">
|
||||
<img :src="python_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add javascript block" @click.stop="addBlock('javascript')">
|
||||
<img :src="javascript_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add json block" @click.stop="addBlock('json')">
|
||||
<img :src="json_block" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add c++ block" @click.stop="addBlock('c++')">
|
||||
<img :src="cpp_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add html block" @click.stop="addBlock('html')">
|
||||
<img :src="html5_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add LaTex block" @click.stop="addBlock('latex')">
|
||||
<img :src="LaTeX_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add bash block" @click.stop="addBlock('bash')">
|
||||
<img :src="bash_block" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Copy message to clipboard" @click.stop="copyContentToClipboard()">
|
||||
<i data-feather="copy"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg text-red-500 hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message with full context"
|
||||
@click.stop="resendMessage('full_context')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<i data-feather="send"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message without the full context"
|
||||
@click.stop="resendMessage('full_context_with_internet')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<img :src="sendGlobe" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message without the full context"
|
||||
@click.stop="resendMessage('simple_question')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<i data-feather="send"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender==this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message"
|
||||
@click.stop="continueMessage()"
|
||||
>
|
||||
<i data-feather="fast-forward"></i>
|
||||
</div>
|
||||
<!-- DELETE CONFIRMATION -->
|
||||
<div v-if="deleteMsgMode" class="flex items-center duration-75">
|
||||
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Cancel removal" type="button" @click.stop="deleteMsgMode = false">
|
||||
<i data-feather="x"></i>
|
||||
</button>
|
||||
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Confirm removal" type="button" @click.stop="deleteMsg()">
|
||||
<i data-feather="check"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div v-if="!editMsgMode && !deleteMsgMode" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Remove message" @click="deleteMsgMode = true">
|
||||
<i data-feather="trash"></i>
|
||||
</div>
|
||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer" title="Upvote"
|
||||
@click.stop="rankUp()">
|
||||
<i data-feather="thumbs-up"></i>
|
||||
</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer" title="Downvote"
|
||||
@click.stop="rankDown()">
|
||||
<i data-feather="thumbs-down"></i>
|
||||
</div>
|
||||
<div v-if="message.rank != 0"
|
||||
class="rounded-full px-2 text-sm flex items-center justify-center font-bold cursor-pointer"
|
||||
:class="message.rank > 0 ? 'bg-secondary' : 'bg-red-600'" title="Rank">{{
|
||||
message.rank }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="speak"
|
||||
v-if ="this.$store.state.config.active_tts_service!='None'"
|
||||
@click.stop="speak()"
|
||||
:class="{ 'text-red-500': isTalking }">
|
||||
<i data-feather="volume-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="this.$store.state.config.xtts_enable && !this.$store.state.config.xtts_use_streaming_mode" class="flex flex-row items-center">
|
||||
<div v-if="!isSynthesizingVoice" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="generate_audio"
|
||||
@click.stop="read()"
|
||||
>
|
||||
<i data-feather="voicemail"></i>
|
||||
</div>
|
||||
<img v-else :src="loading_svg">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto w-full overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
|
||||
@ -202,7 +68,7 @@
|
||||
</MarkdownRenderer>
|
||||
<div >
|
||||
<textarea v-if="message.open" ref="mdTextarea" @keydown.tab.prevent="insertTab"
|
||||
class="block min-h-[900px] p-2.5 w-full text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 overflow-y-scroll flex flex-col shadow-lg p-10 pt-0 overflow-y-scroll dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary"
|
||||
class="block min-h-[500px] p-2.5 w-full text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 overflow-y-scroll flex flex-col shadow-lg p-10 pt-0 overflow-y-scroll dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary"
|
||||
:rows="4"
|
||||
placeholder="Enter message here..."
|
||||
v-model="message.content">
|
||||
@ -223,6 +89,141 @@
|
||||
</audio>
|
||||
|
||||
</div>
|
||||
<!-- MESSAGE CONTROLS -->
|
||||
<div class="flex-row justify-end mx-2">
|
||||
<div class="invisible group-hover:visible flex flex-row ">
|
||||
<!-- MESSAGE CONTROLS -->
|
||||
<!-- EDIT CONFIRMATION -->
|
||||
<div v-if="editMsgMode" class="flex items-center duration-75">
|
||||
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||
title="Cancel edit" type="button" @click.stop="editMsgMode = false">
|
||||
<i data-feather="x"></i>
|
||||
</button>
|
||||
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2"
|
||||
title="Update message" type="button" @click.stop="updateMessage">
|
||||
<i data-feather="check"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div v-if="!editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Edit message" @click.stop="editMsgMode = true">
|
||||
<i data-feather="edit"></i>
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer hover:border-2"
|
||||
title="Add generic block" @click.stop="addBlock('')">
|
||||
<img :src="code_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer hover:border-2"
|
||||
title="Add python block" @click.stop="addBlock('python')">
|
||||
<img :src="python_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add javascript block" @click.stop="addBlock('javascript')">
|
||||
<img :src="javascript_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add json block" @click.stop="addBlock('json')">
|
||||
<img :src="json_block" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add c++ block" @click.stop="addBlock('c++')">
|
||||
<img :src="cpp_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add html block" @click.stop="addBlock('html')">
|
||||
<img :src="html5_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add LaTex block" @click.stop="addBlock('latex')">
|
||||
<img :src="LaTeX_block" width="25" height="25">
|
||||
</div>
|
||||
<div v-if="editMsgMode" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Add bash block" @click.stop="addBlock('bash')">
|
||||
<img :src="bash_block" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Copy message to clipboard" @click.stop="copyContentToClipboard()">
|
||||
<i data-feather="copy"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg text-red-500 hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message with full context"
|
||||
@click.stop="resendMessage('full_context')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<i data-feather="send"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message without the full context"
|
||||
@click.stop="resendMessage('full_context_with_internet')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<img :src="sendGlobe" width="25" height="25">
|
||||
</div>
|
||||
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message without the full context"
|
||||
@click.stop="resendMessage('simple_question')"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<i data-feather="send"></i>
|
||||
</div>
|
||||
<div v-if="!editMsgMode && message.sender==this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Resend message"
|
||||
@click.stop="continueMessage()"
|
||||
>
|
||||
<i data-feather="fast-forward"></i>
|
||||
</div>
|
||||
<!-- DELETE CONFIRMATION -->
|
||||
<div v-if="deleteMsgMode" class="flex items-center duration-75">
|
||||
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Cancel removal" type="button" @click.stop="deleteMsgMode = false">
|
||||
<i data-feather="x"></i>
|
||||
</button>
|
||||
<button class="text-2xl hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Confirm removal" type="button" @click.stop="deleteMsg()">
|
||||
<i data-feather="check"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div v-if="!editMsgMode && !deleteMsgMode" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="Remove message" @click="deleteMsgMode = true">
|
||||
<i data-feather="trash"></i>
|
||||
</div>
|
||||
<div class="text-lg hover:text-secondary duration-75 active:scale-90 p-2 cursor-pointer" title="Upvote"
|
||||
@click.stop="rankUp()">
|
||||
<i data-feather="thumbs-up"></i>
|
||||
</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer" title="Downvote"
|
||||
@click.stop="rankDown()">
|
||||
<i data-feather="thumbs-down"></i>
|
||||
</div>
|
||||
<div v-if="message.rank != 0"
|
||||
class="rounded-full px-2 text-sm flex items-center justify-center font-bold cursor-pointer"
|
||||
:class="message.rank > 0 ? 'bg-secondary' : 'bg-red-600'" title="Rank">{{
|
||||
message.rank }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="speak"
|
||||
v-if ="this.$store.state.config.active_tts_service!='None'"
|
||||
@click.stop="speak()"
|
||||
:class="{ 'text-red-500': isTalking }">
|
||||
<i data-feather="volume-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="this.$store.state.config.xtts_enable && !this.$store.state.config.xtts_use_streaming_mode" class="flex flex-row items-center">
|
||||
<div v-if="!isSynthesizingVoice" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2 cursor-pointer"
|
||||
title="generate_audio"
|
||||
@click.stop="read()"
|
||||
>
|
||||
<i data-feather="voicemail"></i>
|
||||
</div>
|
||||
<img v-else :src="loading_svg">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- FOOTER -->
|
||||
<div class="text-sm text-gray-400 mt-2">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
@ -525,15 +526,25 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
speak() {
|
||||
async speak() {
|
||||
if(this.$store.state.config.active_tts_service!="browser" && this.$store.state.config.active_tts_service!="None"){
|
||||
this.isSpeaking = true;
|
||||
axios.post("./text2Audio",{text:this.message.content}).then(response => {
|
||||
this.isSpeaking = false;
|
||||
}).catch(ex=>{
|
||||
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
||||
this.isSpeaking = false;
|
||||
});
|
||||
if(!this.isSpeaking){
|
||||
this.isSpeaking = true;
|
||||
axios.post("./text2Audio",{client_id:this.$store.state.client_id, text:this.message.content}).then(response => {
|
||||
}).catch(ex=>{
|
||||
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
||||
this.isSpeaking = false;
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.isSpeaking = true;
|
||||
axios.post("./stop",{text:this.message.content}).then(response => {
|
||||
this.isSpeaking = false;
|
||||
}).catch(ex=>{
|
||||
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
||||
this.isSpeaking = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (this.msg) {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit babf95044dc34e46d74843ae17bc87e06f5cecd8
|
||||
Subproject commit 518371c281c619bdae757f310194e7693f0083a1
|
Loading…
Reference in New Issue
Block a user