2
0

Add more video supports (#1023)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
	- Introduced a new layout option for the TextInput component.
- Added support for GUMLET and TIKTOK video content types in
VideoBubbleContent.
- Enhanced VideoUploadContent to handle new properties like aspectRatio
and maxWidth.
- Updated VideoBubble to include aspect-ratio and max-width styles based
on content properties.
- **Refactor**
- Changed the extension used for internationalization (i18n) in the VS
Code environment.
	- Modified how environment variables are accessed in tolgee.tsx.
- Updated parseVideoUrl function to include a new property
videoSizeSuggestion.
- **Chores**
- Updated the tolgeeEnv object in env.ts and added a new optional
parameter to the getRuntimeVariable function.
- Expanded video handling capabilities by introducing new video content
types and associated regular expressions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Closes #978 #936 #926
This commit is contained in:
Baptiste Arnaud
2023-11-10 11:17:14 +01:00
committed by GitHub
parent df578417aa
commit dd4de582a9
20 changed files with 306 additions and 143 deletions

View File

@ -4,7 +4,7 @@
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"unifiedjs.vscode-mdx",
"baptistearno.baptistearno-i18n-ally",
"lokalise.i18n-ally",
"ms-playwright.playwright",
"Prisma.prisma"
]

View File

@ -20,8 +20,8 @@ usageMatchRegex:
# The "$1" will be replaced by the keypath specified.
# Optional: uncomment the following two lines to use
# refactorTemplates:
# - i18n.get("$1")
refactorTemplates:
- t("$1")
# If set to true, only enables this custom framework (will disable all built-in frameworks)
monopoly: true

View File

@ -110,41 +110,35 @@
"billing.usage.chats.heading": "Chats",
"billing.usage.heading": "Nutzung",
"billing.usage.unlimited": "Unbegrenzt",
"blocks.bubbles.embed.blockCard.tooltip": "Ein PDF, ein iframe, eine Website einbetten...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Dateien hochladen",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Tabellen",
"cancel": "Abbrechen",
"clickToEdit": "Zum Bearbeiten klicken...",
"confirmModal.defaultTitle": "Bist du sicher?",
"dashboard.header.settingsButton.label": "Einstellungen & Mitglieder",
"dashboard.redirectionMessage": "Du wirst weitergeleitet...",
"dashboard.title": "Meine Typebots",
"delete": "Löschen",
"downgrade": "Downgrade",
"blocks.bubbles.embed.blockCard.tooltip": "Ein PDF, ein iframe, eine Website einbetten...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Dateien hochladen",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Tabellen",
"editor.blockCard.logicBlock.tooltip.code.label": "JavaScript-Code ausführen",
"editor.blockCard.logicBlock.tooltip.jump.label": "Ablauf zu einer anderen Gruppe beschleunigen",
"editor.blockCard.logicBlock.tooltip.typebotLink.label": "Verlinkung zu einem anderen Typebot",
"editor.blocks.bubbles.audio.node.clickToEdit.text": "Zum Bearbeiten klicken...",
"editor.blocks.bubbles.audio.settings.autoplay.label": "Autoplay aktivieren",
"editor.blocks.bubbles.audio.settings.chooseFile.label": "Datei auswählen",
"editor.blocks.bubbles.audio.settings.embedLink.label": "Link einbetten",
"editor.blocks.bubbles.audio.settings.upload.label": "Hochladen",
"editor.blocks.bubbles.audio.settings.worksWith.placeholder": "Füge den Audio-Dateilink ein...",
"editor.blocks.bubbles.audio.settings.worksWith.text": "Funktioniert mit .MP3- und .WAV-Dateien",
"editor.blocks.bubbles.embed.node.clickToEdit.text": "Zum Bearbeiten klicken...",
"editor.blocks.bubbles.embed.node.show.text": "Einbetten anzeigen",
"editor.blocks.bubbles.embed.settings.numberInput.unit": "px",
"editor.blocks.bubbles.embed.settings.worksWith.placeholder": "Füge den Link oder Code ein...",
"editor.blocks.bubbles.embed.settings.worksWith.text": "Funktioniert mit PDFs, iframes, Websites...",
"editor.blocks.bubbles.image.node.clickToEdit.text": "Zum Bearbeiten klicken...",
"editor.blocks.bubbles.image.switchWithLabel.onClick.label": "Beim Klicken Link",
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Link Alternativtext (Beschreibung)",
"editor.blocks.bubbles.textEditor.plate.label": "Texteditor",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Nach einer Variable suchen",
"editor.blocks.bubbles.video.node.clickToEdit.text": "Zum Bearbeiten klicken...",
"editor.blocks.bubbles.video.settings.numberInput.unit": "px",
"editor.blocks.bubbles.video.settings.worksWith.placeholder": "Füge den Videolink ein...",
"editor.blocks.bubbles.video.settings.worksWith.text": "Funktioniert mit YouTube, Vimeo und anderen",
"editor.blocks.start.text": "Start",
"editor.editableTypebotName.tooltip.rename.label": "Umbenennen",
"editor.gettingStartedModal.editorBasics.heading": "Grundlagen des Editors",
@ -231,6 +225,8 @@
"templates.modal.menuHeading.product": "Produkt",
"templates.modal.useTemplateButton.label": "Diese Vorlage verwenden",
"upgrade": "Upgrade",
"video.urlInput.helperText": "Funktioniert mit YouTube, Vimeo, Gumlet, TikTok und anderen",
"video.urlInput.placeholder": "Füge den Videolink ein...",
"workspace.dropdown.logoutButton.label": "Abmelden",
"workspace.dropdown.newButton.label": "Neuer Workspace",
"workspace.membersList.inviteButton.label": "Einladen",

