Language buttons

This commit is contained in:
Claude Brisson
2023-06-13 10:11:18 +02:00
parent cc0e42eb5a
commit cced576860
4 changed files with 95 additions and 14 deletions

View File

@@ -2,6 +2,7 @@ package org.jeudego.pairgoth.view
import org.apache.velocity.tools.config.ValidScope import org.apache.velocity.tools.config.ValidScope
import org.jeudego.pairgoth.util.Translator import org.jeudego.pairgoth.util.Translator
import javax.servlet.http.HttpServletRequest
@ValidScope("application") @ValidScope("application")
class TranslationTool { class TranslationTool {
@@ -20,6 +21,14 @@ class TranslationTool {
}.let { Pair(iso, it) } }.let { Pair(iso, it) }
} }
fun url(request: HttpServletRequest, lang: String): String {
val out = StringBuilder()
out.append(request.requestURL.replaceFirst(Regex("://"), "://$lang/"))
val qs: String? = request.queryString
if (!qs.isNullOrEmpty()) out.append('?').append(qs)
return out.toString()
}
companion object { companion object {
val translator = ThreadLocal<Translator>() val translator = ThreadLocal<Translator>()
} }

View File

@@ -1,8 +1,10 @@
@import "/lib/fomantic-ui-2.8.7/semantic.css" layer(semantic); @import "/lib/fomantic-ui-2.8.7/semantic.css" layer(semantic);
@layer pairgoth { @layer pairgoth {
/* general styles */
body { body {
font-size : clamp(1rem, 2vw, 3rem); font-size: clamp(12px, .8rem + .25vw, 20px);
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
margin: 0; margin: 0;
@@ -22,19 +24,13 @@
} }
} }
/* header, center, footer */
#header { #header {
height: 3em; height: 3em;
width: 100%; width: 100%;
position: relative; position: relative;
justify-content: space-between; justify-content: space-between;
#left-header {
height: 100%;
}
#right-header {
height: 100%;
margin-top: 0.5em;
margin-right: 0.5em;
}
#logo { #logo {
height: 100%; height: 100%;
img { img {
@@ -67,6 +63,8 @@
padding: 0.5em; padding: 0.5em;
} }
/* buttons */
button { button {
font-size: inherit; font-size: inherit;
} }
@@ -88,4 +86,31 @@
transform: translate(0px, 5px); transform: translate(0px, 5px);
} }
} }
/* languages */
#lang {
position: relative;
#lang-list {
position: absolute;
display: none;
top:100%;
left: -200%;
right: 0.2em;
flex-flow: column nowrap;
padding: 0.2em;
gap: 0.5em;
background-color: #d44935;
align-items: center;
z-index: 50;
&.shown {
display: flex;
}
a {
display: inline-block;
text-align: center;
}
}
}
} }

View File

@@ -11,13 +11,20 @@
</head> </head>
<body class="vert flex"> <body class="vert flex">
<div id="header" class="horz flex"> <div id="header" class="horz flex">
<div id="left-header" class="horz flex"> <div id="logo">
<div id="logo" class="vert flex"> <img src="/img/logo.svg"/>
<img src="/img/logo.svg"/>
</div>
</div> </div>
<div id="right-header"> <div id="title">
</div>
<div id="lang">
<i class="$translate.flags[$request.lang] flag"></i> <i class="$translate.flags[$request.lang] flag"></i>
<div id="lang-list">
#foreach($lang in $translate.flags.entrySet())
#if($lang != $request.lang)
<a class="lang" data-lang="$lang.key" href="#"><i class="$lang.value flag"></i>&nbsp;$lang.key</a>
#end
#end
</div>
</div> </div>
</div> </div>
<div id="center"> <div id="center">
@@ -31,8 +38,28 @@
</div> </div>
<script type="text/javascript" src="/js/store2-2.14.2.min.js"></script> <script type="text/javascript" src="/js/store2-2.14.2.min.js"></script>
<script type="text/javascript" src="/js/tablesort-5.4.0.min.js"></script> <script type="text/javascript" src="/js/tablesort-5.4.0.min.js"></script>
<script type="text/javascript" src="/js/domhelper.js"></script>
<script type="text/javascript" src="/js/formproxy.js"></script> <script type="text/javascript" src="/js/formproxy.js"></script>
<script type="text/javascript" src="/js/api.js"></script> <script type="text/javascript" src="/js/api.js"></script>
<script type="text/javascript" src="/js/main.js"></script> <script type="text/javascript" src="/js/main.js"></script>
<script type="text/javascript">
// #[[
onLoad(() => {
$('#lang').on('click', e => {
$('#lang-list').toggleClass('shown');
});
$('.lang').on('click', e => {
let lang = e.target.closest('.lang').data('lang');
document.location.href = document.location.href.replace(/\/[a-z]{2}\//, `/${lang}/`);
return false;
});
document.on('click', e => {
if ($('#lang-list').hasClass('shown') && !e.target.closest('.lang,#lang')) {
$('#lang-list').removeClass('shown');
}
});
});
// ]]#
</script>
</body> </body>
</html> </html>

View File

@@ -27,6 +27,9 @@ NodeList.prototype.toggleClass = function(className) {
elem.classList.toggle(className); elem.classList.toggle(className);
}); });
} }
NodeList.prototype.hasClass = function(className) {
return this.item(0).classList.contains(className);
}
Node.prototype.offset = function() { Node.prototype.offset = function() {
let _x = 0; let _x = 0;
let _y = 0; let _y = 0;
@@ -47,3 +50,20 @@ Element.prototype.attr = function (key) {
NodeList.prototype.attr = function(key) { NodeList.prototype.attr = function(key) {
this.item(0).attr(key) // CB TODO review this.item(0).attr(key) // CB TODO review
} }
Element.prototype.data = function (key) {
return this.attributes[`data-${key}`].value
}
NodeList.prototype.data = function(key) {
this.item(0).data(key) // CB TODO review
}
let initFunctions = [];
function onLoad(fct) {
if (typeof(fct) == "function") initFunctions.push(fct);
}
document.on("DOMContentLoaded", () => {
initFunctions.forEach(fct => {
fct();
});
});