mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-28 03:37:08 +02:00
fix: markdown rendering and scrolling
fix: markdown rendering for search results
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,7 +1,6 @@
|
|||||||
{% extends 'body_base.html' %}
|
{% extends 'body_base.html' %}
|
||||||
{% block title %}Minne Chat{% endblock %}
|
{% block title %}Minne Chat{% endblock %}
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="/assets/marked.min.js"></script>
|
|
||||||
<script src="/assets/htmx-ext-sse.js" defer></script>
|
<script src="/assets/htmx-ext-sse.js" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -88,34 +87,14 @@
|
|||||||
margin: 0.75em 0;
|
margin: 0.75em 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function initialize() {
|
|
||||||
marked.setOptions({
|
|
||||||
breaks: true, gfm: true, headerIds: false, mangle: false,
|
|
||||||
smartLists: true, smartypants: true, xhtml: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render static markdown (any .markdown-content[data-content])
|
|
||||||
function renderStaticMarkdown() {
|
|
||||||
document.querySelectorAll('.markdown-content[data-content]').forEach(el => {
|
|
||||||
const raw = el.getAttribute('data-content') || '';
|
|
||||||
el.innerHTML = marked.parse(raw);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrollChatToBottom() {
|
function scrollChatToBottom() {
|
||||||
const chatContainer = document.getElementById('chat_container');
|
const chatContainer = document.getElementById('chat_container');
|
||||||
if (chatContainer) chatContainer.scrollTop = chatContainer.scrollHeight;
|
if (chatContainer) chatContainer.scrollTop = chatContainer.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
function processChatUi() {
|
document.addEventListener('DOMContentLoaded', scrollChatToBottom);
|
||||||
initialize();
|
document.body.addEventListener('htmx:afterSettle', scrollChatToBottom);
|
||||||
renderStaticMarkdown();
|
|
||||||
scrollChatToBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', processChatUi);
|
|
||||||
document.body.addEventListener('htmx:afterSettle', processChatUi);
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -1,38 +1,35 @@
|
|||||||
{% extends "modal_base.html" %}
|
{% extends "modal_base.html" %}
|
||||||
|
|
||||||
|
{% block modal_class %}w-11/12 max-w-[90ch] max-h-[95%] overflow-y-auto{% endblock %}
|
||||||
{% block modal_class %}w-11/12 max-w-[90ch] max-h-[95%]{% endblock %}
|
|
||||||
|
|
||||||
{% block modal_content %}
|
{% block modal_content %}
|
||||||
{% if text_content.url_info.image_id %}
|
{% if text_content.url_info.image_id %}
|
||||||
<img class="rounded-t-md overflow-clip" src="/file/{{text_content.url_info.image_id}}" />
|
<img class="rounded-t-md overflow-clip" src="/file/{{text_content.url_info.image_id}}" alt="Screenshot of the site" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<div id="reader-{{text_content.id}}" class="markdown-content prose" data-content="{{text_content.text | escape }}">
|
||||||
<div class="markdown-content prose" data-content="{{text_content.text | escape }}">
|
|
||||||
{{text_content.text | escape }}
|
{{text_content.text | escape }}
|
||||||
</div>
|
</div>
|
||||||
<script src="/assets/marked.min.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
function initialize() {
|
(function () {
|
||||||
marked.setOptions({
|
const readerElementId = "reader-{{text_content.id}}";
|
||||||
breaks: true, gfm: true, headerIds: false, mangle: false,
|
const contentDiv = document.getElementById(readerElementId);
|
||||||
smartLists: true, smartypants: true, xhtml: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderStaticMarkdown() {
|
if (!contentDiv) {
|
||||||
document.querySelectorAll('.markdown-content').forEach(el => {
|
console.error("Markdown content div #" + readerElementId + " not found for processing.");
|
||||||
const raw = el.getAttribute('data-content') || '';
|
return;
|
||||||
el.innerHTML = marked.parse(raw);
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function processMarkdown() {
|
const scrollableModalContainer = contentDiv.closest('.overflow-y-auto.max-h-\\[95\\%\\]');
|
||||||
initialize();
|
|
||||||
renderStaticMarkdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.body.addEventListener('htmx:afterSettle', processMarkdown);
|
if (scrollableModalContainer) {
|
||||||
|
setTimeout(() => {
|
||||||
|
scrollableModalContainer.scrollTop = 0;
|
||||||
|
}, 10);
|
||||||
|
} else {
|
||||||
|
console.warn('Scrollable modal container not found for #', readerElementId);
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<script src="/assets/theme-toggle.js" defer></script>
|
<script src="/assets/theme-toggle.js" defer></script>
|
||||||
<script src="/assets/toast.js" defer></script>
|
<script src="/assets/toast.js" defer></script>
|
||||||
<script src="/assets/htmx-head-ext.js" defer></script>
|
<script src="/assets/htmx-head-ext.js" defer></script>
|
||||||
|
<script src="/assets/marked.min.js" defer></script>
|
||||||
|
|
||||||
<!-- Icons -->
|
<!-- Icons -->
|
||||||
<link rel="icon" href="/assets/icon/favicon.ico">
|
<link rel="icon" href="/assets/icon/favicon.ico">
|
||||||
@@ -39,8 +40,40 @@
|
|||||||
setTimeout(wait_for_htmx, 50);
|
setTimeout(wait_for_htmx, 50);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
|
|
||||||
|
<script defer>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
if (window.marked && !window.markedGlobalOptionsSet) {
|
||||||
|
marked.setOptions({
|
||||||
|
breaks: true,
|
||||||
|
gfm: true,
|
||||||
|
headerIds: false,
|
||||||
|
mangle: false,
|
||||||
|
smartLists: true,
|
||||||
|
smartypants: true,
|
||||||
|
xhtml: false
|
||||||
|
});
|
||||||
|
window.markedGlobalOptionsSet = true;
|
||||||
|
}
|
||||||
|
renderAllMarkdown();
|
||||||
|
});
|
||||||
|
document.body.addEventListener('htmx:afterSettle', renderAllMarkdown);
|
||||||
|
|
||||||
|
function renderAllMarkdown() {
|
||||||
|
if (!window.marked) return;
|
||||||
|
document.querySelectorAll('.markdown-content[data-content]').forEach(el => {
|
||||||
|
const raw = el.getAttribute('data-content') || '';
|
||||||
|
if (el.dataset.renderedContent !== raw) {
|
||||||
|
el.innerHTML = marked.parse(raw);
|
||||||
|
el.dataset.renderedContent = raw;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.renderAllMarkdown = renderAllMarkdown;
|
||||||
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -30,7 +30,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="prose prose-sm text-sm truncate text-base-content/80 mb-3">
|
<div class="markdown-content prose prose-sm text-sm text-base-content/80 mb-3 overflow-hidden line-clamp-6"
|
||||||
|
data-content="{{result.highlighted_text | escape}}">
|
||||||
{% if result.highlighted_text %}
|
{% if result.highlighted_text %}
|
||||||
{{ result.highlighted_text | escape }}
|
{{ result.highlighted_text | escape }}
|
||||||
{% elif result.text %}
|
{% elif result.text %}
|
||||||
|
|||||||
6
todo.md
6
todo.md
@@ -1,7 +1,5 @@
|
|||||||
[] debug vector search
|
|
||||||
[] archive ingressed webpage, pdf would be easy
|
[] archive ingressed webpage, pdf would be easy
|
||||||
[] embed surrealdb for the main binary
|
[] embed surrealdb for the main binary
|
||||||
[x] full text search
|
|
||||||
[] three js graph explorer
|
[] three js graph explorer
|
||||||
[] three js vector explorer
|
[] three js vector explorer
|
||||||
[x] add user_id to ingress objects
|
[x] add user_id to ingress objects
|
||||||
@@ -13,11 +11,13 @@
|
|||||||
[x] chat history
|
[x] chat history
|
||||||
[x] chat styling overhaul
|
[x] chat styling overhaul
|
||||||
[x] configs primarily get envs
|
[x] configs primarily get envs
|
||||||
|
[x] debug vector search
|
||||||
[x] debug why not automatic retrieval of chrome binary works
|
[x] debug why not automatic retrieval of chrome binary works
|
||||||
[x] filtering on categories
|
[x] filtering on categories
|
||||||
[x] fix card image in content
|
[x] fix card image in content
|
||||||
[x] fix patch_text_content
|
[x] fix patch_text_content
|
||||||
[x] fix redirect for non hx
|
[x] fix redirect for non hx
|
||||||
|
[x] full text search
|
||||||
[x] html ingression
|
[x] html ingression
|
||||||
[x] hx-redirect
|
[x] hx-redirect
|
||||||
[x] implement migrations
|
[x] implement migrations
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
[x] macro for pagedata?
|
[x] macro for pagedata?
|
||||||
[x] make sure error messages render correctly
|
[x] make sure error messages render correctly
|
||||||
[x] markdown rendering in client
|
[x] markdown rendering in client
|
||||||
|
[x] marked loading conditions
|
||||||
[x] on updates of knowledgeentity create new embeddings
|
[x] on updates of knowledgeentity create new embeddings
|
||||||
[x] openai api key in config
|
[x] openai api key in config
|
||||||
[x] option to set models, query and processing
|
[x] option to set models, query and processing
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
[x] redirects
|
[x] redirects
|
||||||
[x] rename ingestion instructions to context
|
[x] rename ingestion instructions to context
|
||||||
[x] restrict retrieval to users own objects
|
[x] restrict retrieval to users own objects
|
||||||
|
[x] scroll reading window to top
|
||||||
[x] smoothie_dom test
|
[x] smoothie_dom test
|
||||||
[x] sse ingestion updates
|
[x] sse ingestion updates
|
||||||
[x] store page title
|
[x] store page title
|
||||||
|
|||||||
Reference in New Issue
Block a user