View File

@ -29,7 +29,7 @@
"account.preferences.graphNavigation.trackpad.description": "Move the board using 2 fingers and zoom in/out by pinching",
"account.preferences.graphNavigation.trackpad.label": "Trackpad",
"account.preferences.language.heading": "Language",
"account.preferences.language.tooltip": "The translations are not complete yet. It is a work in progress. 🤓",
"account.preferences.language.tooltip": "The translations are not complete yet. It is a work in progress. \uD83E\uDD13",
"analytics.completionRateLabel": "Completion rate",
"analytics.notAvailableLabel": "Not available",
"analytics.startsLabel": "Starts",
@ -40,7 +40,7 @@
"auth.error.oauthNotLinked": "To confirm your identity, sign in with the same account you used originally.",
"auth.error.unknown": "An error occurred. Please try again.",
"auth.magicLink.description": "Make sure to check your spam folder.",
"auth.magicLink.title": "A magic link email was sent. 🪄",
"auth.magicLink.title": "A magic link email was sent. \uD83E\uDE84",
"auth.noProvider.link": "configure at least one auth provider (Email, Google, GitHub, Facebook or Azure AD).",
"auth.noProvider.preLink": "You need to",
"auth.orEmailLabel": "Or with your email",
@ -102,54 +102,49 @@
"billing.pricingCard.starter.fileUploadBlock": "File upload input block",
"billing.pricingCard.starter.includedSeats": "2 seats included",
"billing.pricingCard.upgradeButton.current": "Your current plan",
"billing.updateSuccessToast.description": "Workspace {plan} plan successfully updated 🎉",
"billing.tiersModal.heading": "Chats pricing table",
"billing.updateSuccessToast.description": "Workspace {plan} plan successfully updated \uD83C\uDF89",
"billing.upgradeAlert.buttonDefaultLabel": "More info",
"billing.upgradeLimitLabel": "You need to upgrade your plan in order to {type}",
"billing.usage.chats.alert.soonReach": "Your typebots are popular! You will soon reach your plan's chats limit. 🚀",
"billing.usage.chats.alert.soonReach": "Your typebots are popular! You will soon reach your plan's chats limit. \uD83D\uDE80",
"billing.usage.chats.alert.updatePlan": "Make sure to update your plan to increase this limit and continue chatting with your users.",
"billing.usage.chats.heading": "Chats",
"billing.usage.heading": "Usage",
"billing.usage.unlimited": "Unlimited",
"blocks.bubbles.embed.blockCard.tooltip": "Embed a pdf, an iframe, a website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Upload Files",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Cancel",
"clickToEdit": "Click to edit...",
"confirmModal.defaultTitle": "Are you sure?",
"dashboard.header.settingsButton.label": "Settings & Members",
"dashboard.redirectionMessage": "You are being redirected...",
"dashboard.title": "My typebots",
"delete": "Delete",
"downgrade": "Downgrade",
"blocks.bubbles.embed.blockCard.tooltip": "Embed a pdf, an iframe, a website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Upload Files",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"editor.blockCard.logicBlock.tooltip.code.label": "Execute Javascript code",
"editor.blockCard.logicBlock.tooltip.jump.label": "Fast forward the flow to another group",
"editor.blockCard.logicBlock.tooltip.typebotLink.label": "Link and jump to another typebot",
"editor.blocks.bubbles.audio.node.clickToEdit.text": "Click to edit...",
"editor.blocks.bubbles.audio.settings.autoplay.label": "Enable autoplay",
"editor.blocks.bubbles.audio.settings.chooseFile.label": "Choose a file",
"editor.blocks.bubbles.audio.settings.embedLink.label": "Embed link",
"editor.blocks.bubbles.audio.settings.upload.label": "Upload",
"editor.blocks.bubbles.audio.settings.worksWith.placeholder": "Paste the audio file link...",
"editor.blocks.bubbles.audio.settings.worksWith.text": "Works with .MP3s and .WAVs",
"editor.blocks.bubbles.embed.node.clickToEdit.text": "Click to edit...",
"editor.blocks.bubbles.embed.node.show.text": "Show embed",
"editor.blocks.bubbles.embed.settings.numberInput.unit": "px",
"editor.blocks.bubbles.embed.settings.worksWith.placeholder": "Paste the link or code...",
"editor.blocks.bubbles.embed.settings.worksWith.text": "Works with PDFs, iframes, websites...",
"editor.blocks.bubbles.image.node.clickToEdit.text": "Click to edit...",
"editor.blocks.bubbles.image.switchWithLabel.onClick.label": "On click link",
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Link alt text (description)",
"editor.blocks.bubbles.textEditor.plate.label": "Text editor",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Search for a variable",
"editor.blocks.bubbles.video.node.clickToEdit.text": "Click to edit...",
"editor.blocks.bubbles.video.settings.numberInput.unit": "px",
"editor.blocks.bubbles.video.settings.worksWith.placeholder": "Paste the video link...",
"editor.blocks.bubbles.video.settings.worksWith.text": "Works with Youtube, Vimeo and others",
"editor.blocks.start.text": "Start",
"editor.editableTypebotName.tooltip.rename.label": "Rename",
"editor.gettingStartedModal.editorBasics.heading": "Editor Basics",
"editor.gettingStartedModal.editorBasics.list.four.label": "Preview your bot by clicking the preview button on the top right",
"editor.gettingStartedModal.editorBasics.list.label": "Feel free to use the bottom-right bubble to reach out if you have any question. I usually answer within the next 24 hours. 😃",
"editor.gettingStartedModal.editorBasics.list.label": "Feel free to use the bottom-right bubble to reach out if you have any question. I usually answer within the next 24 hours. \uD83D\uDE03",
"editor.gettingStartedModal.editorBasics.list.one.label": "The left side bar contains blocks that you can drag and drop to the board.",
"editor.gettingStartedModal.editorBasics.list.three.label": "Connect the groups together",
"editor.gettingStartedModal.editorBasics.list.two.label": "You can group blocks together by dropping them below or above each other",
@ -231,12 +226,18 @@
"templates.modal.menuHeading.product": "Product",
"templates.modal.useTemplateButton.label": "Use this template",
"upgrade": "Upgrade",
"video.aspectRatioInput.label": "Aspect ratio",
"video.aspectRatioInput.moreInfoTooltip": "Example: \"16/9\" or \"9/16",
"video.maxWidthInput.label": "Max width",
"video.maxWidthInput.moreInfoTooltip": "Example: \"300px\" or \"100%",
"video.urlInput.helperText": "Works with Youtube, Vimeo, Gumlet, TikTok and others",
"video.urlInput.placeholder": "Paste the video link...",
"workspace.dropdown.logoutButton.label": "Log out",
"workspace.dropdown.newButton.label": "New workspace",
"workspace.membersList.inviteButton.label": "Invite",
"workspace.membersList.inviteInput.placeholder": "colleague@company.com",
"workspace.membersList.title": "Members",
"workspace.membersList.unlockBanner.label": "Upgrade your plan to work with more team members, and unlock awesome power features 🚀",
"workspace.membersList.unlockBanner.label": "Upgrade your plan to work with more team members, and unlock awesome power features \uD83D\uDE80",
"workspace.settings.deleteButton.confirmMessage": "Are you sure you want to delete {workspaceName} workspace? All its folders, typebots and results will be deleted forever.",
"workspace.settings.deleteButton.label": "Delete workspace",
"workspace.settings.icon.title": "Icon",
@ -247,6 +248,5 @@
"workspace.settings.modal.menu.settings.label": "Settings",
"workspace.settings.modal.menu.version.label": "Version: {version}",
"workspace.settings.modal.menu.workspace.label": "Workspace",
"workspace.settings.name.label": "Name:",
"billing.tiersModal.heading": "Chats pricing table"
"workspace.settings.name.label": "Name:"
}

