Compare commits

..
2 Commits
3 changed files with 116 additions and 4 deletions

No files matched your search

+8 -4
View File
@@ -83,7 +83,8 @@
"endTimeRequired": "Please select an end time",
"endAfterStart": "End time must be after start time",
"organizerRequired": "Please enter an organizer email",
"organizerInvalid": "Please enter a valid organizer email address"
"organizerInvalid": "Please enter a valid organizer email address",
"nextcloudButton": "Create in Nextcloud Calendar"
}
},
"de": {
@@ -170,7 +171,8 @@
"endTimeRequired": "Bitte wählen Sie eine Endzeit",
"endAfterStart": "Die Endzeit muss nach der Startzeit liegen",
"organizerRequired": "Bitte geben Sie eine Organisator-E-Mail ein",
"organizerInvalid": "Bitte geben Sie eine gültige Organisator-E-Mail-Adresse ein"
"organizerInvalid": "Bitte geben Sie eine gültige Organisator-E-Mail-Adresse ein",
"nextcloudButton": "Im Nextcloud-Kalender erstellen"
}
},
"fr": {
@@ -257,7 +259,8 @@
"endTimeRequired": "Veuillez sélectionner une heure de fin",
"endAfterStart": "L'heure de fin doit être après l'heure de début",
"organizerRequired": "Veuillez entrer un email d'organisateur",
"organizerInvalid": "Veuillez entrer une adresse email d'organisateur valide"
"organizerInvalid": "Veuillez entrer une adresse email d'organisateur valide",
"nextcloudButton": "Créer dans le calendrier Nextcloud"
}
},
"zh": {
@@ -344,7 +347,8 @@
"endTimeRequired": "请选择结束时间",
"endAfterStart": "结束时间必须晚于开始时间",
"organizerRequired": "请输入组织者邮箱",
"organizerInvalid": "请输入有效的组织者邮箱地址"
"organizerInvalid": "请输入有效的组织者邮箱地址",
"nextcloudButton": "在 Nextcloud 日历中创建"
}
}
}
+101
View File
@@ -14,6 +14,10 @@ const CONFIG = {
* Your Jitsi domain.
*/
jitsiHost: "meet.bnvb-ingenieure.de",
/*
* Your Nextcloud instance (calendar event creation).
*/
nextcloudBase: "https://cloud.bnvb-ingenieure.de",
/*
* Timeout trying to start the jitsi-meet-electron client
*/
@@ -357,9 +361,12 @@ const meetingStartInput = document.getElementById("meetingStart");
const meetingEndInput = document.getElementById("meetingEnd");
const meetingOrganizerInput = document.getElementById("meetingOrganizer");
const createMeetingButton = document.getElementById("createMeetingButton");
const createNextcloudButton = document.getElementById('createNextcloudButton');
const createAdhocButton = document.getElementById("createAdhocButton");
const cancelCreateButton = document.getElementById("cancelCreateButton");
const icsSuccess = document.getElementById("icsSuccess");
const nextcloudStatus = document.getElementById('nextcloudStatus');
const nextcloudError = document.getElementById('nextcloudError');
const downloadIcsLink = document.getElementById("downloadIcsLink");
const adhocResult = document.getElementById("adhocResult");
const adhocLink = document.getElementById("adhocLink");
@@ -1000,6 +1007,93 @@ function showMeetingCreator() {
meetingEndInput.value = formatLocal(end);
}
function openNextcloudCalendarCreator() {
const meetingName =
meetingNameInput.value.trim();
const description =
meetingDescriptionInput.value.trim();
const startTime =
meetingStartInput.value;
const endTime =
meetingEndInput.value;
const organizer =
meetingOrganizerInput.value.trim();
if (!meetingName) {
alert(getTranslation('creator.meetingNameRequired') || 'Please enter a meeting name.');
meetingNameInput.focus();
return;
}
if (!startTime || !endTime) {
alert(getTranslation('creator.startTimeRequired') || 'Please select a start time.');
return;
}
const start = new Date(startTime);
const end = new Date(endTime);
if (Number.isNaN(start.getTime()) ||
Number.isNaN(end.getTime())) {
alert('Invalid start or end date.');
return;
}
if (end <= start) {
alert(getTranslation('creator.endAfterStart') || 'End time must be after start time.');
return;
}
/*
* Nextcloud validiert die E-Mail serverseitig und
* bricht sonst mit einer Fehlerseite ab.
*/
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (organizer && !emailPattern.test(organizer)) {
alert(getTranslation('creator.organizerInvalid') || 'Please enter a valid organizer email address.');
return;
}
/*
* Use exactly the same room-generation logic as the
* existing ICS creation.
*/
const roomName = createRoomName(meetingName);
const meetingUrl =
createLaunchUrl(roomName);
const params = new URLSearchParams();
params.set('summary', meetingName);
if (description) {
params.set('description', description);
}
params.set('start', startTime);
params.set('end', endTime);
if (organizer) {
params.set('organizer', organizer);
}
params.set('location', meetingUrl);
params.set('url', meetingUrl);
const nextcloudUrl =
CONFIG.nextcloudBase +
'/index.php/apps/jitsi_calendar/confirm?' +
params.toString();
window.location.href = nextcloudUrl;
}
function createMeeting() {
const meetingName = meetingNameInput.value.trim();
const description = meetingDescriptionInput.value.trim();
@@ -1262,6 +1356,13 @@ createMeetingButton.addEventListener(
createMeeting
);
if (createNextcloudButton) {
createNextcloudButton.addEventListener(
'click',
openNextcloudCalendarCreator
);
}
createAdhocButton.addEventListener(
"click",
createAdhocLink
+7
View File
@@ -289,6 +289,9 @@
<button id="createMeetingButton" class="button primary" type="button" data-i18n="creator.createButton">
Create Meeting
</button>
<button id="createNextcloudButton" class="button primary" type="button" data-i18n="creator.nextcloudButton">
Create in Nextcloud Calendar
</button>
<button id="createAdhocButton" class="button secondary" type="button" data-i18n="creator.adhocButton">
Create Adhoc Link
</button>
@@ -309,6 +312,10 @@
<span data-i18n="creator.successMessage">Meeting created! Download your calendar file and open it to import the meeting into your personal calendar.</span>
<a id="downloadIcsLink" class="button primary" style="margin-top: 12px; display: inline-block;" data-i18n="creator.downloadButton">Download ICS File</a>
</div>
<div id="nextcloudStatus" class="success-message hidden" aria-live="polite"></div>
<div id="nextcloudError" class="error hidden" aria-live="assertive"></div>
</div>
</div>