Compare commits

..
2 Commits
+129 -6
View File
@@ -249,6 +249,29 @@
color: #0066cc;
}
.adhoc-result {
margin-top: 24px;
padding: 16px;
border-radius: 8px;
background: #f0fff4;
color: #1a7f37;
}
.adhoc-link {
margin-top: 12px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
flex-wrap: wrap;
}
.adhoc-link a {
font-family: monospace;
word-break: break-all;
color: #0066cc;
}
@keyframes spin {
to {
transform: rotate(360deg);
@@ -315,6 +338,15 @@
background: #1a3a5a;
color: #99ccff;
}
:root.dark .adhoc-result {
background: #1c3527;
color: #7ee2a8;
}
:root.dark .adhoc-link a {
color: #99ccff;
}
</style>
</head>
@@ -549,13 +581,24 @@
<button id="createMeetingButton" class="button primary" type="button" data-i18n="creator.createButton">
Create Meeting
</button>
<button id="createAdhocButton" class="button secondary" type="button" data-i18n="creator.adhocButton">
Create Adhoc Link
</button>
<button id="cancelCreateButton" class="button secondary" type="button" data-i18n="creator.cancelButton">
Cancel
</button>
</div>
<div id="adhocResult" class="adhoc-result hidden">
<span data-i18n="creator.adhocLinkLabel">Your adhoc meeting link:</span>
<div class="adhoc-link">
<a id="adhocLink" target="_blank" rel="noopener noreferrer"></a>
<button id="copyAdhocLinkButton" class="button secondary" type="button" data-i18n="creator.copyLinkButton">Copy Link</button>
</div>
</div>
<div id="icsSuccess" class="success-message hidden">
<span data-i18n="creator.successMessage">Meeting created! Download your calendar file.</span>
<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>
@@ -682,9 +725,13 @@
meetingOrganizerLabel: "Organizer Email",
createButton: "Create Meeting",
cancelButton: "Cancel",
successMessage: "Meeting created! Download your calendar file.",
successMessage: "Meeting created! Download your calendar file and open it to import the meeting into your personal calendar.",
downloadButton: "Download ICS File",
createNewButton: "Create New Meeting",
adhocButton: "Create Adhoc Link",
adhocLinkLabel: "Your adhoc meeting link:",
copyLinkButton: "Copy Link",
copiedLabel: "Copied!",
meetingNameRequired: "Please enter a meeting name",
meetingNameInvalid: "Meeting name may only contain letters, numbers and hyphens",
startTimeRequired: "Please select a start time",
@@ -772,9 +819,13 @@
meetingOrganizerLabel: "Organisator E-Mail",
createButton: "Meeting erstellen",
cancelButton: "Abbrechen",
successMessage: "Meeting erstellt! Laden Sie Ihre Kalenderdatei herunter.",
successMessage: "Meeting erstellt! Laden Sie Ihre Kalenderdatei herunter und öffnen Sie diese, um das Meeting in Ihren persönlichen Kalender zu importieren.",
downloadButton: "ICS-Datei herunterladen",
createNewButton: "Neues Meeting erstellen",
adhocButton: "Adhoc-Link erstellen",
adhocLinkLabel: "Ihr Adhoc-Meeting-Link:",
copyLinkButton: "Link kopieren",
copiedLabel: "Kopiert!",
meetingNameRequired: "Bitte geben Sie einen Meeting-Namen ein",
meetingNameInvalid: "Der Meeting-Name darf nur Buchstaben, Zahlen und Bindestriche enthalten",
startTimeRequired: "Bitte wählen Sie eine Startzeit",
@@ -861,9 +912,13 @@
meetingOrganizerLabel: "Email de l'organisateur",
createButton: "Créer la réunion",
cancelButton: "Annuler",
successMessage: "Réunion créée ! Téléchargez votre fichier calendrier.",
successMessage: "Réunion créée ! Téléchargez votre fichier calendrier et ouvrez-le pour importer la réunion dans votre calendrier personnel.",
downloadButton: "Télécharger le fichier ICS",
createNewButton: "Créer une nouvelle réunion",
adhocButton: "Créer un lien adhoc",
adhocLinkLabel: "Votre lien de réunion adhoc :",
copyLinkButton: "Copier le lien",
copiedLabel: "Copié !",
meetingNameRequired: "Veuillez entrer un nom de réunion",
meetingNameInvalid: "Le nom de la réunion ne peut contenir que des lettres, des chiffres et des tirets",
startTimeRequired: "Veuillez sélectionner une heure de début",
@@ -944,9 +999,13 @@
meetingOrganizerLabel: "组织者邮箱",
createButton: "创建会议",
cancelButton: "取消",
successMessage: "会议已创建!请下载您的日历文件。",
successMessage: "会议已创建!请下载您的日历文件并打开它,将会议导入您的个人日历。",
downloadButton: "下载 ICS 文件",
createNewButton: "创建新会议",
adhocButton: "创建临时链接",
adhocLinkLabel: "您的临时会议链接:",
copyLinkButton: "复制链接",
copiedLabel: "已复制!",
meetingNameRequired: "请输入会议名称",
meetingNameInvalid: "会议名称只能包含字母、数字和连字符",
startTimeRequired: "请选择开始时间",
@@ -1243,9 +1302,13 @@
const meetingEndInput = document.getElementById("meetingEnd");
const meetingOrganizerInput = document.getElementById("meetingOrganizer");
const createMeetingButton = document.getElementById("createMeetingButton");
const createAdhocButton = document.getElementById("createAdhocButton");
const cancelCreateButton = document.getElementById("cancelCreateButton");
const icsSuccess = document.getElementById("icsSuccess");
const downloadIcsLink = document.getElementById("downloadIcsLink");
const adhocResult = document.getElementById("adhocResult");
const adhocLink = document.getElementById("adhocLink");
const copyAdhocLinkButton = document.getElementById("copyAdhocLinkButton");
/* Language menu DOM elements */
const langMenu = document.getElementById("langMenu");
@@ -1778,6 +1841,7 @@ END:VCALENDAR`;
meetingEndInput.value = '';
meetingOrganizerInput.value = '';
icsSuccess.classList.add("hidden");
adhocResult.classList.add("hidden");
/* Set default start and end times */
const start = roundMinutes(new Date());
@@ -1843,11 +1907,60 @@ END:VCALENDAR`;
/* Show success message */
icsSuccess.classList.remove("hidden");
adhocResult.classList.add("hidden");
/* Scroll to success message */
icsSuccess.scrollIntoView({ behavior: 'smooth' });
}
/* ============================================================
* ADHOC LINK
* ============================================================
*/
function createAdhocLink() {
const meetingName = meetingNameInput.value.trim();
if (!meetingName) {
alert(getTranslation('creator.meetingNameRequired') || 'Please enter a meeting name');
return;
}
if (!ROOM_PATTERN.test(createRoomName(meetingName))) {
alert(getTranslation('creator.meetingNameInvalid') || 'Meeting name may only contain letters, numbers and hyphens');
return;
}
const roomName = createRoomName(meetingName);
const url = `https://${CONFIG.jitsiLauncher}/launch.html?room=${encodeURIComponent(roomName)}`;
adhocLink.href = url;
adhocLink.textContent = url;
icsSuccess.classList.add("hidden");
adhocResult.classList.remove("hidden");
adhocResult.scrollIntoView({ behavior: 'smooth' });
}
async function copyAdhocLink() {
const url = adhocLink.href;
try {
await navigator.clipboard.writeText(url);
} catch (error) {
const input = document.createElement('textarea');
input.value = url;
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
}
copyAdhocLinkButton.textContent = getTranslation('creator.copiedLabel') || 'Copied!';
setTimeout(() => {
copyAdhocLinkButton.textContent = getTranslation('creator.copyLinkButton') || 'Copy Link';
}, 2000);
}
function cancelCreateMeeting() {
meetingCreator.classList.add("hidden");
@@ -1980,6 +2093,16 @@ END:VCALENDAR`;
createMeeting
);
createAdhocButton.addEventListener(
"click",
createAdhocLink
);
copyAdhocLinkButton.addEventListener(
"click",
copyAdhocLink
);
cancelCreateButton.addEventListener(
"click",
cancelCreateMeeting