View File

@ -102,6 +102,7 @@
"billing.pricingCard.starter.fileUploadBlock": "Bloc d'upload de fichier",
"billing.pricingCard.starter.includedSeats": "2 collègues inclus",
"billing.pricingCard.upgradeButton.current": "Abonnement actuel",
"billing.tiersModal.heading": "Table des prix des chats",
"billing.updateSuccessToast.description": "Ton abonnement {plan} a été mis à jour avec succès \uD83C\uDF89",
"billing.upgradeAlert.buttonDefaultLabel": "Plus d'informations",
"billing.upgradeLimitLabel": "Tu dois mettre à niveau ton abonnement pour {type}",
@ -110,41 +111,35 @@
"billing.usage.chats.heading": "Chats",
"billing.usage.heading": "Utilisation",
"billing.usage.unlimited": "Illimité",
"blocks.bubbles.embed.blockCard.tooltip": "Intégrer un pdf, un iframe, un site web...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Télécharger des fichiers",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Annuler",
"clickToEdit": "Clique pour modifier...",
"confirmModal.defaultTitle": "Es-tu sûr ?",
"dashboard.header.settingsButton.label": "Paramètres & Membres",
"dashboard.redirectionMessage": "Redirection en cours...",
"dashboard.title": "Mes typebots",
"delete": "Supprimer",
"downgrade": "Downgrade",
"blocks.bubbles.embed.blockCard.tooltip": "Intégrer un pdf, un iframe, un site web...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Télécharger des fichiers",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"editor.blockCard.logicBlock.tooltip.code.label": "Exécuter du code Javascript",
"editor.blockCard.logicBlock.tooltip.jump.label": "Passer rapidement au groupe suivant",
"editor.blockCard.logicBlock.tooltip.typebotLink.label": "Lier et exécuter un autre typebot",
"editor.blocks.bubbles.audio.node.clickToEdit.text": "Cliquez pour modifier...",
"editor.blocks.bubbles.audio.settings.autoplay.label": "Activer la lecture automatique",
"editor.blocks.bubbles.audio.settings.chooseFile.label": "Choisir un fichier",
"editor.blocks.bubbles.audio.settings.embedLink.label": "Lien intégré",
"editor.blocks.bubbles.audio.settings.upload.label": "Uploader",
"editor.blocks.bubbles.audio.settings.worksWith.placeholder": "Collez le lien du fichier audio...",
"editor.blocks.bubbles.audio.settings.worksWith.text": "Fonctionne avec les fichiers .MP3 et .WAV",
"editor.blocks.bubbles.embed.node.clickToEdit.text": "Cliquez pour modifier...",
"editor.blocks.bubbles.embed.node.show.text": "Afficher l'intégration",
"editor.blocks.bubbles.embed.settings.numberInput.unit": "px",
"editor.blocks.bubbles.embed.settings.worksWith.placeholder": "Collez le lien ou le code...",
"editor.blocks.bubbles.embed.settings.worksWith.text": "Fonctionne avec les PDF, les iframes, les sites web...",
"editor.blocks.bubbles.image.node.clickToEdit.text": "Cliquez pour modifier...",
"editor.blocks.bubbles.image.switchWithLabel.onClick.label": "Redirection au clic",
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Texte alternatif du lien (description)",
"editor.blocks.bubbles.textEditor.plate.label": "Éditeur de texte",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Rechercher une variable",
"editor.blocks.bubbles.video.node.clickToEdit.text": "Cliquez pour modifier...",
"editor.blocks.bubbles.video.settings.numberInput.unit": "px",
"editor.blocks.bubbles.video.settings.worksWith.placeholder": "Collez le lien de la vidéo...",
"editor.blocks.bubbles.video.settings.worksWith.text": "Fonctionne avec Youtube, Vimeo et autres",
"editor.blocks.start.text": "Démarrer",
"editor.editableTypebotName.tooltip.rename.label": "Renommer",
"editor.gettingStartedModal.editorBasics.heading": "Principes de base de l'éditeur",
@ -231,6 +226,12 @@
"templates.modal.menuHeading.product": "Produit",
"templates.modal.useTemplateButton.label": "Utiliser ce modèle",
"upgrade": "Upgrade",
"video.aspectRatioInput.label": "Ratio",
"video.aspectRatioInput.moreInfoTooltip": "Exemple: \"16/9\" ou \"9/16\"",
"video.maxWidthInput.label": "Largeur max",
"video.maxWidthInput.moreInfoTooltip": "Exemple: \"300px\" ou \"100%\"",
"video.urlInput.helperText": "Fonctionne avec Youtube, Vimeo, Gumlet, TikTok et autres",
"video.urlInput.placeholder": "Collez le lien de la vidéo...",
"workspace.dropdown.logoutButton.label": "Déconnexion",
"workspace.dropdown.newButton.label": "Nouveau workspace",
"workspace.membersList.inviteButton.label": "Inviter",

