| import React, { useEffect, useState } from 'react' | import React, { useEffect, useState } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import cn from 'classnames' | import cn from 'classnames' | ||||
| import copy from 'copy-to-clipboard' | |||||
| import style from './style.module.css' | import style from './style.module.css' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | |||||
| import copyStyle from '@/app/components/app/chat/copy-btn/style.module.css' | import copyStyle from '@/app/components/app/chat/copy-btn/style.module.css' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const [option, setOption] = useState<Option>('iframe') | const [option, setOption] = useState<Option>('iframe') | ||||
| const [isCopied, setIsCopied] = useState<OptionStatus>({ iframe: false, scripts: false }) | const [isCopied, setIsCopied] = useState<OptionStatus>({ iframe: false, scripts: false }) | ||||
| const [_, copy] = useCopyToClipboard() | |||||
| const { langeniusVersionInfo } = useAppContext() | const { langeniusVersionInfo } = useAppContext() | ||||
| const isTestEnv = langeniusVersionInfo.current_env === 'TESTING' || langeniusVersionInfo.current_env === 'DEVELOPMENT' | const isTestEnv = langeniusVersionInfo.current_env === 'TESTING' || langeniusVersionInfo.current_env === 'DEVELOPMENT' |
| LinkIcon, | LinkIcon, | ||||
| } from '@heroicons/react/24/outline' | } from '@heroicons/react/24/outline' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import copy from 'copy-to-clipboard' | |||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | |||||
| import './style.css' | import './style.css' | ||||
| onClose, | onClose, | ||||
| onGenerateCode, | onGenerateCode, | ||||
| }) => { | }) => { | ||||
| const [_, copy] = useCopyToClipboard() | |||||
| const [genLoading, setGenLoading] = useState(false) | const [genLoading, setGenLoading] = useState(false) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| return <Modal | return <Modal |
| import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid' | import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid' | ||||
| import useSWR, { useSWRConfig } from 'swr' | import useSWR, { useSWRConfig } from 'swr' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| import copy from 'copy-to-clipboard' | |||||
| import SecretKeyGenerateModal from './secret-key-generate' | import SecretKeyGenerateModal from './secret-key-generate' | ||||
| import s from './style.module.css' | import s from './style.module.css' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import Loading from '@/app/components/base/loading' | import Loading from '@/app/components/base/loading' | ||||
| import Confirm from '@/app/components/base/confirm' | import Confirm from '@/app/components/base/confirm' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | |||||
| import I18n from '@/context/i18n' | import I18n from '@/context/i18n' | ||||
| type ISecretKeyModalProps = { | type ISecretKeyModalProps = { | ||||
| const { data: apiKeysList } = useSWR(commonParams, fetchApiKeysList) | const { data: apiKeysList } = useSWR(commonParams, fetchApiKeysList) | ||||
| const [delKeyID, setDelKeyId] = useState('') | const [delKeyID, setDelKeyId] = useState('') | ||||
| const [_, copy] = useCopyToClipboard() | |||||
| const { locale } = useContext(I18n) | const { locale } = useContext(I18n) | ||||
| 'use client' | 'use client' | ||||
| import React, { useCallback, useEffect, useRef, useState } from 'react' | import React, { useCallback, useEffect, useRef, useState } from 'react' | ||||
| import { t } from 'i18next' | import { t } from 'i18next' | ||||
| import copy from 'copy-to-clipboard' | |||||
| import s from './index.module.css' | import s from './index.module.css' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | |||||
| import { randomString } from '@/app/components/app-sidebar/basic' | import { randomString } from '@/app/components/app-sidebar/basic' | ||||
| type IInvitationLinkProps = { | type IInvitationLinkProps = { | ||||
| }: IInvitationLinkProps) => { | }: IInvitationLinkProps) => { | ||||
| const [isCopied, setIsCopied] = useState(false) | const [isCopied, setIsCopied] = useState(false) | ||||
| const selector = useRef(`invite-link-${randomString(4)}`) | const selector = useRef(`invite-link-${randomString(4)}`) | ||||
| const [_, copy] = useCopyToClipboard() | |||||
| const copyHandle = useCallback(() => { | const copyHandle = useCallback(() => { | ||||
| copy(value) | copy(value) | ||||
| setIsCopied(true) | setIsCopied(true) | ||||
| }, [value, copy]) | |||||
| }, [value]) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (isCopied) { | if (isCopied) { |
| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { ClipboardDocumentIcon, HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline' | import { ClipboardDocumentIcon, HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline' | ||||
| import { Feedbacktype } from '@/app/components/app/chat' | |||||
| import copy from 'copy-to-clipboard' | |||||
| import type { Feedbacktype } from '@/app/components/app/chat/type' | |||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| // import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | |||||
| import copy from 'copy-to-clipboard' | |||||
| type IResultHeaderProps = { | type IResultHeaderProps = { | ||||
| result: string | result: string | ||||
| showFeedback: boolean | showFeedback: boolean | ||||
| <div | <div | ||||
| onClick={() => { | onClick={() => { | ||||
| onFeedback({ | onFeedback({ | ||||
| rating: null | |||||
| rating: null, | |||||
| }) | }) | ||||
| }} | }} | ||||
| className='flex w-7 h-7 items-center justify-center rounded-md cursor-pointer !text-primary-600 border border-primary-200 bg-primary-100 hover:border-primary-300 hover:bg-primary-200'> | className='flex w-7 h-7 items-center justify-center rounded-md cursor-pointer !text-primary-600 border border-primary-200 bg-primary-100 hover:border-primary-300 hover:bg-primary-200'> | ||||
| <div | <div | ||||
| onClick={() => { | onClick={() => { | ||||
| onFeedback({ | onFeedback({ | ||||
| rating: null | |||||
| rating: null, | |||||
| }) | }) | ||||
| }} | }} | ||||
| className='flex w-7 h-7 items-center justify-center rounded-md cursor-pointer !text-red-600 border border-red-200 bg-red-100 hover:border-red-300 hover:bg-red-200'> | className='flex w-7 h-7 items-center justify-center rounded-md cursor-pointer !text-red-600 border border-red-200 bg-red-100 hover:border-red-300 hover:bg-red-200'> | ||||
| <div | <div | ||||
| onClick={() => { | onClick={() => { | ||||
| onFeedback({ | onFeedback({ | ||||
| rating: 'like' | |||||
| rating: 'like', | |||||
| }) | }) | ||||
| }} | }} | ||||
| className='flex w-6 h-6 items-center justify-center rounded-md cursor-pointer hover:bg-gray-100'> | className='flex w-6 h-6 items-center justify-center rounded-md cursor-pointer hover:bg-gray-100'> | ||||
| <div | <div | ||||
| onClick={() => { | onClick={() => { | ||||
| onFeedback({ | onFeedback({ | ||||
| rating: 'dislike' | |||||
| rating: 'dislike', | |||||
| }) | }) | ||||
| }} | }} | ||||
| className='flex w-6 h-6 items-center justify-center rounded-md cursor-pointer hover:bg-gray-100'> | className='flex w-6 h-6 items-center justify-center rounded-md cursor-pointer hover:bg-gray-100'> |
| import { useCallback, useState } from 'react' | |||||
| import writeText from 'copy-to-clipboard' | |||||
| type CopiedValue = string | null | |||||
| type CopyFn = (text: string) => Promise<boolean> | |||||
| function useCopyToClipboard(): [CopiedValue, CopyFn] { | |||||
| const [copiedText, setCopiedText] = useState<CopiedValue>(null) | |||||
| const copy: CopyFn = useCallback(async (text: string) => { | |||||
| try { | |||||
| writeText(text) | |||||
| setCopiedText(text) | |||||
| return true | |||||
| } | |||||
| catch (error) { | |||||
| console.warn('Copy failed', error) | |||||
| setCopiedText(null) | |||||
| return false | |||||
| } | |||||
| }, []) | |||||
| return [copiedText, copy] | |||||
| } | |||||
| export default useCopyToClipboard |