Faisal Amir 2394c13065
ui: standalone UIKit and refactor (#557)
* Eslint import order

* Initial Uikit

* Rename file with camelCase

* Remove unused code

* Remove unused code

* Set position traficlight mac

* Grouping Ribbon, Topbar and Bottombar as layout

* Added image brand

* Moving feature toggle into context folder

* Fix active state of setting menu

* Cleanup downloadModel atom helper

* Cleanup useGetConfigureModel

* Added wave animation

* Create useMainViewState intead of import helper atom

* Remove unused code

* Take a back switch ui

* Toggle using switch component

* Add dynamic primary color

* Cleanup import

* Added uikit scroll area

* Add best practice form

* Added toaster container

* Fix loader container

* Add hooks useDownloadState

* Added tooltip on ribbon menu

* Added case user multiple download model

* Adjust input style with bigger ring

* Restyle my model screen

* Replace useStartStop model with useActiveModel

* Import icon using Icon name

* Fix missing login loading start and stop model

* WIP integrate with cmdk

* Move layout search bar on middle of app

* Added function cancel download

* Cleanup model explore

* Cleanup unused code

* Move app version in bototmbar or footer

* WIP chat screen

* WIP chat screen

* Cleanup style and remove unsed code

* Added command for showing downloaded model

* Fix missing keyframe loader dot animation

* Conditional loader of plugin setting

* WIP history list message

* chore: rebase main

* Adding script ui into root package

* Fix different version react hooks form

* Add close toaster

* Added status model active or not on list of command

* Conditional showing info if user don't have a model

* Disabled toolbar chat when user not yet have convo

* chore: fix state

* fix: get resource atom

* Fix conditional bottom bar

* fix: model download state

* Fix font

* Improve icon my model

* Add toaster delete chat

* Remove test classname

* Fix scroll chat body

* Fix scrolling chat body

* chore: add message update

* Add uikit into depedencies on root package

* Update chat flow

* Fix hot reload ui changes

* Increate background color chat screen light mode

* Added visual conversation active state

* Added build:uikit on gh actions

* chore: attempt to fix CI

* fix: deps

* fix: tests

* chore: attempt to fix CI

---------

Co-authored-by: Louis <louis@jan.ai>
2023-11-07 21:27:11 +07:00

94 lines
2.4 KiB
TypeScript

import React, { Fragment } from 'react'
import hljs from 'highlight.js'
import { Marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import { twMerge } from 'tailwind-merge'
import LogoMark from '@/containers/Brand/Logo/Mark'
import { displayDate } from '@/utils/datetime'
import LoadingIndicator from '../../../components/LoadingIndicator'
import { MessageSenderType } from '@/models/ChatMessage'
type Props = {
avatarUrl: string
senderName: string
createdAt: number
senderType: MessageSenderType
text?: string
}
const marked = new Marked(
// markedHighlight({
// langPrefix: 'hljs',
// highlight(code, lang) {
// if (lang === undefined || lang === '') {
// return hljs.highlightAuto(code).value
// }
// return hljs.highlight(code, { language: lang }).value
// },
// }),
markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return hljs.highlight(code, { language }).value
},
}),
{
renderer: {
code(code, lang, escaped) {
return `<pre class="hljs"><code class="language-${encodeURIComponent(
lang ?? ''
)}">${escaped ? code : encodeURIComponent(code)}</code></pre>`
},
},
}
)
const SimpleTextMessage: React.FC<Props> = ({
senderName,
senderType,
createdAt,
text = '',
}) => {
const parsedText = marked.parse(text)
const isUser = senderType === 'user'
return (
<div className="mx-auto flex w-full flex-col items-start gap-1 rounded-xl px-4 lg:w-3/4">
<div
className={twMerge(
'mb-1 flex items-center justify-start gap-2',
!isUser && 'mt-2'
)}
>
{!isUser && <LogoMark width={20} />}
<div className="text-sm font-extrabold ">{senderName}</div>
<p className="text-xs font-medium">{displayDate(createdAt)}</p>
</div>
<div className="w-full">
{text === '' ? (
<LoadingIndicator />
) : (
<>
<span
className="message text-[15px] font-normal leading-relaxed"
// eslint-disable-next-line @typescript-eslint/naming-convention
dangerouslySetInnerHTML={{ __html: parsedText }}
/>
</>
)}
</div>
</div>
)
}
export default React.memo(SimpleTextMessage)