better special citation styling
This commit is contained in:
parent
f5fa03f472
commit
649c94298c
@ -39,21 +39,31 @@ const CIRCLE_IMAGES = {
|
|||||||
outlookAttachment: OutlookLogo,
|
outlookAttachment: OutlookLogo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the custom image for a given type, or null if no custom image is available.
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {string|null}
|
||||||
|
*/
|
||||||
|
export function getCustomImage(type) {
|
||||||
|
return CIRCLE_IMAGES[type] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a circle with a source type icon inside, or a favicon if URL is provided.
|
* Renders a circle with a source type icon inside, or a favicon if URL is provided.
|
||||||
* @param {"file"|"link"|"youtube"|"github"|"gitlab"|"confluence"|"drupalwiki"|"obsidian"|"paperlessNgx"} props.type
|
* @param {"file"|"link"|"youtube"|"github"|"gitlab"|"confluence"|"drupalwiki"|"obsidian"|"paperlessNgx"} props.type
|
||||||
* @param {number} [props.size] - Circle diameter in px
|
* @param {number} [props.size] - Circle diameter in px
|
||||||
* @param {number} [props.iconSize] - Icon size in px
|
* @param {number} [props.iconSize] - Icon size in px
|
||||||
* @param {string} [props.url] - Optional URL to fetch favicon from
|
* @param {string} [props.url] - Optional URL to fetch favicon from
|
||||||
|
* @param {string} [props.customImage] - Optional custom image to display
|
||||||
*/
|
*/
|
||||||
export function SourceTypeCircle({
|
export function SourceTypeCircle({
|
||||||
type = "file",
|
type = "file",
|
||||||
size = 22,
|
size = 22,
|
||||||
iconSize = 12,
|
iconSize = 12,
|
||||||
url = null,
|
url = null,
|
||||||
|
customImage = null,
|
||||||
}) {
|
}) {
|
||||||
const Icon = CIRCLE_ICONS[type] || CIRCLE_ICONS.file;
|
const Icon = CIRCLE_ICONS[type] || CIRCLE_ICONS.file;
|
||||||
const customImage = CIRCLE_IMAGES[type];
|
|
||||||
const [imgError, setImgError] = useState(false);
|
const [imgError, setImgError] = useState(false);
|
||||||
|
|
||||||
let faviconUrl = null;
|
let faviconUrl = null;
|
||||||
@ -72,7 +82,7 @@ export function SourceTypeCircle({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="bg-white light:bg-slate-100 rounded-full flex items-center justify-center overflow-hidden"
|
className={`${customImage ? "bg-transparent border-none" : "bg-white light:bg-slate-100 border-zinc-800 light:border-white rounded-full"} flex items-center justify-center overflow-hidden`}
|
||||||
style={{ width: size, height: size }}
|
style={{ width: size, height: size }}
|
||||||
>
|
>
|
||||||
{faviconUrl && !imgError ? (
|
{faviconUrl && !imgError ? (
|
||||||
@ -87,8 +97,8 @@ export function SourceTypeCircle({
|
|||||||
<img
|
<img
|
||||||
src={customImage}
|
src={customImage}
|
||||||
alt={type}
|
alt={type}
|
||||||
style={{ width: iconSize, height: iconSize }}
|
style={{ width: size, height: size }}
|
||||||
className="object-contain"
|
className="object-contain bg-transparent"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Icon size={iconSize} weight="bold" className="text-black" />
|
<Icon size={iconSize} weight="bold" className="text-black" />
|
||||||
@ -152,10 +162,11 @@ export default function Citations({ sources = [] }) {
|
|||||||
>
|
>
|
||||||
{visibleSources.map((source, idx) => {
|
{visibleSources.map((source, idx) => {
|
||||||
const info = parseChunkSource(source);
|
const info = parseChunkSource(source);
|
||||||
|
const customImage = CIRCLE_IMAGES[info.icon];
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={source.title || idx}
|
key={source.title || idx}
|
||||||
className="absolute top-0 size-[22px] rounded-full border-2 border-zinc-800 light:border-white"
|
className={`absolute top-0 size-[22px] rounded-full ${customImage ? "border-none" : "border-2 border-zinc-800 light:border-white"}`}
|
||||||
style={{ left: `${idx * 17}px`, zIndex: 3 - idx }}
|
style={{ left: `${idx * 17}px`, zIndex: 3 - idx }}
|
||||||
>
|
>
|
||||||
<SourceTypeCircle
|
<SourceTypeCircle
|
||||||
@ -163,6 +174,7 @@ export default function Citations({ sources = [] }) {
|
|||||||
size={18}
|
size={18}
|
||||||
iconSize={10}
|
iconSize={10}
|
||||||
url={info.href}
|
url={info.href}
|
||||||
|
customImage={customImage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
import { parseChunkSource, SourceTypeCircle } from "../../ChatHistory/Citation";
|
import {
|
||||||
|
parseChunkSource,
|
||||||
|
SourceTypeCircle,
|
||||||
|
getCustomImage,
|
||||||
|
} from "../../ChatHistory/Citation";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function SourceItem({ source, onClick }) {
|
export default function SourceItem({ source, onClick }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const info = parseChunkSource(source);
|
const info = parseChunkSource(source);
|
||||||
const subtitle = info.isUrl ? info.text : t("chat_window.document");
|
const customImage = getCustomImage(info?.icon);
|
||||||
|
const subtitle = info?.isUrl ? info?.text : t("chat_window.document");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@ -18,6 +23,7 @@ export default function SourceItem({ source, onClick }) {
|
|||||||
size={16}
|
size={16}
|
||||||
iconSize={10}
|
iconSize={10}
|
||||||
url={info.href}
|
url={info.href}
|
||||||
|
customImage={customImage}
|
||||||
/>
|
/>
|
||||||
<p className="flex-1 font-medium text-sm text-white light:text-slate-900 leading-[15px] truncate">
|
<p className="flex-1 font-medium text-sm text-white light:text-slate-900 leading-[15px] truncate">
|
||||||
{source.title}
|
{source.title}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user