From 20d2955e689cce90c1ff3eebef4fd7a6c4ac3370 Mon Sep 17 00:00:00 2001
From: Philipp Dormann <17651032+philippdormann@users.noreply.github.com>
Date: Tue, 8 Feb 2022 23:12:28 +0100
Subject: [PATCH] Add Jitsi Meet Integration (#1674)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* basic integration structure
* jitsi logo
* add jitsi meet description to event settings page
* add JitsiVideoApiAdapter
ref #1445
* add LocationType.Jitsi to BookingPage
ref #1445
* add LocationType.Jitsi to event-types
ref #1445
* add meet.jit.si/cal/uuid support to BookingPage
ref #1445
* add basic "cal_provide_jitsi_meeting_url" translation strings
ref #1445
* generate meeting id
ref #1445
* implement direct jitsi link in /success page
ref #1445
* cleanup location link duplicate
ref #1445
* full JitsiVideoApiAdapter implementation
ref #1445
* check integration availability in /pages/event-types/[type]
ref #1445
* add video conferencing link as calendar event location
ref #1445
* PR feedback
* Update components/booking/pages/BookingPage.tsx
don't know - wouldn't do this myself for future proofing but fine...
Co-authored-by: Omar López
* Update components/booking/pages/BookingPage.tsx
🤷♂️
Co-authored-by: Omar López
* cleanup: props.type === "jitsi_video"
ref #1445
Co-authored-by: zomars
---
components/booking/pages/BookingPage.tsx | 11 +++
lib/events/EventManager.ts | 1 +
lib/integrations.ts | 2 +
.../Jitsi/JitsiVideoApiAdapter.ts | 34 ++++++++
lib/integrations/getIntegrations.ts | 20 +++--
lib/location.ts | 1 +
lib/videoClient.ts | 4 +
pages/event-types/[type].tsx | 80 +++++++++++++++++--
pages/integrations/index.tsx | 2 +-
pages/success.tsx | 20 +++--
public/integrations/jitsi.svg | 1 +
public/static/locales/cs/common.json | 1 +
public/static/locales/de/common.json | 1 +
public/static/locales/en/common.json | 1 +
public/static/locales/es/common.json | 1 +
public/static/locales/fr/common.json | 1 +
public/static/locales/it/common.json | 1 +
public/static/locales/ja/common.json | 1 +
public/static/locales/ko/common.json | 1 +
public/static/locales/nl/common.json | 1 +
public/static/locales/pl/common.json | 1 +
public/static/locales/pt-BR/common.json | 1 +
public/static/locales/pt/common.json | 1 +
public/static/locales/ro/common.json | 1 +
public/static/locales/ru/common.json | 1 +
public/static/locales/zh-CN/common.json | 1 +
26 files changed, 171 insertions(+), 20 deletions(-)
create mode 100644 lib/integrations/Jitsi/JitsiVideoApiAdapter.ts
create mode 100644 public/integrations/jitsi.svg
diff --git a/components/booking/pages/BookingPage.tsx b/components/booking/pages/BookingPage.tsx
index 46d4ef85..4ffda4bd 100644
--- a/components/booking/pages/BookingPage.tsx
+++ b/components/booking/pages/BookingPage.tsx
@@ -16,6 +16,7 @@ import { Controller, useForm, useWatch } from "react-hook-form";
import { FormattedNumber, IntlProvider } from "react-intl";
import { ReactMultiEmail } from "react-multi-email";
import { useMutation } from "react-query";
+import { v4 as uuidv4 } from "uuid";
import { createPaymentLink } from "@ee/lib/stripe/client";
@@ -89,6 +90,9 @@ const BookingPage = (props: BookingPageProps) => {
if (!location) {
return;
}
+ if (location === "integrations:jitsi") {
+ return "https://meet.jit.si/cal/" + uuidv4();
+ }
if (location.includes("integration")) {
return t("web_conferencing_details_to_follow");
}
@@ -143,6 +147,7 @@ const BookingPage = (props: BookingPageProps) => {
[LocationType.Phone]: t("phone_call"),
[LocationType.GoogleMeet]: "Google Meet",
[LocationType.Zoom]: "Zoom Video",
+ [LocationType.Jitsi]: "Jitsi Meet",
[LocationType.Daily]: "Daily.co Video",
[LocationType.Huddle01]: "Huddle01 Video",
[LocationType.Tandem]: "Tandem Video",
@@ -330,6 +335,12 @@ const BookingPage = (props: BookingPageProps) => {
{getLocationValue({ locationType: selectedLocation })}
)}
+ {selectedLocation === LocationType.Jitsi && (
+
+
+ Jitsi Meet
+
+ )}
{parseDate(date)}
diff --git a/lib/events/EventManager.ts b/lib/events/EventManager.ts
index 14cf3238..199418b2 100644
--- a/lib/events/EventManager.ts
+++ b/lib/events/EventManager.ts
@@ -66,6 +66,7 @@ export const getLocationRequestFromIntegration = (location: string) => {
location === LocationType.GoogleMeet.valueOf() ||
location === LocationType.Zoom.valueOf() ||
location === LocationType.Daily.valueOf() ||
+ location === LocationType.Jitsi.valueOf() ||
location === LocationType.Huddle01.valueOf() ||
location === LocationType.Tandem.valueOf()
) {
diff --git a/lib/integrations.ts b/lib/integrations.ts
index 03bb519c..9556dc98 100644
--- a/lib/integrations.ts
+++ b/lib/integrations.ts
@@ -14,6 +14,8 @@ export function getIntegrationName(name: string) {
return "Apple Calendar";
case "daily_video":
return "Daily";
+ case "jitsi_video":
+ return "Jitsi Meet";
case "huddle01_video":
return "Huddle01";
case "tandem_video":
diff --git a/lib/integrations/Jitsi/JitsiVideoApiAdapter.ts b/lib/integrations/Jitsi/JitsiVideoApiAdapter.ts
new file mode 100644
index 00000000..92f7c2f9
--- /dev/null
+++ b/lib/integrations/Jitsi/JitsiVideoApiAdapter.ts
@@ -0,0 +1,34 @@
+import { v4 as uuidv4 } from "uuid";
+
+import { PartialReference } from "@lib/events/EventManager";
+import { VideoApiAdapter, VideoCallData } from "@lib/videoClient";
+
+const JitsiVideoApiAdapter = (): VideoApiAdapter => {
+ return {
+ getAvailability: () => {
+ return Promise.resolve([]);
+ },
+ createMeeting: async (): Promise => {
+ const meetingID = uuidv4();
+ return Promise.resolve({
+ type: "jitsi_video",
+ id: meetingID,
+ password: "",
+ url: "https://meet.jit.si/cal/" + meetingID,
+ });
+ },
+ deleteMeeting: async (): Promise => {
+ Promise.resolve();
+ },
+ updateMeeting: (bookingRef: PartialReference): Promise => {
+ return Promise.resolve({
+ type: "jitsi_video",
+ id: bookingRef.meetingId as string,
+ password: bookingRef.meetingPassword as string,
+ url: bookingRef.meetingUrl as string,
+ });
+ },
+ };
+};
+
+export default JitsiVideoApiAdapter;
diff --git a/lib/integrations/getIntegrations.ts b/lib/integrations/getIntegrations.ts
index fce6deb4..62d2a520 100644
--- a/lib/integrations/getIntegrations.ts
+++ b/lib/integrations/getIntegrations.ts
@@ -1,11 +1,7 @@
import { Prisma } from "@prisma/client";
import _ from "lodash";
-/**
- * We can't use aliases in playwright tests (yet)
- * https://github.com/microsoft/playwright/issues/7121
- */
-import { validJson } from "../../lib/jsonUtils";
+import { validJson } from "@lib/jsonUtils";
const credentialData = Prisma.validator()({
select: { id: true, type: true },
@@ -24,6 +20,7 @@ export type Integration = {
| "caldav_calendar"
| "apple_calendar"
| "stripe_payment"
+ | "jitsi_video"
| "huddle01_video"
| "metamask_web3";
title: string;
@@ -65,6 +62,14 @@ export const ALL_INTEGRATIONS = [
description: "Video Conferencing",
variant: "conferencing",
},
+ {
+ installed: true,
+ type: "jitsi_video",
+ title: "Jitsi Meet",
+ imageSrc: "integrations/jitsi.svg",
+ description: "Video Conferencing",
+ variant: "conferencing",
+ },
{
installed: true,
type: "huddle01_video",
@@ -146,7 +151,10 @@ export function hasIntegration(integrations: IntegrationMeta, type: string): boo
(i) =>
i.type === type &&
!!i.installed &&
- (type === "daily_video" || type === "huddle01_video" || i.credentials.length > 0)
+ (type === "daily_video" ||
+ type === "jitsi_video" ||
+ type === "huddle01_video" ||
+ i.credentials.length > 0)
);
}
export function hasIntegrationInstalled(type: Integration["type"]): boolean {
diff --git a/lib/location.ts b/lib/location.ts
index c3070051..5401d888 100644
--- a/lib/location.ts
+++ b/lib/location.ts
@@ -4,6 +4,7 @@ export enum LocationType {
GoogleMeet = "integrations:google:meet",
Zoom = "integrations:zoom",
Daily = "integrations:daily",
+ Jitsi = "integrations:jitsi",
Huddle01 = "integrations:huddle01",
Tandem = "integrations:tandem",
}
diff --git a/lib/videoClient.ts b/lib/videoClient.ts
index dfcf642c..577eca4a 100644
--- a/lib/videoClient.ts
+++ b/lib/videoClient.ts
@@ -6,6 +6,7 @@ import { getUid } from "@lib/CalEventParser";
import { EventResult } from "@lib/events/EventManager";
import { PartialReference } from "@lib/events/EventManager";
import Huddle01VideoApiAdapter from "@lib/integrations/Huddle01/Huddle01VideoApiAdapter";
+import JitsiVideoApiAdapter from "@lib/integrations/Jitsi/JitsiVideoApiAdapter";
import logger from "@lib/logger";
import DailyVideoApiAdapter from "./integrations/Daily/DailyVideoApiAdapter";
@@ -46,6 +47,9 @@ const getVideoAdapters = (withCredentials: Credential[]): VideoApiAdapter[] =>
case "daily_video":
acc.push(DailyVideoApiAdapter(cred));
break;
+ case "jitsi_video":
+ acc.push(JitsiVideoApiAdapter());
+ break;
case "huddle01_video":
acc.push(Huddle01VideoApiAdapter());
break;
diff --git a/pages/event-types/[type].tsx b/pages/event-types/[type].tsx
index 5b819ef3..e85988c0 100644
--- a/pages/event-types/[type].tsx
+++ b/pages/event-types/[type].tsx
@@ -115,6 +115,7 @@ const EventTypePage = (props: inferSSRProps) => {
const defaultLocations = [
{ value: LocationType.InPerson, label: t("in_person_meeting") },
+ { value: LocationType.Jitsi, label: "Jitsi Meet" },
{ value: LocationType.Phone, label: t("phone_call") },
];
@@ -125,7 +126,12 @@ const EventTypePage = (props: inferSSRProps) => {
const updateMutation = trpc.useMutation("viewer.eventTypes.update", {
onSuccess: async ({ eventType }) => {
await router.push("/event-types");
- showToast(t("event_type_updated_successfully", { eventTypeTitle: eventType.title }), "success");
+ showToast(
+ t("event_type_updated_successfully", {
+ eventTypeTitle: eventType.title,
+ }),
+ "success"
+ );
},
onError: (err) => {
if (err instanceof HttpError) {
@@ -261,6 +267,8 @@ const EventTypePage = (props: inferSSRProps) => {
return {t("cal_provide_zoom_meeting_url")}
;
case LocationType.Daily:
return {t("cal_provide_video_meeting_url")}
;
+ case LocationType.Jitsi:
+ return {t("cal_provide_jitsi_meeting_url")}
;
case LocationType.Huddle01:
return {t("cal_provide_huddle01_meeting_url")}
;
case LocationType.Tandem:
@@ -276,7 +284,11 @@ const EventTypePage = (props: inferSSRProps) => {
setCustomInputs([...customInputs]);
};
- const schedulingTypeOptions: { value: SchedulingType; label: string; description: string }[] = [
+ const schedulingTypeOptions: {
+ value: SchedulingType;
+ label: string;
+ description: string;
+ }[] = [
{
value: SchedulingType.COLLECTIVE,
label: t("collective"),
@@ -328,7 +340,10 @@ const EventTypePage = (props: inferSSRProps) => {
locations: { type: LocationType; address?: string }[];
customInputs: EventTypeCustomInput[];
users: string[];
- availability: { openingHours: AvailabilityInput[]; dateOverrides: AvailabilityInput[] };
+ availability: {
+ openingHours: AvailabilityInput[];
+ dateOverrides: AvailabilityInput[];
+ };
timeZone: string;
periodType: PeriodType;
periodDays: number;
@@ -548,6 +563,33 @@ const EventTypePage = (props: inferSSRProps) => {
Tandem Video
)}
+ {location.type === LocationType.Jitsi && (
+
+
+
Jitsi Meet
+
+ )}
{!needsConfirmation && (
-
+
{t("add_to_calendar")}
@@ -162,7 +171,8 @@ export default function Success(props: inferSSRProps
)
.utc()
.format("YYYYMMDDTHHmmss[Z]")}&text=${eventName}&details=${
props.eventType.description
- }` + (typeof location === "string" ? encodeURIComponent(location) : "")
+ }` +
+ (typeof location === "string" ? "&location=" + encodeURIComponent(location) : "")
}>
\ No newline at end of file
diff --git a/public/static/locales/cs/common.json b/public/static/locales/cs/common.json
index 24c31007..902e6207 100644
--- a/public/static/locales/cs/common.json
+++ b/public/static/locales/cs/common.json
@@ -553,6 +553,7 @@
"cal_provide_zoom_meeting_url": "Cal poskytne URL Zoom meetingu.",
"cal_provide_tandem_meeting_url": "Cal poskytne URL Tandem meetingu.",
"cal_provide_video_meeting_url": "Cal poskytne URL Daily video meetingu.",
+ "cal_provide_jitsi_meeting_url": "Cal poskytne URL Jitsi Meet video meetingu.",
"cal_provide_huddle01_meeting_url": "Cal poskytne URL Huddle01 web3 video meetingu.",
"require_payment": "Vyžadovat platbu",
"commission_per_transaction": "provize za transakci",
diff --git a/public/static/locales/de/common.json b/public/static/locales/de/common.json
index 471f1c98..e8af131e 100644
--- a/public/static/locales/de/common.json
+++ b/public/static/locales/de/common.json
@@ -557,6 +557,7 @@
"cal_provide_zoom_meeting_url": "Cal stellt eine Zoom Meeting-URL zur Verfügung.",
"cal_provide_tandem_meeting_url": "Cal stellt eine Tandem Meeting-URL zur Verfügung.",
"cal_provide_video_meeting_url": "Cal stellt eine tägliche Video-Meeting-URL zur Verfügung.",
+ "cal_provide_jitsi_meeting_url": "Cal stellt eine Jitsi Meet URL zur Verfügung.",
"cal_provide_huddle01_meeting_url": "Cal stellt eine tägliche Huddle01-Web3-Meeting-URL zur Verfügung.",
"require_payment": "Zahlung erforderlich",
"commission_per_transaction": "Provision pro Transaktion",
diff --git a/public/static/locales/en/common.json b/public/static/locales/en/common.json
index 2ee157b6..4fec5d30 100644
--- a/public/static/locales/en/common.json
+++ b/public/static/locales/en/common.json
@@ -559,6 +559,7 @@
"cal_provide_zoom_meeting_url": "Cal will provide a Zoom meeting URL.",
"cal_provide_tandem_meeting_url": "Cal will provide a Tandem meeting URL.",
"cal_provide_video_meeting_url": "Cal will provide a Daily video meeting URL.",
+ "cal_provide_jitsi_meeting_url": "We will generate a Jitsi Meet URL for you.",
"cal_provide_huddle01_meeting_url": "Cal will provide a Huddle01 web3 video meeting URL.",
"require_payment": "Require Payment",
"commission_per_transaction": "commission per transaction",
diff --git a/public/static/locales/es/common.json b/public/static/locales/es/common.json
index e286e08b..551ede22 100644
--- a/public/static/locales/es/common.json
+++ b/public/static/locales/es/common.json
@@ -525,6 +525,7 @@
"cal_provide_zoom_meeting_url": "Cal proporcionará una URL de reunión de Zoom.",
"cal_provide_tandem_meeting_url": "Cal proporcionará una URL de reunión de Tandem.",
"cal_provide_video_meeting_url": "Cal proporcionará una URL de reunión de Daily Video.",
+ "cal_provide_jitsi_meeting_url": "Cal proporcionará una URL de reunión de Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal proporcionará una URL de reunión de Huddle01 Web3 Video.",
"require_payment": "Requiere Pago",
"commission_per_transaction": "Comisión por Transacción",
diff --git a/public/static/locales/fr/common.json b/public/static/locales/fr/common.json
index 4d1c423a..1c9949c9 100644
--- a/public/static/locales/fr/common.json
+++ b/public/static/locales/fr/common.json
@@ -491,6 +491,7 @@
"cal_provide_zoom_meeting_url": "Cal fournira une URL de réunion Zoom.",
"cal_provide_tandem_meeting_url": "Cal fournira une URL de réunion Tandem.",
"cal_provide_video_meeting_url": "Cal fournira une URL de réunion Daily video.",
+ "cal_provide_jitsi_meeting_url": "Cal fournira une URL de réunion Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal fournira une URL de réunion Huddle01 web3 video.",
"require_payment": "Exiger un paiement",
"commission_per_transaction": "commission par transaction",
diff --git a/public/static/locales/it/common.json b/public/static/locales/it/common.json
index bda09eef..ad446e10 100644
--- a/public/static/locales/it/common.json
+++ b/public/static/locales/it/common.json
@@ -517,6 +517,7 @@
"cal_provide_zoom_meeting_url": "Cal fornirà un URL di riunione Zoom.",
"cal_provide_tandem_meeting_url": "Cal fornirà un URL di riunione Tandem.",
"cal_provide_video_meeting_url": "Cal fornirà un URL di riunione Daily video.",
+ "cal_provide_jitsi_meeting_url": "Cal fornirà un URL di riunione Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal fornirà un URL di riunione Huddle01 web3 video.",
"require_payment": "Richiedi Pagamento",
"commission_per_transaction": "commissione per transazione",
diff --git a/public/static/locales/ja/common.json b/public/static/locales/ja/common.json
index 54f8b62f..1054065e 100644
--- a/public/static/locales/ja/common.json
+++ b/public/static/locales/ja/common.json
@@ -489,6 +489,7 @@
"cal_provide_zoom_meeting_url": "カルはZoomミーティングURLを提供します。",
"cal_provide_tandem_meeting_url": "カルはTandemミーティングURLを提供します。",
"cal_provide_video_meeting_url": "カルは毎日のビデオミーティングのURLを提供します。",
+ "cal_provide_jitsi_meeting_url": "カルはJitsi MeetミーティングURLを提供します。",
"cal_provide_huddle01_meeting_url": "カルはHuddle01 Web3ミーティングURLを提供します。",
"require_payment": "お支払いが必要です",
"commission_per_transaction": "取引あたりの手数料",
diff --git a/public/static/locales/ko/common.json b/public/static/locales/ko/common.json
index 3c6500ec..e8eb6975 100644
--- a/public/static/locales/ko/common.json
+++ b/public/static/locales/ko/common.json
@@ -512,6 +512,7 @@
"cal_provide_zoom_meeting_url": "Cal은 Zoom 회의 URL을 제공합니다.",
"cal_provide_tandem_meeting_url": "Cal은 Tandem 회의 URL을 제공합니다.",
"cal_provide_video_meeting_url": "Cal은 일일 화상 회의 URL을 제공합니다.",
+ "cal_provide_jitsi_meeting_url": "Cal은 Jitsi Meet 회의 URL을 제공합니다.",
"cal_provide_huddle01_meeting_url": "Cal은 Huddle01 Web3 회의 URL을 제공합니다.",
"require_payment": "지불 요청",
"commission_per_transaction": "거래당 수수료",
diff --git a/public/static/locales/nl/common.json b/public/static/locales/nl/common.json
index 2ef5231f..ee56c094 100644
--- a/public/static/locales/nl/common.json
+++ b/public/static/locales/nl/common.json
@@ -482,6 +482,7 @@
"cal_provide_zoom_meeting_url": "Cal zal een Zoom meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_tandem_meeting_url": "Cal zal een Tandem meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_video_meeting_url": "Cal zal een Daily meeting-URL meegeven in de afspraak bevestiging.",
+ "cal_provide_jitsi_meeting_url": "Cal zal een Jitsi Meet meeting-URL meegeven in de afspraak bevestiging.",
"cal_provide_huddle01_meeting_url": "Cal zal een Huddle01 web3 meeting-URL meegeven in de afspraak bevestiging.",
"require_payment": "Betaling vereisen",
"commission_per_transaction": "commissie per transactie",
diff --git a/public/static/locales/pl/common.json b/public/static/locales/pl/common.json
index 57a0d831..791c4b67 100644
--- a/public/static/locales/pl/common.json
+++ b/public/static/locales/pl/common.json
@@ -527,6 +527,7 @@
"cal_provide_google_meet_location": "Cal zapewni lokalizację Google Meet.",
"cal_provide_zoom_meeting_url": "Cal zapewni URL spotkania Zoom.",
"cal_provide_video_meeting_url": "Kal poda adres URL spotkania wideo platformy Daily.",
+ "cal_provide_jitsi_meeting_url": "Cal zapewni URL spotkania Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal zapewni URL spotkania Huddle01 Web3.",
"require_payment": "Wymagaj płatności",
"commission_per_transaction": "prowizja za transakcję",
diff --git a/public/static/locales/pt-BR/common.json b/public/static/locales/pt-BR/common.json
index ebf69ab1..7e688aa5 100644
--- a/public/static/locales/pt-BR/common.json
+++ b/public/static/locales/pt-BR/common.json
@@ -528,6 +528,7 @@
"cal_provide_zoom_meeting_url": "Cal fornecerá uma URL de reunião do Zoom.",
"cal_provide_tandem_meeting_url": "Cal fornecerá uma URL de reunião do Tandem.",
"cal_provide_video_meeting_url": "O Cal irá fornecer um URL de reunião do Daily video.",
+ "cal_provide_jitsi_meeting_url": "O Cal irá fornecer um URL de reunião do Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "O Cal irá fornecer um URL de reunião do Huddle01 Web3 video.",
"require_payment": "Requerer Pagamento",
"commission_per_transaction": "comissão por transação",
diff --git a/public/static/locales/pt/common.json b/public/static/locales/pt/common.json
index 2018c35f..d3b10f85 100644
--- a/public/static/locales/pt/common.json
+++ b/public/static/locales/pt/common.json
@@ -559,6 +559,7 @@
"cal_provide_zoom_meeting_url": "O Cal irá fornecer um URL de reunião do Zoom.",
"cal_provide_tandem_meeting_url": "O Cal irá fornecer um URL de reunião do Tandem.",
"cal_provide_video_meeting_url": "O Cal irá fornecer um URL de reunião do Daily video.",
+ "cal_provide_jitsi_meeting_url": "O Cal irá fornecer um URL de reunião vídeo do Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "O Cal irá fornecer um URL de reunião vídeo do Huddle01 Web3.",
"require_payment": "Requer Pagamento",
"commission_per_transaction": "comissão por transação",
diff --git a/public/static/locales/ro/common.json b/public/static/locales/ro/common.json
index b23bc891..5a67aa91 100644
--- a/public/static/locales/ro/common.json
+++ b/public/static/locales/ro/common.json
@@ -489,6 +489,7 @@
"cal_provide_zoom_meeting_url": "Cal va oferi un URL pentru ședința de Zoom.",
"cal_provide_tandem_meeting_url": "Cal va oferi un URL pentru ședința de Tandem.",
"cal_provide_video_meeting_url": "Cal va oferi un URL pentru ședința de Daily.",
+ "cal_provide_jitsi_meeting_url": "Cal va oferi un URL pentru ședința de Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal va oferi un URL pentru ședința de Huddle01 Web3.",
"require_payment": "Solicită plata",
"commission_per_transaction": "comision per tranzacție",
diff --git a/public/static/locales/ru/common.json b/public/static/locales/ru/common.json
index 827a1a4b..023a14c9 100644
--- a/public/static/locales/ru/common.json
+++ b/public/static/locales/ru/common.json
@@ -529,6 +529,7 @@
"cal_provide_zoom_meeting_url": "Cal создаст ссылку на встречу в Zoom.",
"cal_provide_tandem_meeting_url": "Cal создаст ссылку на встречу в Tandem.",
"cal_provide_video_meeting_url": "Cal создаст ссылку на встречу в Daily.",
+ "cal_provide_jitsi_meeting_url": "Cal создаст ссылку на встречу в Jitsi Meet.",
"cal_provide_huddle01_meeting_url": "Cal создаст ссылку на встречу в Huddle01 Web3.",
"require_payment": "Требуется оплата",
"commission_per_transaction": "комиссия за сделку",
diff --git a/public/static/locales/zh-CN/common.json b/public/static/locales/zh-CN/common.json
index b64af2f7..36b7b86e 100644
--- a/public/static/locales/zh-CN/common.json
+++ b/public/static/locales/zh-CN/common.json
@@ -534,6 +534,7 @@
"cal_provide_google_meet_location": "Cal 将提供 Google Meet 位置。",
"cal_provide_zoom_meeting_url": "Cal 将提供Zoom会议 URL",
"cal_provide_video_meeting_url": "Cal 将提供Daily视频会议 URL",
+ "cal_provide_jitsi_meeting_url": "Cal 将提供Jitsi Meet视频会议 URL",
"cal_provide_huddle01_meeting_url": "Cal 将提供Huddle01 Web3视频会议 URL",
"require_payment": "需要付款",
"commission_per_transaction": "每笔交易的佣金",