🌐 Add pt_BR and more translations (#767)
Original PR: https://github.com/baptisteArno/typebot.io/pull/694 --------- Co-authored-by: Daniel Oliveira <daniel.oliveira@kununu.com> Co-authored-by: Daniel Oliveira <daniel@headdev.com.br>
This commit is contained in:
@@ -4,6 +4,7 @@ import { TextInput } from '@/components/inputs'
|
||||
import { useState } from 'react'
|
||||
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
|
||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
|
||||
type Props = {
|
||||
fileUploadPath: string
|
||||
@@ -16,6 +17,7 @@ export const AudioBubbleForm = ({
|
||||
content,
|
||||
onContentChange,
|
||||
}: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.audio.settings')
|
||||
const [currentTab, setCurrentTab] = useState<'link' | 'upload'>('link')
|
||||
|
||||
const updateUrl = (url: string) => onContentChange({ ...content, url })
|
||||
@@ -31,14 +33,14 @@ export const AudioBubbleForm = ({
|
||||
onClick={() => setCurrentTab('upload')}
|
||||
size="sm"
|
||||
>
|
||||
Upload
|
||||
{scopedT('upload.label')}
|
||||
</Button>
|
||||
<Button
|
||||
variant={currentTab === 'link' ? 'solid' : 'ghost'}
|
||||
onClick={() => setCurrentTab('link')}
|
||||
size="sm"
|
||||
>
|
||||
Embed link
|
||||
{scopedT('embedLink.label')}
|
||||
</Button>
|
||||
</HStack>
|
||||
<Stack p="2" spacing={4}>
|
||||
@@ -51,25 +53,25 @@ export const AudioBubbleForm = ({
|
||||
onFileUploaded={updateUrl}
|
||||
colorScheme="blue"
|
||||
>
|
||||
Choose a file
|
||||
{scopedT('chooseFile.label')}
|
||||
</UploadButton>
|
||||
</Flex>
|
||||
)}
|
||||
{currentTab === 'link' && (
|
||||
<>
|
||||
<TextInput
|
||||
placeholder="Paste the audio file link..."
|
||||
placeholder={scopedT('worksWith.placeholder')}
|
||||
defaultValue={content.url ?? ''}
|
||||
onChange={updateUrl}
|
||||
/>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
Works with .MP3s and .WAVs
|
||||
{scopedT('worksWith.text')}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<SwitchWithLabel
|
||||
label={'Enable autoplay'}
|
||||
label={scopedT('autoplay.label')}
|
||||
initialValue={content.isAutoplayEnabled ?? true}
|
||||
onCheckChange={updateAutoPlay}
|
||||
/>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { Text } from '@chakra-ui/react'
|
||||
import { AudioBubbleContent } from '@typebot.io/schemas'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
|
||||
type Props = {
|
||||
url: AudioBubbleContent['url']
|
||||
}
|
||||
|
||||
export const AudioBubbleNode = ({ url }: Props) =>
|
||||
isDefined(url) ? (
|
||||
export const AudioBubbleNode = ({ url }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.audio.node')
|
||||
return isDefined(url) ? (
|
||||
<audio src={url} controls />
|
||||
) : (
|
||||
<Text color={'gray.500'}>Click to edit...</Text>
|
||||
<Text color={'gray.500'}>{scopedT('clickToEdit.text')}</Text>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { Text } from '@chakra-ui/react'
|
||||
import { EmbedBubbleBlock } from '@typebot.io/schemas'
|
||||
|
||||
export const EmbedBubbleContent = ({ block }: { block: EmbedBubbleBlock }) => {
|
||||
if (!block.content?.url) return <Text color="gray.500">Click to edit...</Text>
|
||||
return <Text>Show embed</Text>
|
||||
type Props = {
|
||||
block: EmbedBubbleBlock
|
||||
}
|
||||
|
||||
export const EmbedBubbleContent = ({ block }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.embed.node')
|
||||
if (!block.content?.url)
|
||||
return <Text color="gray.500">{scopedT('clickToEdit.text')}</Text>
|
||||
return <Text>{scopedT('show.text')}</Text>
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { TextInput, NumberInput } from '@/components/inputs'
|
||||
import { HStack, Stack, Text } from '@chakra-ui/react'
|
||||
import { EmbedBubbleContent } from '@typebot.io/schemas'
|
||||
import { sanitizeUrl } from '@typebot.io/lib'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
|
||||
type Props = {
|
||||
content: EmbedBubbleContent
|
||||
@@ -9,6 +10,7 @@ type Props = {
|
||||
}
|
||||
|
||||
export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.embed.settings')
|
||||
const handleUrlChange = (url: string) => {
|
||||
const iframeUrl = sanitizeUrl(
|
||||
url.trim().startsWith('<iframe') ? extractUrlFromIframe(url) : url
|
||||
@@ -23,12 +25,12 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
<Stack p="2" spacing={6}>
|
||||
<Stack>
|
||||
<TextInput
|
||||
placeholder="Paste the link or code..."
|
||||
placeholder={scopedT('worksWith.placeholder')}
|
||||
defaultValue={content?.url ?? ''}
|
||||
onChange={handleUrlChange}
|
||||
/>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
Works with PDFs, iframes, websites...
|
||||
{scopedT('worksWith.text')}
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
@@ -38,7 +40,7 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
|
||||
defaultValue={content?.height}
|
||||
onValueChange={handleHeightChange}
|
||||
/>
|
||||
<Text>px</Text>
|
||||
<Text>{scopedT('numberInput.unit')}</Text>
|
||||
</HStack>
|
||||
</Stack>
|
||||
)
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { Box, Text, Image } from '@chakra-ui/react'
|
||||
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
||||
|
||||
export const ImageBubbleContent = ({ block }: { block: ImageBubbleBlock }) => {
|
||||
type Props = {
|
||||
block: ImageBubbleBlock
|
||||
}
|
||||
|
||||
export const ImageBubbleContent = ({ block }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.image.node')
|
||||
const containsVariables =
|
||||
block.content?.url?.includes('{{') && block.content.url.includes('}}')
|
||||
return !block.content?.url ? (
|
||||
<Text color={'gray.500'}>Click to edit...</Text>
|
||||
<Text color={'gray.500'}>{scopedT('clickToEdit.text')}</Text>
|
||||
) : (
|
||||
<Box w="full">
|
||||
<Image
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ImageUploadContent } from '@/components/ImageUploadContent'
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { Stack } from '@chakra-ui/react'
|
||||
import { isDefined, isNotEmpty } from '@typebot.io/lib'
|
||||
import { ImageBubbleBlock } from '@typebot.io/schemas'
|
||||
@@ -17,6 +18,9 @@ export const ImageBubbleSettings = ({
|
||||
block,
|
||||
onContentChange,
|
||||
}: Props) => {
|
||||
const scopedT = useScopedI18n(
|
||||
'editor.blocks.bubbles.image.switchWithLabel.onClick'
|
||||
)
|
||||
const [showClickLinkInput, setShowClickLinkInput] = useState(
|
||||
isNotEmpty(block.content.clickLink?.url)
|
||||
)
|
||||
@@ -55,7 +59,7 @@ export const ImageBubbleSettings = ({
|
||||
/>
|
||||
<Stack>
|
||||
<SwitchWithLabel
|
||||
label={'On click link'}
|
||||
label={scopedT('label')}
|
||||
initialValue={showClickLinkInput}
|
||||
onCheckChange={toggleClickLink}
|
||||
/>
|
||||
@@ -68,7 +72,7 @@ export const ImageBubbleSettings = ({
|
||||
defaultValue={block.content.clickLink?.url}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Link alt text (description)"
|
||||
placeholder={scopedT('placeholder')}
|
||||
onChange={updateClickLinkAltText}
|
||||
defaultValue={block.content.clickLink?.alt}
|
||||
/>
|
||||
|
||||
@@ -18,6 +18,7 @@ import { colors } from '@/lib/theme'
|
||||
import { useOutsideClick } from '@/hooks/useOutsideClick'
|
||||
import { selectEditor, TElement } from '@udecode/plate-common'
|
||||
import { TextEditorToolBar } from './TextEditorToolBar'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
|
||||
type TextBubbleEditorContentProps = {
|
||||
id: string
|
||||
@@ -30,6 +31,7 @@ const TextBubbleEditorContent = ({
|
||||
textEditorValue,
|
||||
onClose,
|
||||
}: TextBubbleEditorContentProps) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles')
|
||||
const editor = usePlateEditorRef()
|
||||
const varDropdownRef = useRef<HTMLDivElement | null>(null)
|
||||
const rememberedSelection = useRef<BaseSelection | null>(null)
|
||||
@@ -108,7 +110,7 @@ const TextBubbleEditorContent = ({
|
||||
backgroundColor: useColorModeValue('white', 'gray.800'),
|
||||
borderRadius: 'md',
|
||||
transitionProperty: 'background-color',
|
||||
transitionDuration: 'normal'
|
||||
transitionDuration: 'normal',
|
||||
},
|
||||
'[class^="FloatingVerticalDivider___"]': {
|
||||
'--tw-bg-opacity': useColorModeValue('1', '.4') + '!important',
|
||||
@@ -135,7 +137,7 @@ const TextBubbleEditorContent = ({
|
||||
})
|
||||
setIsFirstFocus(false)
|
||||
},
|
||||
'aria-label': 'Text editor',
|
||||
'aria-label': `${scopedT('textEditor.plate.label')}`,
|
||||
onBlur: () => {
|
||||
rememberedSelection.current = editor?.selection
|
||||
},
|
||||
@@ -154,7 +156,7 @@ const TextBubbleEditorContent = ({
|
||||
<VariableSearchInput
|
||||
initialVariableId={undefined}
|
||||
onSelectVariable={handleVariableSelected}
|
||||
placeholder="Search for a variable"
|
||||
placeholder={scopedT('textEditor.searchVariable.placeholder')}
|
||||
autoFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import { useScopedI18n } from '@/locales'
|
||||
import { Box, Text } from '@chakra-ui/react'
|
||||
import { VideoBubbleBlock, VideoBubbleContentType } from '@typebot.io/schemas'
|
||||
|
||||
export const VideoBubbleContent = ({ block }: { block: VideoBubbleBlock }) => {
|
||||
type Props = {
|
||||
block: VideoBubbleBlock
|
||||
}
|
||||
|
||||
export const VideoBubbleContent = ({ block }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.video.node')
|
||||
if (!block.content?.url || !block.content.type)
|
||||
return <Text color="gray.500">Click to edit...</Text>
|
||||
return <Text color="gray.500">{scopedT('clickToEdit.text')}</Text>
|
||||
switch (block.content.type) {
|
||||
case VideoBubbleContentType.URL:
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Stack, Text } from '@chakra-ui/react'
|
||||
import { VideoBubbleContent, VideoBubbleContentType } from '@typebot.io/schemas'
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { useScopedI18n } from '@/locales'
|
||||
|
||||
const vimeoRegex = /vimeo\.com\/(\d+)/
|
||||
const youtubeRegex = /youtube\.com\/(watch\?v=|shorts\/)(\w+)|youtu\.be\/(\w+)/
|
||||
@@ -11,6 +12,7 @@ type Props = {
|
||||
}
|
||||
|
||||
export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
||||
const scopedT = useScopedI18n('editor.blocks.bubbles.video.settings')
|
||||
const handleUrlChange = (url: string) => {
|
||||
const info = parseVideoUrl(url)
|
||||
return onSubmit({
|
||||
@@ -22,12 +24,12 @@ export const VideoUploadContent = ({ content, onSubmit }: Props) => {
|
||||
return (
|
||||
<Stack p="2">
|
||||
<TextInput
|
||||
placeholder="Paste the video link..."
|
||||
placeholder={scopedT('worksWith.placeholder')}
|
||||
defaultValue={content?.url ?? ''}
|
||||
onChange={handleUrlChange}
|
||||
/>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
Works with Youtube, Vimeo and others
|
||||
{scopedT('worksWith.text')}
|
||||
</Text>
|
||||
</Stack>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user