index.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import {
  5. RiClipboardLine,
  6. RiDeleteBinLine,
  7. } from '@remixicon/react'
  8. import { useTranslation } from 'react-i18next'
  9. import copy from 'copy-to-clipboard'
  10. import NoData from './no-data'
  11. import cn from '@/utils/classnames'
  12. import type { SavedMessage } from '@/models/debug'
  13. import { Markdown } from '@/app/components/base/markdown'
  14. import Toast from '@/app/components/base/toast'
  15. import ActionButton from '@/app/components/base/action-button'
  16. import NewAudioButton from '@/app/components/base/new-audio-button'
  17. export type ISavedItemsProps = {
  18. className?: string
  19. isShowTextToSpeech?: boolean
  20. list: SavedMessage[]
  21. onRemove: (id: string) => void
  22. onStartCreateContent: () => void
  23. }
  24. const SavedItems: FC<ISavedItemsProps> = ({
  25. className,
  26. isShowTextToSpeech,
  27. list,
  28. onRemove,
  29. onStartCreateContent,
  30. }) => {
  31. const { t } = useTranslation()
  32. return (
  33. <div className={cn('space-y-4', className)}>
  34. {list.length === 0
  35. ? (
  36. <NoData onStartCreateContent={onStartCreateContent} />
  37. )
  38. : (<>
  39. {list.map(({ id, answer }) => (
  40. <div key={id} className='relative'>
  41. <div className={cn(
  42. 'p-4 bg-background-section-burn rounded-2xl',
  43. )}>
  44. <Markdown content={answer} />
  45. </div>
  46. <div className='mt-1 h-4 px-4 text-text-quaternary system-xs-regular'>
  47. <span>{answer.length} {t('common.unit.char')}</span>
  48. </div>
  49. <div className='absolute right-2 bottom-1'>
  50. <div className='ml-1 flex items-center gap-0.5 p-0.5 rounded-[10px] border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg shadow-md backdrop-blur-sm'>
  51. {isShowTextToSpeech && <NewAudioButton value={answer}/>}
  52. <ActionButton onClick={() => {
  53. copy(answer)
  54. Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
  55. }}>
  56. <RiClipboardLine className='w-4 h-4' />
  57. </ActionButton>
  58. <ActionButton onClick={() => {
  59. onRemove(id)
  60. }}>
  61. <RiDeleteBinLine className='w-4 h-4' />
  62. </ActionButton>
  63. </div>
  64. </div>
  65. </div>
  66. ))}
  67. </>)}
  68. </div>
  69. )
  70. }
  71. export default React.memo(SavedItems)