View File

@ -102,6 +102,7 @@
"billing.pricingCard.starter.fileUploadBlock": "Bloco de envio de arquivo",
"billing.pricingCard.starter.includedSeats": "2 assentos incluídos",
"billing.pricingCard.upgradeButton.current": "Sua assinatura atual",
"billing.tiersModal.heading": "Tabela de preço de chats",
"billing.updateSuccessToast.description": "Sua assinatura {plan} foi atualizada com sucesso \uD83C\uDF89",
"billing.upgradeAlert.buttonDefaultLabel": "Mais informações",
"billing.upgradeLimitLabel": "Você precisa atualizar sua assinatura para {type}",
@ -110,41 +111,35 @@
"billing.usage.chats.heading": "Chats",
"billing.usage.heading": "Uso",
"billing.usage.unlimited": "Ilimitado",
"blocks.bubbles.embed.blockCard.tooltip": "Incorporar pdf, iframe, website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Carregar Ficheiros",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Cancelar",
"clickToEdit": "Clique para editar...",
"confirmModal.defaultTitle": "Tem certeza?",
"dashboard.header.settingsButton.label": "Configurações & Membros",
"dashboard.redirectionMessage": "Você está sendo redirecionado...",
"dashboard.title": "Meus typebots",
"delete": "Apagar",
"downgrade": "Downgrade",
"blocks.bubbles.embed.blockCard.tooltip": "Incorporar pdf, iframe, website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Carregar Ficheiros",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"editor.blockCard.logicBlock.tooltip.code.label": "Executar código Javascript",
"editor.blockCard.logicBlock.tooltip.jump.label": "Encaminhar fluxo para outro grupo",
"editor.blockCard.logicBlock.tooltip.typebotLink.label": "Link e salte para outro typebot",
"editor.blocks.bubbles.audio.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.audio.settings.autoplay.label": "Ativar reprodução automática",
"editor.blocks.bubbles.audio.settings.chooseFile.label": "Escolher um arquivo",
"editor.blocks.bubbles.audio.settings.embedLink.label": "Incorporar link",
"editor.blocks.bubbles.audio.settings.upload.label": "Carregar",
"editor.blocks.bubbles.audio.settings.worksWith.placeholder": "Colar o link do arquivo de áudio...",
"editor.blocks.bubbles.audio.settings.worksWith.text": "Compatível com .MP3s e .WAVs",
"editor.blocks.bubbles.embed.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.embed.node.show.text": "Mostrar incorporação",
"editor.blocks.bubbles.embed.settings.numberInput.unit": "px",
"editor.blocks.bubbles.embed.settings.worksWith.placeholder": "Colar o link ou código...",
"editor.blocks.bubbles.embed.settings.worksWith.text": "Compatível com PDFs, iframes, websites...",
"editor.blocks.bubbles.image.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.image.switchWithLabel.onClick.label": "Link ao clicar",
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Texto alternativo do link (descrição)",
"editor.blocks.bubbles.textEditor.plate.label": "Editor de texto",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Pesquisar uma variável",
"editor.blocks.bubbles.video.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.video.settings.numberInput.unit": "px",
"editor.blocks.bubbles.video.settings.worksWith.placeholder": "Colar o link do vídeo...",
"editor.blocks.bubbles.video.settings.worksWith.text": "Compatível com Youtube, Vimeo e outros",
"editor.blocks.start.text": "Início",
"editor.editableTypebotName.tooltip.rename.label": "Renomear",
"editor.gettingStartedModal.editorBasics.heading": "Fundamentos do Editor",
@ -231,6 +226,8 @@
"templates.modal.menuHeading.product": "Produto",
"templates.modal.useTemplateButton.label": "Usar esse modelo",
"upgrade": "Upgrade",
"video.urlInput.helperText": "Compatível com Youtube, Vimeo, Gumlet, TikTok e outros",
"video.urlInput.placeholder": "Colar o link do vídeo...",
"workspace.dropdown.logoutButton.label": "Sair",
"workspace.dropdown.newButton.label": "Novo espaço de trabalho",
"workspace.membersList.inviteButton.label": "Convidar",

View File

