add navigation bar on top, remove footer

This commit is contained in:
stefan.tollkuehn committed 2026-09-30 13:39:24 +02:00
1 parent f3f47aee4d
commit 0d06c9ab24
1 file changed
+183 -19
+183 -19
View File
@@ -27,6 +27,57 @@
width: min(700px, calc(100% - 32px)); width: min(700px, calc(100% - 32px));
} }
.navbar {
position: fixed;
top: 16px;
right: 16px;
z-index: 100;
}
.lang-menu {
position: relative;
}
.lang-dropdown {
display: none;
position: absolute;
right: 0;
top: 100%;
min-width: 150px;
margin-top: 6px;
padding: 6px;
background: white;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.lang-dropdown.open {
display: block;
}
.lang-dropdown button {
display: block;
width: 100%;
margin: 0;
padding: 10px 14px;
border: 0;
border-radius: 6px;
background: none;
text-align: left;
font-size: 14px;
font-family: inherit;
cursor: pointer;
}
.lang-dropdown button:hover {
background: #f0f0f0;
}
.lang-dropdown button.active {
font-weight: 600;
background: #f0f8ff;
}
.card { .card {
box-sizing: border-box; box-sizing: border-box;
width: min(600px, calc(100% - 32px)); width: min(600px, calc(100% - 32px));
@@ -37,18 +88,6 @@
text-align: center; text-align: center;
} }
.footer {
margin-top: 25px;
box-sizing: border-box;
width: min(600px, calc(100% - 32px));
padding: 32px;
background: white;
border-radius: 14px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.10);
text-align: center;
float: right;
}
h1 { h1 {
margin-top: 0; margin-top: 0;
} }
@@ -180,10 +219,18 @@
background: #242424; background: #242424;
} }
.footer { .lang-dropdown {
background: #242424; background: #242424;
} }
.lang-dropdown button:hover {
background: #303030;
}
.lang-dropdown button.active {
background: #1a3a5a;
}
p { p {
color: #bbb; color: #bbb;
} }
@@ -218,6 +265,19 @@
</head> </head>
<body> <body>
<nav class="navbar">
<div id="langMenu" class="lang-menu">
<button id="langButton" class="button secondary" type="button" aria-haspopup="true" aria-expanded="false">
English
</button>
<div id="langDropdown" class="lang-dropdown">
<button type="button" data-lang="en">English</button>
<button type="button" data-lang="de">Deutsch</button>
<button type="button" data-lang="fr">Français</button>
</div>
</div>
</nav>
<div class="container"> <div class="container">
<div class="card"> <div class="card">
@@ -414,10 +474,6 @@
</div> </div>
</div> </div>
<div class="footer">
Impressum
</div>
</div> </div>
<script> <script>
"use strict"; "use strict";
@@ -722,6 +778,21 @@
*/ */
function detectLanguage() { function detectLanguage() {
/*
* Gespeicherte Sprachwahl hat Vorrang.
*/
try {
const saved = localStorage.getItem("jitsiLauncherLanguage");
if (saved && TRANSLATIONS[saved]) {
return saved;
}
} catch (error) {
/*
* localStorage kann z.B. im Privat-Modus blockiert sein.
*/
}
const languages = navigator.languages || [navigator.language]; const languages = navigator.languages || [navigator.language];
for (const language of languages) { for (const language of languages) {
@@ -744,8 +815,8 @@
return "en"; return "en";
} }
const currentLanguage = detectLanguage(); let currentLanguage = detectLanguage();
const translation = TRANSLATIONS[currentLanguage]; let translation = TRANSLATIONS[currentLanguage];
/* ============================================================ /* ============================================================
* Apply translations to webpage * Apply translations to webpage
@@ -799,6 +870,64 @@
return typeof value === "string" ? value : null; return typeof value === "string" ? value : null;
} }
/* ============================================================
* LANGUAGE MENU
* ============================================================
*/
const LANGUAGE_NAMES = {
en: "English",
de: "Deutsch",
fr: "Français"
};
function updateLanguageMenu() {
langButton.textContent = LANGUAGE_NAMES[currentLanguage];
langDropdown
.querySelectorAll("button[data-lang]")
.forEach((item) => {
item.classList.toggle(
"active",
item.dataset.lang === currentLanguage
);
});
}
function setLanguage(language) {
if (!TRANSLATIONS[language]) {
return;
}
currentLanguage = language;
translation = TRANSLATIONS[language];
try {
localStorage.setItem("jitsiLauncherLanguage", language);
} catch (error) {
/*
* localStorage kann z.B. im Privat-Modus blockiert sein.
*/
}
applyTranslations();
updateLanguageMenu();
}
function toggleLanguageMenu() {
const isOpen = langDropdown.classList.toggle("open");
langButton.setAttribute(
"aria-expanded",
isOpen ? "true" : "false"
);
}
function closeLanguageMenu() {
langDropdown.classList.remove("open");
langButton.setAttribute("aria-expanded", "false");
}
/* ============================================================ /* ============================================================
* BACKGROUND IMAGE * BACKGROUND IMAGE
* ============================================================ * ============================================================
@@ -849,6 +978,11 @@
const icsSuccess = document.getElementById("icsSuccess"); const icsSuccess = document.getElementById("icsSuccess");
const downloadIcsLink = document.getElementById("downloadIcsLink"); const downloadIcsLink = document.getElementById("downloadIcsLink");
/* Language menu DOM elements */
const langMenu = document.getElementById("langMenu");
const langButton = document.getElementById("langButton");
const langDropdown = document.getElementById("langDropdown");
/* ============================================================ /* ============================================================
* GET ROOM FROM QUERY-PARAMETER * GET ROOM FROM QUERY-PARAMETER
* ============================================================ * ============================================================
@@ -1448,6 +1582,35 @@ END:VCALENDAR`;
cancelCreateMeeting cancelCreateMeeting
); );
/* Language menu events */
langButton.addEventListener(
"click",
toggleLanguageMenu
);
langDropdown.addEventListener(
"click",
(event) => {
const item = event.target.closest("button[data-lang]");
if (!item) {
return;
}
setLanguage(item.dataset.lang);
closeLanguageMenu();
}
);
document.addEventListener(
"click",
(event) => {
if (!langMenu.contains(event.target)) {
closeLanguageMenu();
}
}
);
/* ============================================================ /* ============================================================
* START * START
* ============================================================ * ============================================================
@@ -1455,6 +1618,7 @@ END:VCALENDAR`;
applyTranslations(); applyTranslations();
applyBackgroundImage(); applyBackgroundImage();
updateLanguageMenu();
initialize(); initialize();
</script> </script>
</body> </body>