generated from arvinxx/npm-template
-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
79 changed files
with
4,445 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import ActionIconGroup from '@/ActionIconGroup'; | ||
import { RenderAction } from '@/ChatList'; | ||
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar'; | ||
import { memo } from 'react'; | ||
|
||
import { ErrorActionsBar } from './Error'; | ||
|
||
export const AssistantActionsBar: RenderAction = memo(({ text, id, onActionClick, error }) => { | ||
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text); | ||
|
||
if (id === 'default') return; | ||
|
||
if (error) return <ErrorActionsBar onActionClick={onActionClick} text={text} />; | ||
|
||
return ( | ||
<ActionIconGroup | ||
dropdownMenu={[ | ||
edit, | ||
copy, | ||
regenerate, | ||
divider, | ||
// TODO: need a translate | ||
divider, | ||
del, | ||
]} | ||
items={[regenerate, copy]} | ||
onActionClick={onActionClick} | ||
type="ghost" | ||
/> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import ActionIconGroup from '@/ActionIconGroup'; | ||
import { ActionsBarProps } from '@/ChatList/ActionsBar'; | ||
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar'; | ||
import { memo } from 'react'; | ||
|
||
export const ErrorActionsBar = memo<ActionsBarProps>(({ text, onActionClick }) => { | ||
const { regenerate, del } = useChatListActionsBar(text); | ||
|
||
return <ActionIconGroup items={[regenerate, del]} onActionClick={onActionClick} type="ghost" />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar'; | ||
import { ActionIconGroup, RenderAction } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
export const DefaultActionsBar: RenderAction = memo(({ text, onActionClick }) => { | ||
const { del } = useChatListActionsBar(text); | ||
return ( | ||
<ActionIconGroup dropdownMenu={[del]} items={[]} onActionClick={onActionClick} type="ghost" /> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar'; | ||
import { ActionIconGroup, RenderAction } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
export const FunctionActionsBar: RenderAction = memo(({ text, onActionClick }) => { | ||
const { regenerate, divider, del } = useChatListActionsBar(text); | ||
return ( | ||
<ActionIconGroup | ||
dropdownMenu={[regenerate, divider, del]} | ||
items={[regenerate]} | ||
onActionClick={onActionClick} | ||
type="ghost" | ||
/> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { useChatListActionsBar } from '@/hooks/useChatListActionsBar'; | ||
import { ActionIconGroup, RenderAction } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
export const UserActionsBar: RenderAction = memo(({ text, onActionClick }) => { | ||
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text); | ||
|
||
return ( | ||
<ActionIconGroup | ||
dropdownMenu={[ | ||
edit, | ||
copy, | ||
regenerate, | ||
divider, | ||
// TODO: need a translate | ||
divider, | ||
del, | ||
]} | ||
items={[regenerate, edit]} | ||
onActionClick={onActionClick} | ||
type="ghost" | ||
/> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { ChatListProps } from '@lobehub/ui'; | ||
|
||
import { AssistantActionsBar } from './Assistant'; | ||
import { DefaultActionsBar } from './Fallback'; | ||
import { FunctionActionsBar } from './Function'; | ||
import { UserActionsBar } from './User'; | ||
|
||
export const renderActions: ChatListProps['renderActions'] = { | ||
assistant: AssistantActionsBar, | ||
function: FunctionActionsBar, | ||
system: DefaultActionsBar, | ||
user: UserActionsBar, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Tag from '@/components/Tag'; | ||
import { RenderMessageExtra } from '@/index'; | ||
|
||
import { memo } from 'react'; | ||
import { Flexbox } from 'react-layout-kit'; | ||
|
||
import { useChatStore } from '@/ProChat/store'; | ||
import { agentSelectors } from '@/ProChat/store/selectors'; | ||
|
||
export const AssistantMessageExtra: RenderMessageExtra = memo(({ extra }) => { | ||
const model = useChatStore(agentSelectors.currentAgentModel); | ||
|
||
const showModelTag = extra?.fromModel && model !== extra?.fromModel; | ||
const hasTranslate = !!extra?.translate; | ||
|
||
const showExtra = showModelTag || hasTranslate; | ||
|
||
if (!showExtra) return; | ||
|
||
return ( | ||
<Flexbox gap={8} style={{ marginTop: 8 }}> | ||
{showModelTag && ( | ||
<div> | ||
{/*TODO: need a model icons */} | ||
<Tag>{extra?.fromModel as string}</Tag> | ||
</div> | ||
)} | ||
</Flexbox> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { RenderMessageExtra } from '@/index'; | ||
import { Divider } from 'antd'; | ||
import { memo } from 'react'; | ||
import { Flexbox } from 'react-layout-kit'; | ||
|
||
export const UserMessageExtra: RenderMessageExtra = memo(({ extra }) => { | ||
const hasTranslate = !!extra?.translate; | ||
|
||
return ( | ||
<Flexbox gap={8} style={{ marginTop: hasTranslate ? 8 : 0 }}> | ||
{extra?.translate && ( | ||
<div> | ||
<Divider style={{ margin: '12px 0' }} /> | ||
</div> | ||
)} | ||
</Flexbox> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ChatListProps } from '@lobehub/ui'; | ||
|
||
import { AssistantMessageExtra } from './Assistant'; | ||
import { UserMessageExtra } from './User'; | ||
|
||
export const renderMessagesExtra: ChatListProps['renderMessagesExtra'] = { | ||
assistant: AssistantMessageExtra, | ||
user: UserMessageExtra, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useTheme } from 'antd-style'; | ||
|
||
const Svg = () => ( | ||
<svg viewBox="0 0 32 24" xmlns="http://www.w3.org/2000/svg"> | ||
<circle cx="0" cy="12" r="0" transform="translate(8 0)"> | ||
<animate | ||
attributeName="r" | ||
begin="0" | ||
calcMode="spline" | ||
dur="1.2s" | ||
keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" | ||
keyTimes="0;0.2;0.7;1" | ||
repeatCount="indefinite" | ||
values="0; 4; 0; 0" | ||
/> | ||
</circle> | ||
<circle cx="0" cy="12" r="0" transform="translate(16 0)"> | ||
<animate | ||
attributeName="r" | ||
begin="0.3" | ||
calcMode="spline" | ||
dur="1.2s" | ||
keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" | ||
keyTimes="0;0.2;0.7;1" | ||
repeatCount="indefinite" | ||
values="0; 4; 0; 0" | ||
/> | ||
</circle> | ||
<circle cx="0" cy="12" r="0" transform="translate(24 0)"> | ||
<animate | ||
attributeName="r" | ||
begin="0.6" | ||
calcMode="spline" | ||
dur="1.2s" | ||
keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8" | ||
keyTimes="0;0.2;0.7;1" | ||
repeatCount="indefinite" | ||
values="0; 4; 0; 0" | ||
/> | ||
</circle> | ||
</svg> | ||
); | ||
|
||
const BubblesLoading = () => { | ||
const { colorTextTertiary } = useTheme(); | ||
return ( | ||
<div style={{ fill: colorTextTertiary, height: 24, width: 32 }}> | ||
<Svg /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default BubblesLoading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { RenderMessage } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
import { DefaultMessage } from './Default'; | ||
|
||
export const AssistantMessage: RenderMessage = memo(({ id, content, ...props }) => { | ||
// todo: need a custom render | ||
return <DefaultMessage content={content} id={id} {...props} />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { RenderMessage } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
import { LOADING_FLAT } from '@/ProChat/const/message'; | ||
|
||
import BubblesLoading from '../Loading'; | ||
|
||
export const DefaultMessage: RenderMessage = memo(({ id, editableContent, content }) => { | ||
if (content === LOADING_FLAT) return <BubblesLoading />; | ||
|
||
return <div id={id}>{editableContent}</div>; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ChatListProps } from '@lobehub/ui'; | ||
|
||
import { AssistantMessage } from './Assistant'; | ||
import { DefaultMessage } from './Default'; | ||
|
||
export const renderMessages: ChatListProps['renderMessages'] = { | ||
assistant: AssistantMessage, | ||
default: DefaultMessage, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import { useControllableValue } from 'ahooks'; | ||
import { createStyles } from 'antd-style'; | ||
import React, { memo } from 'react'; | ||
import { Flexbox } from 'react-layout-kit'; | ||
|
||
const useStyles = createStyles( | ||
({ css, token }) => css` | ||
width: ${token.controlHeight}px; | ||
height: ${token.controlHeight}px; | ||
font-size: 16px; | ||
color: ${token.colorText}; | ||
text-align: center; | ||
background: ${token.colorBgContainer}; | ||
border: 1px solid ${token.colorBorder}; | ||
border-radius: 8px; | ||
&:focus, | ||
&:focus-visible { | ||
border-color: ${token.colorPrimary}; | ||
outline: none; | ||
} | ||
`, | ||
); | ||
|
||
/** | ||
* Let's borrow some props from HTML "input". More info below: | ||
* | ||
* [Pick Documentation](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) | ||
* | ||
* [How to extend HTML Elements](https://reacthustle.com/blog/how-to-extend-html-elements-in-react-typescript) | ||
*/ | ||
type PartialInputProps = Pick<React.ComponentPropsWithoutRef<'input'>, 'className' | 'style'>; | ||
|
||
interface OtpInputProps extends PartialInputProps { | ||
onChange?: (value: string) => void; | ||
/** | ||
* Number of characters/input for this component | ||
*/ | ||
size?: number; | ||
/** | ||
* Validation pattern for each input. | ||
* e.g: /[0-9]{1}/ for digits only or /[0-9a-zA-Z]{1}/ for alphanumeric | ||
*/ | ||
validationPattern?: RegExp; | ||
/** | ||
* full value of the otp input, up to {size} characters | ||
*/ | ||
value?: string; | ||
} | ||
|
||
const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => { | ||
const current = e.currentTarget; | ||
if (e.key === 'ArrowLeft' || e.key === 'Backspace') { | ||
const prev = current.previousElementSibling as HTMLInputElement | null; | ||
prev?.focus(); | ||
prev?.setSelectionRange(0, 1); | ||
return; | ||
} | ||
|
||
if (e.key === 'ArrowRight') { | ||
const prev = current.nextSibling as HTMLInputElement | null; | ||
prev?.focus(); | ||
prev?.setSelectionRange(0, 1); | ||
return; | ||
} | ||
}; | ||
|
||
const OtpInput = memo<OtpInputProps>((props) => { | ||
const { | ||
//Set the default size to 6 characters | ||
size = 6, | ||
//Default validation is digits | ||
validationPattern = /\d/, | ||
value: outerValue, | ||
onChange, | ||
className, | ||
...restProps | ||
} = props; | ||
const [value, setValue] = useControllableValue({ onChange, value: outerValue }); | ||
|
||
const { styles, cx } = useStyles(); | ||
// Create an array based on the size. | ||
const arr = Array.from({ length: size }).fill('-'); | ||
|
||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => { | ||
const elem = e.target; | ||
const val = e.target.value; | ||
|
||
// check if the value is valid | ||
if (!validationPattern.test(val) && val !== '') return; | ||
|
||
// change the value using onChange props | ||
const valueArr = value?.split('') || []; | ||
valueArr[index] = val; | ||
const newVal = valueArr.join('').slice(0, 6); | ||
setValue(newVal); | ||
|
||
//focus the next element if there's a value | ||
if (val) { | ||
const next = elem.nextElementSibling as HTMLInputElement | null; | ||
next?.focus(); | ||
} | ||
}; | ||
|
||
const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => { | ||
e.preventDefault(); | ||
const val = e.clipboardData.getData('text').slice(0, Math.max(0, size)); | ||
|
||
setValue(val); | ||
}; | ||
|
||
return ( | ||
<Flexbox gap={12} horizontal> | ||
{arr.map((_, index) => { | ||
return ( | ||
<input | ||
key={index} | ||
{...restProps} | ||
className={cx(styles, className)} | ||
maxLength={6} | ||
onChange={(e) => handleInputChange(e, index)} | ||
onKeyUp={handleKeyUp} | ||
onPaste={handlePaste} | ||
pattern={validationPattern.source} | ||
type="text" | ||
value={value?.at(index) ?? ''} | ||
/> | ||
); | ||
})} | ||
</Flexbox> | ||
); | ||
}); | ||
|
||
export default OtpInput; |
Oops, something went wrong.