@ -110,41 +110,35 @@
"billing.usage.chats.heading": "Chats",
"billing.usage.heading": "Uso",
"billing.usage.unlimited": "Ilimitado",
"blocks.bubbles.embed.blockCard.tooltip": "Incorporar pdf, iframe, website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Carregar Ficheiros",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"cancel": "Cancelar",
"clickToEdit": "Clique para editar...",
"confirmModal.defaultTitle": "Tem a certeza?",
"dashboard.header.settingsButton.label": "Configurações & Membros",
"dashboard.redirectionMessage": "Está a ser redirecionado...",
"dashboard.title": "Os meus typebots",
"delete": "Apagar",
"downgrade": "Downgrade",
"blocks.bubbles.embed.blockCard.tooltip": "Incorporar pdf, iframe, website...",
"blocks.inputs.fileUpload.blockCard.tooltip": "Carregar Ficheiros",
"blocks.integrations.googleAnalytics.blockCard.tooltip": "Google Analytics",
"blocks.integrations.googleSheets.blockCard.tooltip": "Google Sheets",
"editor.blockCard.logicBlock.tooltip.code.label": "Executar código Javascript",
"editor.blockCard.logicBlock.tooltip.jump.label": "Encaminhar fluxo para outro grupo",
"editor.blockCard.logicBlock.tooltip.typebotLink.label": "Link e salte para outro typebot",
"editor.blocks.bubbles.audio.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.audio.settings.autoplay.label": "Ativar reprodução automática",
"editor.blocks.bubbles.audio.settings.chooseFile.label": "Escolher um ficheiro",
"editor.blocks.bubbles.audio.settings.embedLink.label": "Incorporar link",
"editor.blocks.bubbles.audio.settings.upload.label": "Carregar",
"editor.blocks.bubbles.audio.settings.worksWith.placeholder": "Colar o link do ficheiro de áudio...",
"editor.blocks.bubbles.audio.settings.worksWith.text": "Compatível com .MP3s e .WAVs",
"editor.blocks.bubbles.embed.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.embed.node.show.text": "Mostrar incorporação",
"editor.blocks.bubbles.embed.settings.numberInput.unit": "px",
"editor.blocks.bubbles.embed.settings.worksWith.placeholder": "Colar o link ou código...",
"editor.blocks.bubbles.embed.settings.worksWith.text": "Compatível com PDFs, iframes, websites...",
"editor.blocks.bubbles.image.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.image.switchWithLabel.onClick.label": "Link ao clicar",
"editor.blocks.bubbles.image.switchWithLabel.onClick.placeholder": "Texto alternativo do link (descrição)",
"editor.blocks.bubbles.textEditor.plate.label": "Editor de texto",
"editor.blocks.bubbles.textEditor.searchVariable.placeholder": "Pesquisar uma variável",
"editor.blocks.bubbles.video.node.clickToEdit.text": "Clique para editar...",
"editor.blocks.bubbles.video.settings.numberInput.unit": "px",
"editor.blocks.bubbles.video.settings.worksWith.placeholder": "Colar o link do vídeo...",
"editor.blocks.bubbles.video.settings.worksWith.text": "Compatível com Youtube, Vimeo e outros",
"editor.blocks.start.text": "Começar",
"editor.editableTypebotName.tooltip.rename.label": "Renomear",
"editor.gettingStartedModal.editorBasics.heading": "Noções básicas de editor",
@ -231,6 +225,8 @@
"templates.modal.menuHeading.product": "Produto",
"templates.modal.useTemplateButton.label": "Usar este modelo",
"upgrade": "Upgrade",
"video.urlInput.helperText": "Compatível com Youtube, Vimeo, Gumlet, TikTok e outros",
"video.urlInput.placeholder": "Colar o link do vídeo...",
"workspace.dropdown.logoutButton.label": "Sair",
"workspace.dropdown.newButton.label": "Novo espaço de trabalho",
"workspace.membersList.inviteButton.label": "Convidar",

View File

