mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 12:25:20 +00:00
feat/enh: embed citation
This commit is contained in:
parent
118549caf3
commit
f58fc753e3
9 changed files with 96 additions and 12 deletions
|
|
@ -38,7 +38,8 @@
|
|||
toolServers,
|
||||
functions,
|
||||
selectedFolder,
|
||||
pinnedChats
|
||||
pinnedChats,
|
||||
showEmbeds
|
||||
} from '$lib/stores';
|
||||
import {
|
||||
convertMessagesToHistory,
|
||||
|
|
@ -564,6 +565,7 @@
|
|||
showCallOverlay.set(false);
|
||||
showOverview.set(false);
|
||||
showArtifacts.set(false);
|
||||
showEmbeds.set(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,14 @@
|
|||
import { Pane, PaneResizer } from 'paneforge';
|
||||
|
||||
import { onDestroy, onMount, tick } from 'svelte';
|
||||
import { mobile, showControls, showCallOverlay, showOverview, showArtifacts } from '$lib/stores';
|
||||
import {
|
||||
mobile,
|
||||
showControls,
|
||||
showCallOverlay,
|
||||
showOverview,
|
||||
showArtifacts,
|
||||
showEmbeds
|
||||
} from '$lib/stores';
|
||||
|
||||
import Modal from '../common/Modal.svelte';
|
||||
import Controls from './Controls/Controls.svelte';
|
||||
|
|
@ -13,6 +20,7 @@
|
|||
import Overview from './Overview.svelte';
|
||||
import EllipsisVertical from '../icons/EllipsisVertical.svelte';
|
||||
import Artifacts from './Artifacts.svelte';
|
||||
import Embeds from './ChatControls/Embeds.svelte';
|
||||
|
||||
export let history;
|
||||
export let models = [];
|
||||
|
|
@ -134,6 +142,7 @@
|
|||
showControls.set(false);
|
||||
showOverview.set(false);
|
||||
showArtifacts.set(false);
|
||||
showEmbeds.set(false);
|
||||
|
||||
if ($showCallOverlay) {
|
||||
showCallOverlay.set(false);
|
||||
|
|
@ -155,9 +164,9 @@
|
|||
}}
|
||||
>
|
||||
<div
|
||||
class=" {$showCallOverlay || $showOverview || $showArtifacts
|
||||
class=" {$showCallOverlay || $showOverview || $showArtifacts || $showEmbeds
|
||||
? ' h-screen w-full'
|
||||
: 'px-6 py-4'} h-full"
|
||||
: 'px-4 py-3'} h-full"
|
||||
>
|
||||
{#if $showCallOverlay}
|
||||
<div
|
||||
|
|
@ -175,6 +184,8 @@
|
|||
}}
|
||||
/>
|
||||
</div>
|
||||
{:else if $showEmbeds}
|
||||
<Embeds />
|
||||
{:else if $showArtifacts}
|
||||
<Artifacts {history} />
|
||||
{:else if $showOverview}
|
||||
|
|
@ -241,9 +252,9 @@
|
|||
{#if $showControls}
|
||||
<div class="flex max-h-full min-h-full">
|
||||
<div
|
||||
class="w-full {($showOverview || $showArtifacts) && !$showCallOverlay
|
||||
class="w-full {($showOverview || $showArtifacts || $showEmbeds) && !$showCallOverlay
|
||||
? ' '
|
||||
: 'px-4 py-4 bg-white dark:shadow-lg dark:bg-gray-850 '} z-40 pointer-events-auto overflow-y-auto scrollbar-hidden"
|
||||
: 'px-4 py-3 bg-white dark:shadow-lg dark:bg-gray-850 '} z-40 pointer-events-auto overflow-y-auto scrollbar-hidden"
|
||||
id="controls-container"
|
||||
>
|
||||
{#if $showCallOverlay}
|
||||
|
|
@ -260,6 +271,8 @@
|
|||
}}
|
||||
/>
|
||||
</div>
|
||||
{:else if $showEmbeds}
|
||||
<Embeds overlay={dragged} />
|
||||
{:else if $showArtifacts}
|
||||
<Artifacts {history} overlay={dragged} />
|
||||
{:else if $showOverview}
|
||||
|
|
|
|||
42
src/lib/components/chat/ChatControls/Embeds.svelte
Normal file
42
src/lib/components/chat/ChatControls/Embeds.svelte
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<script>
|
||||
import { embed, showControls, showEmbeds } from '$lib/stores';
|
||||
|
||||
import FullHeightIframe from '$lib/components/common/FullHeightIframe.svelte';
|
||||
import XMark from '$lib/components/icons/XMark.svelte';
|
||||
|
||||
export let overlay = false;
|
||||
</script>
|
||||
|
||||
{#if $embed}
|
||||
<div class="h-full w-full">
|
||||
<div
|
||||
class="pointer-events-auto z-20 flex justify-between items-center py-3 px-2 font-primar text-gray-900 dark:text-white"
|
||||
>
|
||||
<div class="flex-1 flex items-center justify-between pl-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
{$embed?.title ?? 'Embedded Content'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="self-center pointer-events-auto p-1 rounded-full bg-white dark:bg-gray-850"
|
||||
on:click={() => {
|
||||
console.log('hi');
|
||||
showControls.set(false);
|
||||
showEmbeds.set(false);
|
||||
embed.set(null);
|
||||
}}
|
||||
>
|
||||
<XMark className="size-3.5 text-gray-900 dark:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class=" w-full h-full relative">
|
||||
{#if overlay}
|
||||
<div class=" absolute top-0 left-0 right-0 bottom-0 z-10"></div>
|
||||
{/if}
|
||||
|
||||
<FullHeightIframe src={$embed?.url} iframeClassName="w-full h-full" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import CitationModal from './Citations/CitationModal.svelte';
|
||||
import { embed, showControls, showEmbeds } from '$lib/stores';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
|
@ -21,8 +22,24 @@
|
|||
export const showSourceModal = (sourceIdx) => {
|
||||
if (citations[sourceIdx]) {
|
||||
console.log('Showing citation modal for:', citations[sourceIdx]);
|
||||
selectedCitation = citations[sourceIdx];
|
||||
showCitationModal = true;
|
||||
|
||||
if (citations[sourceIdx]?.source?.embed_url) {
|
||||
const embedUrl = citations[sourceIdx].source.embed_url;
|
||||
if (embedUrl) {
|
||||
showControls.set(true);
|
||||
showEmbeds.set(true);
|
||||
embed.set({
|
||||
title: citations[sourceIdx]?.source?.name || 'Embedded Content',
|
||||
url: embedUrl
|
||||
});
|
||||
} else {
|
||||
selectedCitation = citations[sourceIdx];
|
||||
showCitationModal = true;
|
||||
}
|
||||
} else {
|
||||
selectedCitation = citations[sourceIdx];
|
||||
showCitationModal = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
settings,
|
||||
showArtifacts,
|
||||
showControls,
|
||||
showEmbeds,
|
||||
showOverview
|
||||
} from '$lib/stores';
|
||||
import FloatingButtons from '../ContentRenderer/FloatingButtons.svelte';
|
||||
|
|
@ -194,6 +195,7 @@
|
|||
await showControls.set(true);
|
||||
await showArtifacts.set(true);
|
||||
await showOverview.set(false);
|
||||
await showEmbeds.set(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@
|
|||
</script>
|
||||
|
||||
<div class="w-full h-full relative">
|
||||
<div class=" absolute z-50 w-full flex justify-between dark:text-gray-100 px-4 py-3.5">
|
||||
<div class=" absolute z-50 w-full flex justify-between dark:text-gray-100 px-4 py-3">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<button
|
||||
class="self-center p-0.5"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
export let title = 'Embedded Content';
|
||||
export let initialHeight: number | null = null; // initial height in px, null = auto
|
||||
|
||||
export let iframeClassName = 'w-full rounded-2xl';
|
||||
|
||||
export let args = null;
|
||||
|
||||
export let allowScripts = true;
|
||||
|
|
@ -174,7 +176,7 @@ window.Chart = parent.Chart; // Chart previously assigned on parent
|
|||
bind:this={iframe}
|
||||
srcdoc={iframeDoc}
|
||||
{title}
|
||||
class="w-full rounded-2xl"
|
||||
class={iframeClassName}
|
||||
style={`${initialHeight ? `height:${initialHeight}px;` : ''}`}
|
||||
width="100%"
|
||||
frameborder="0"
|
||||
|
|
@ -187,7 +189,7 @@ window.Chart = parent.Chart; // Chart previously assigned on parent
|
|||
bind:this={iframe}
|
||||
src={iframeSrc}
|
||||
{title}
|
||||
class="w-full rounded-2xl"
|
||||
class={iframeClassName}
|
||||
style={`${initialHeight ? `height:${initialHeight}px;` : ''}`}
|
||||
width="100%"
|
||||
frameborder="0"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
theme,
|
||||
user,
|
||||
settings,
|
||||
folders
|
||||
folders,
|
||||
showEmbeds
|
||||
} from '$lib/stores';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
import { getChatById } from '$lib/apis/chats';
|
||||
|
|
@ -319,6 +320,7 @@
|
|||
await showControls.set(true);
|
||||
await showOverview.set(false);
|
||||
await showArtifacts.set(false);
|
||||
await showEmbeds.set(false);
|
||||
}}
|
||||
>
|
||||
<AdjustmentsHorizontal className=" size-4" strokeWidth="1.5" />
|
||||
|
|
@ -333,6 +335,7 @@
|
|||
await showControls.set(true);
|
||||
await showOverview.set(true);
|
||||
await showArtifacts.set(false);
|
||||
await showEmbeds.set(false);
|
||||
}}
|
||||
>
|
||||
<Map className=" size-4" strokeWidth="1.5" />
|
||||
|
|
@ -346,6 +349,7 @@
|
|||
await showControls.set(true);
|
||||
await showArtifacts.set(true);
|
||||
await showOverview.set(false);
|
||||
await showEmbeds.set(false);
|
||||
}}
|
||||
>
|
||||
<Cube className=" size-4" strokeWidth="1.5" />
|
||||
|
|
|
|||
|
|
@ -75,10 +75,12 @@ export const showArchivedChats = writable(false);
|
|||
export const showChangelog = writable(false);
|
||||
|
||||
export const showControls = writable(false);
|
||||
export const showEmbeds = writable(false);
|
||||
export const showOverview = writable(false);
|
||||
export const showArtifacts = writable(false);
|
||||
export const showCallOverlay = writable(false);
|
||||
|
||||
export const embed = writable(null);
|
||||
export const artifactCode = writable(null);
|
||||
|
||||
export const temporaryChatEnabled = writable(false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue