add navigation bar on top, remove footer
This commit is contained in:
1 parent
f3f47aee4d
commit
0d06c9ab24
1 file changed
+183
-19
+183
-19
@@ -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>
|
||||||
|
|||||||
Reference in new issue
Block a user