@ -8,6 +8,7 @@ import {
HStack,
Input as ChakraInput,
InputProps,
Stack,
} from '@chakra-ui/react'
import { Variable } from '@typebot.io/schemas'
import React, {
@ -33,6 +34,7 @@ export type TextInputProps = {
isRequired?: boolean
placeholder?: string
isDisabled?: boolean
direction?: 'row' | 'column'
} & Pick<
InputProps,
| 'autoComplete'
@ -63,6 +65,7 @@ export const TextInput = forwardRef(function TextInput(
onKeyUp,
size,
maxWidth,
direction = 'column',
}: TextInputProps,
ref
) {
@ -134,9 +137,15 @@ export const TextInput = forwardRef(function TextInput(
)
return (
<FormControl isRequired={isRequired}>
<FormControl
isRequired={isRequired}
as={direction === 'column' ? Stack : HStack}
justifyContent="space-between"
width={label ? 'full' : 'auto'}
spacing={direction === 'column' ? 2 : 3}
>
{label && (
<FormLabel>
<FormLabel display="flex" flexShrink={0} gap="1" mb="0" mr="0">
{label}{' '}
{moreInfoTooltip && (
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>

View File

@ -1,7 +1,10 @@
import { useTranslate } from '@tolgee/react'
import { Box, Text, Image } from '@chakra-ui/react'
import { VideoBubbleBlock } from '@typebot.io/schemas'
import { VideoBubbleContentType } from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
import {
VideoBubbleContentType,
embedBaseUrls,
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
type Props = {
block: VideoBubbleBlock
@ -45,17 +48,32 @@ export const VideoBubbleContent = ({ block }: Props) => {
)}
</Box>
)
case VideoBubbleContentType.GUMLET:
case VideoBubbleContentType.VIMEO:
case VideoBubbleContentType.YOUTUBE: {
const baseUrl =
block.content.type === VideoBubbleContentType.VIMEO
? 'https://player.vimeo.com/video'
: 'https://www.youtube.com/embed'
const baseUrl = embedBaseUrls[block.content.type]
return (
<Box w="full" h="120px" pos="relative">
<iframe
src={`${baseUrl}/${block.content.id}`}
allowFullScreen
style={{
width: '100%',
height: '100%',
position: 'absolute',
left: '0',
top: '0',
borderRadius: '10px',
pointerEvents: 'none',
}}
/>
</Box>
)
}
case VideoBubbleContentType.TIKTOK: {
return (
<Box w="full" h="300px" pos="relative">
<iframe
src={`https://www.tiktok.com/embed/v2/${block.content.id}`}
style={{
width: '100%',
height: '100%',

View File

@ -1,12 +1,9 @@
import { Stack, Text } from '@chakra-ui/react'
import { VariableString, VideoBubbleBlock } from '@typebot.io/schemas'
import { NumberInput, TextInput } from '@/components/inputs'
import { VideoBubbleBlock } from '@typebot.io/schemas'
import { TextInput } from '@/components/inputs'
import { useTranslate } from '@tolgee/react'
import { parseVideoUrl } from '@typebot.io/lib/parseVideoUrl'
import {
VideoBubbleContentType,
defaultVideoBubbleContent,
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
import { defaultVideoBubbleContent } from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
type Props = {
content?: VideoBubbleBlock['content']
@ -16,42 +13,69 @@ type Props = {
export const VideoUploadContent = ({ content, onSubmit }: Props) => {
const { t } = useTranslate()
const updateUrl = (url: string) => {
const info = parseVideoUrl(url)
return onSubmit({
type: info.type,
url,
id: info.id,
})
}
const updateHeight = (height?: number | VariableString) => {
const {
type,
url: matchedUrl,
id,
videoSizeSuggestion,
} = parseVideoUrl(url)
return onSubmit({
...content,
height,
type,
url: matchedUrl,
id,
...(!content?.aspectRatio && !content?.maxWidth
? videoSizeSuggestion
: {}),
})
}
const updateAspectRatio = (aspectRatio?: string) => {
return onSubmit({
...content,
aspectRatio,
})
}
const updateMaxWidth = (maxWidth?: string) => {
return onSubmit({
...content,
maxWidth,
})
}
return (
<Stack p="2" spacing={4}>
<Stack>
<TextInput
placeholder={t(
'editor.blocks.bubbles.video.settings.worksWith.placeholder'
)}
placeholder={t('video.urlInput.placeholder')}
defaultValue={content?.url ?? ''}
onChange={updateUrl}
/>
<Text fontSize="sm" color="gray.400" textAlign="center">
{t('editor.blocks.bubbles.video.settings.worksWith.text')}
<Text fontSize="xs" color="gray.400" textAlign="center">
{t('video.urlInput.helperText')}
</Text>
</Stack>
{content?.type !== VideoBubbleContentType.URL && (
<NumberInput
label="Height:"
defaultValue={content?.height ?? defaultVideoBubbleContent.height}
onValueChange={updateHeight}
suffix={t('editor.blocks.bubbles.video.settings.numberInput.unit')}
width="150px"
{content?.url && (
<Stack>
<TextInput
label={t('video.aspectRatioInput.label')}
moreInfoTooltip={t('video.aspectRatioInput.moreInfoTooltip')}
defaultValue={
content?.aspectRatio ?? defaultVideoBubbleContent.aspectRatio
}
onChange={updateAspectRatio}
direction="row"
/>
<TextInput
label={t('video.maxWidthInput.label')}
moreInfoTooltip={t('video.maxWidthInput.moreInfoTooltip')}
defaultValue={
content?.maxWidth ?? defaultVideoBubbleContent.maxWidth
}
onChange={updateMaxWidth}
direction="row"
/>
</Stack>
)}
</Stack>
)

View File

@ -5,13 +5,14 @@ import fr from '../../public/locales/fr.json'
import de from '../../public/locales/de.json'
import pt from '../../public/locales/pt.json'
import ptBR from '../../public/locales/pt-BR.json'
import { env } from '@typebot.io/env'
export const tolgee = Tolgee()
.use(DevTools())
.use(FormatIcu())
.init({
apiKey: process.env.NEXT_PUBLIC_TOLGEE_API_KEY,
apiUrl: process.env.NEXT_PUBLIC_TOLGEE_API_URL,
apiKey: env.NEXT_PUBLIC_TOLGEE_API_KEY,
apiUrl: env.NEXT_PUBLIC_TOLGEE_API_URL,
defaultLanguage: 'en',
availableLanguages: ['en', 'fr', 'de', 'pt', 'pt-BR'],
fallbackLanguage: 'en',

View File

@ -13,7 +13,9 @@
"build:apps": "turbo run build --filter=builder... --filter=viewer...",
"db:migrate": "cd packages/prisma && pnpm run db:migrate",
"generate-change-log": "git fetch --all && pnpx gitmoji-changelog",
"locales:sync": "tolgee sync './apps/builder/src/**/*.ts?(x)' --continue-on-warning --remove-unused"
"locales:sync": "tolgee sync './apps/builder/src/**/*.ts?(x)' --continue-on-warning --remove-unused",
"locales:push": "tolgee push ./apps/builder/public/locales",
"locales:pull": "tolgee pull ./apps/builder/public/locales"
},
"devDependencies": {
"cross-env": "7.0.3",
@ -21,7 +23,7 @@
"husky": "8.0.3",
"prettier": "2.8.8",
"turbo": "1.10.12",
"@tolgee/cli": "1.2.0"
"@tolgee/cli": "1.3.2"
},
"config": {
"commitizen": {

View File

@ -69,9 +69,11 @@ export const parseBubbleBlock = (
const parsedContent = block.content
? deepParseVariables(variables)(block.content)
: undefined
return {
...block,
content: {
...parsedContent,
...(parsedContent?.url ? parseVideoUrl(parsedContent.url) : {}),
height:
typeof parsedContent?.height === 'string'

View File

@ -4,9 +4,14 @@ import { createSignal, Match, onCleanup, onMount, Switch } from 'solid-js'
import { clsx } from 'clsx'
import {
defaultVideoBubbleContent,
embedBaseUrls,
embeddableVideoTypes,
VideoBubbleContentType,
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
import { VideoBubbleBlock } from '@typebot.io/schemas'
import {
EmbeddableVideoBubbleContentType,
VideoBubbleBlock,
} from '@typebot.io/schemas'
type Props = {
content: VideoBubbleBlock['content']
@ -23,8 +28,8 @@ export const VideoBubble = (props: Props) => {
onMount(() => {
const typingDuration =
props.content?.type &&
[VideoBubbleContentType.VIMEO, VideoBubbleContentType.YOUTUBE].includes(
props.content?.type
embeddableVideoTypes.includes(
props.content?.type as EmbeddableVideoBubbleContentType
)
? 2000
: 100
@ -50,6 +55,8 @@ export const VideoBubble = (props: Props) => {
style={{
width: isTyping() ? '64px' : '100%',
height: isTyping() ? '32px' : '100%',
'max-width':
props.content?.maxWidth ?? defaultVideoBubbleContent.maxWidth,
}}
>
{isTyping() && <TypingBubble />}
@ -71,16 +78,19 @@ export const VideoBubble = (props: Props) => {
}
style={{
height: isTyping() ? (isMobile() ? '32px' : '36px') : 'auto',
'aspect-ratio': props.content?.aspectRatio,
'max-width':
props.content?.maxWidth ??
defaultVideoBubbleContent.maxWidth,
}}
/>
</Match>
<Match
when={
props.content?.type &&
[
VideoBubbleContentType.VIMEO,
VideoBubbleContentType.YOUTUBE,
].includes(props.content.type)
embeddableVideoTypes.includes(
props.content.type as EmbeddableVideoBubbleContentType
)
}
>
<div
@ -93,17 +103,23 @@ export const VideoBubble = (props: Props) => {
? isMobile()
? '32px'
: '36px'
: `${
: !props.content?.aspectRatio
? `${
props.content?.height ??
defaultVideoBubbleContent.height
}px`,
}px`
: undefined,
'aspect-ratio': props.content?.aspectRatio,
'max-width':
props.content?.maxWidth ??
defaultVideoBubbleContent.maxWidth,
}}
>
<iframe
src={`${
props.content?.type === VideoBubbleContentType.VIMEO
? 'https://player.vimeo.com/video'
: 'https://www.youtube.com/embed'
embedBaseUrls[
props.content?.type as EmbeddableVideoBubbleContentType
]
}/${props.content?.id}`}
class={'w-full h-full'}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"

7
packages/env/env.ts vendored
View File

@ -279,15 +279,16 @@ const tolgeeEnv = {
NEXT_PUBLIC_TOLGEE_API_URL: z
.string()
.url()
.default('https://tolgee.server.baptistearno.com"')
.optional(),
.optional()
.default('https://tolgee.server.baptistearno.com"'),
},
runtimeEnv: {
NEXT_PUBLIC_TOLGEE_API_KEY: getRuntimeVariable(
'NEXT_PUBLIC_TOLGEE_API_KEY'
),
NEXT_PUBLIC_TOLGEE_API_URL: getRuntimeVariable(
'NEXT_PUBLIC_TOLGEE_API_URL'
'NEXT_PUBLIC_TOLGEE_API_URL',
'https://tolgee.server.baptistearno.com'
),
},
}

View File

@ -2,9 +2,9 @@ declare const window: {
__ENV?: any
}
export const getRuntimeVariable = (key: string) => {
export const getRuntimeVariable = (key: string, defaultValue?: string) => {
if (typeof window !== 'undefined')
return window.__ENV ? window.__ENV[key] : undefined
return window.__ENV ? window.__ENV[key] ?? defaultValue : undefined
if (typeof process === 'undefined') return undefined
return process.env[key]
return process.env[key] ?? defaultValue
}

View File

@ -1,21 +1,74 @@
import { VideoBubbleContentType } from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
const vimeoRegex = /vimeo\.com\/(\d+)/
const youtubeRegex =
/youtube\.com\/(watch\?v=|shorts\/)([\w-]+)|youtu\.be\/([\w-]+)/
import { VideoBubbleBlock } from '@typebot.io/schemas'
import {
VideoBubbleContentType,
gumletRegex,
horizontalVideoSuggestionSize,
tiktokRegex,
verticalVideoSuggestionSize,
vimeoRegex,
youtubeRegex,
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
export const parseVideoUrl = (
url: string
): { type: VideoBubbleContentType; url: string; id?: string } => {
if (vimeoRegex.test(url)) {
const id = url.match(vimeoRegex)?.at(1)
if (!id) return { type: VideoBubbleContentType.URL, url }
return { type: VideoBubbleContentType.VIMEO, url, id }
}
): {
type: VideoBubbleContentType
url: string
id?: string
videoSizeSuggestion?: Pick<
NonNullable<VideoBubbleBlock['content']>,
'aspectRatio' | 'maxWidth'
>
} => {
if (youtubeRegex.test(url)) {
const id = url.match(youtubeRegex)?.at(2) ?? url.match(youtubeRegex)?.at(3)
if (!id) return { type: VideoBubbleContentType.URL, url }
return { type: VideoBubbleContentType.YOUTUBE, url, id }
const match = url.match(youtubeRegex)
const id = match?.at(2) ?? match?.at(3)
const parsedUrl = match?.at(0) ?? url
if (!id) return { type: VideoBubbleContentType.URL, url: parsedUrl }
return {
type: VideoBubbleContentType.YOUTUBE,
url: parsedUrl,
id,
videoSizeSuggestion: url.includes('shorts')
? verticalVideoSuggestionSize
: horizontalVideoSuggestionSize,
}
}
if (vimeoRegex.test(url)) {
const match = url.match(vimeoRegex)
const id = match?.at(1)
const parsedUrl = match?.at(0) ?? url
if (!id) return { type: VideoBubbleContentType.URL, url: parsedUrl }
return {
type: VideoBubbleContentType.VIMEO,
url: parsedUrl,
id,
videoSizeSuggestion: horizontalVideoSuggestionSize,
}
}
if (tiktokRegex.test(url)) {
const match = url.match(tiktokRegex)
const id = url.match(tiktokRegex)?.at(1)
const parsedUrl = match?.at(0) ?? url
if (!id) return { type: VideoBubbleContentType.URL, url: parsedUrl }
return {
type: VideoBubbleContentType.TIKTOK,
url: parsedUrl,
id,
videoSizeSuggestion: verticalVideoSuggestionSize,
}
}
if (gumletRegex.test(url)) {
const match = url.match(gumletRegex)
const id = match?.at(1)
const parsedUrl = match?.at(0) ?? url
if (!id) return { type: VideoBubbleContentType.URL, url: parsedUrl }
return {
type: VideoBubbleContentType.GUMLET,
url: parsedUrl,
id,
videoSizeSuggestion: horizontalVideoSuggestionSize,
}
}
return { type: VideoBubbleContentType.URL, url }
}

View File

@ -2,8 +2,49 @@ export enum VideoBubbleContentType {
URL = 'url',
YOUTUBE = 'youtube',
VIMEO = 'vimeo',
TIKTOK = 'tiktok',
GUMLET = 'gumlet',
}
export const embeddableVideoTypes = [
VideoBubbleContentType.YOUTUBE,
VideoBubbleContentType.VIMEO,
VideoBubbleContentType.TIKTOK,
VideoBubbleContentType.GUMLET,
] as const
export const defaultVideoBubbleContent = {
height: 400,
aspectRatio: '16/9',
maxWidth: '100%',
} as const
export const horizontalVideoSuggestionSize = {
aspectRatio: '16/9',
maxWidth: '100%',
}
export const verticalVideoSuggestionSize = {
aspectRatio: '9/16',
maxWidth: '400px',
}
const youtubeBaseUrl = 'https://www.youtube.com/embed'
export const youtubeRegex =
/youtube\.com\/(watch\?v=|shorts\/)([\w-]+)|youtu\.be\/([\w-]+)/
const vimeoBaseUrl = 'https://player.vimeo.com/video'
export const vimeoRegex = /vimeo\.com\/(\d+)/
const tiktokBaseUrl = 'https://www.tiktok.com/embed/v2'
export const tiktokRegex = /tiktok\.com\/@[\w-]+\/video\/(\d+)/
const gumletBaseUrl = 'https://play.gumlet.io/embed'
export const gumletRegex = /gumlet\.com\/watch\/(\w+)/
export const embedBaseUrls = {
[VideoBubbleContentType.VIMEO]: vimeoBaseUrl,
[VideoBubbleContentType.YOUTUBE]: youtubeBaseUrl,
[VideoBubbleContentType.TIKTOK]: tiktokBaseUrl,
[VideoBubbleContentType.GUMLET]: gumletBaseUrl,
} as const

View File

@ -9,6 +9,8 @@ export const videoBubbleContentSchema = z.object({
id: z.string().optional(),
type: z.nativeEnum(VideoBubbleContentType).optional(),
height: z.number().or(variableStringSchema).optional(),
aspectRatio: z.string().optional(),
maxWidth: z.string().optional(),
})
export const videoBubbleBlockSchema = blockBaseSchema.merge(
@ -19,3 +21,7 @@ export const videoBubbleBlockSchema = blockBaseSchema.merge(
)
export type VideoBubbleBlock = z.infer<typeof videoBubbleBlockSchema>
export type EmbeddableVideoBubbleContentType = Exclude<
VideoBubbleContentType,
VideoBubbleContentType.URL
>

8
pnpm-lock.yaml generated
View File

@ -9,8 +9,8 @@ importers:
.:
devDependencies:
'@tolgee/cli':
specifier: 1.2.0
version: 1.2.0
specifier: 1.3.2
version: 1.3.2
cross-env:
specifier: 7.0.3
version: 7.0.3
@ -8645,8 +8645,8 @@ packages:
tippy.js: 6.3.7
dev: false
/@tolgee/cli@1.2.0:
resolution: {integrity: sha512-1DBHdidNR0efuUAMjAtf9MDLC/nIwwYArCHjuscHvd/a3hgsdZYwrj926Ass1npj7RbtBYYTlBNju7qdLKD3Wg==}
/@tolgee/cli@1.3.2:
resolution: {integrity: sha512-7Vf+BFGmQ9jLfDiRrhsgg+h494k0V8BacSdKVZV83PqhibI6/+H9boJvB1oSA+IEwAO9BoBFxy87Y1LN0NI1Cg==}
engines: {node: '>= 18'}
hasBin: true
dependencies: