Skip to content

Commit c8bf325

Browse files
committed
feat: add hu and lv locales to airpicker and moment
1 parent 4c678dc commit c8bf325

File tree

6 files changed

+78
-27
lines changed

6 files changed

+78
-27
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
### Features
44

55
- Add `LANGUAGES` setting to configure available languages in the app
6+
- Add Latvian language support (@possible-im)
7+
- Add Hungarian language support (@bpisch)
68

79
### Fixes and improvements
810

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Claper has a two-sided mission:
3434
- The first one is to help these people presenting an idea or a message by giving them the opportunity to make their presentation unique and to have real-time feedback from their audience.
3535
- The second one is to help each participant to take their place, to be an actor in the presentation, in the meeting and to feel important and useful.
3636

37-
Supported languages: 🇬🇧 English, 🇫🇷 French, 🇩🇪 German, 🇪🇸 Spanish, 🇳🇱 Dutch, 🇮🇹 Italian
37+
Supported languages: 🇬🇧 English, 🇫🇷 French, 🇩🇪 German, 🇪🇸 Spanish, 🇳🇱 Dutch, 🇮🇹 Italian, 🇭🇺 Hungarian, 🇱🇻 Latvian
3838

3939
### Built With
4040

@@ -101,6 +101,3 @@ Distributed under the GPLv3 License. See `LICENSE.txt` for more information.
101101
[Tailwind-url]: https://tailwindcss.com/
102102
[Phoenix]: https://img.shields.io/badge/phoenix-f35424?style=for-the-badge&logo=&logoColor=white
103103
[Phoenix-url]: https://www.phoenixframework.org/
104-
[lmddc-logo]: /priv/static/images/partners/lmddc.png
105-
[pixilearn-logo]: /priv/static/images/partners/pixilearn.png
106-
[uccs-logo]: /priv/static/images/partners/uccs.png

assets/js/app.js

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ import airdatepickerLocaleDe from "air-datepicker/locale/de";
1313
import airdatepickerLocaleEs from "air-datepicker/locale/es";
1414
import airdatepickerLocaleNl from "air-datepicker/locale/nl";
1515
import airdatepickerLocaleIt from "air-datepicker/locale/it";
16+
import airdatepickerLocaleHu from "air-datepicker/locale/hu";
1617
import "moment/locale/de";
1718
import "moment/locale/fr";
1819
import "moment/locale/es";
1920
import "moment/locale/nl";
2021
import "moment/locale/it";
22+
import "moment/locale/hu";
23+
import "moment/locale/lv";
2124
import QRCodeStyling from "qr-code-styling";
2225
import { Presenter } from "./presenter";
2326
import { Manager } from "./manager";
@@ -26,28 +29,53 @@ import { TourGuideClient } from "@sjmc11/tourguidejs/src/Tour";
2629
window.moment = moment;
2730

2831
// Get supported locales from backend configuration or fallback to default list
29-
const supportedLocales = window.claperConfig?.supportedLocales || ["en", "fr", "de", "es", "nl", "it"];
32+
const supportedLocales = window.claperConfig?.supportedLocales || [
33+
"en",
34+
"fr",
35+
"de",
36+
"es",
37+
"nl",
38+
"it",
39+
"hu",
40+
"lv",
41+
];
42+
43+
const airdatePickrSupportedLocales = window.claperConfig?.supportedLocales || [
44+
"en",
45+
"fr",
46+
"de",
47+
"es",
48+
"nl",
49+
"it",
50+
"hu",
51+
];
3052

3153
var locale =
3254
document.querySelector("html").getAttribute("lang") ||
3355
navigator.language.split("-")[0];
3456

57+
var airdatepickrLocale = locale;
58+
3559
if (!supportedLocales.includes(locale)) {
3660
locale = "en";
3761
}
62+
if (!airdatePickrSupportedLocales.includes(locale)) {
63+
airdatepickrLocale = "en";
64+
}
3865

3966
window.moment.locale("en");
4067
window.moment.locale(locale);
4168
window.Alpine = Alpine;
4269
Alpine.start();
4370

44-
let airdatepickerLocale = {
71+
let airdatePickrLocales = {
4572
en: airdatepickerLocaleEn,
4673
fr: airdatepickerLocaleFr,
4774
de: airdatepickerLocaleDe,
4875
es: airdatepickerLocaleEs,
4976
nl: airdatepickerLocaleNl,
5077
it: airdatepickerLocaleIt,
78+
hu: airdatepickerLocaleHu,
5179
};
5280
let csrfToken = document
5381
.querySelector("meta[name='csrf-token']")
@@ -70,8 +98,8 @@ Hooks.EmbeddedBanner = {
7098
Hooks.TourGuide = {
7199
mounted() {
72100
this.triggerDiv = document.querySelector(this.el.dataset.btnTrigger);
73-
this.btnTrigger = this.triggerDiv.querySelector('.open');
74-
this.closeBtnTrigger = this.triggerDiv.querySelector('.close');
101+
this.btnTrigger = this.triggerDiv.querySelector(".open");
102+
this.closeBtnTrigger = this.triggerDiv.querySelector(".close");
75103

76104
this.tour = new TourGuideClient({
77105
nextLabel: this.el.dataset.nextLabel,
@@ -106,7 +134,7 @@ Hooks.TourGuide = {
106134
destroyed() {
107135
this.btnTrigger.removeEventListener("click", () => {
108136
this.startTour();
109-
});
137+
});
110138
this.closeBtnTrigger.removeEventListener("click", () => {
111139
this.triggerDiv.classList.add("hidden");
112140
this.tour.finishTour(true, this.el.dataset.group);
@@ -201,26 +229,36 @@ Hooks.Scroll = {
201229
Hooks.ScrollIntoDiv = {
202230
mounted() {
203231
let useParent = this.el.dataset.useParent === "true";
204-
this.scrollElement = this.el.dataset.useParent === "true" ? this.el.parentElement : this.el;
232+
this.scrollElement =
233+
this.el.dataset.useParent === "true" ? this.el.parentElement : this.el;
205234
this.checkIfAtBottom();
206235
this.scrollToBottom(true);
207236
this.handleEvent("scroll", () => this.scrollToBottom());
208237
this.scrollElement.addEventListener("scroll", () => this.checkIfAtBottom());
209238
},
210239
checkIfAtBottom() {
211-
this.isAtBottom = this.scrollElement.scrollHeight - this.scrollElement.scrollTop - this.scrollElement.clientHeight <= 30;
240+
this.isAtBottom =
241+
this.scrollElement.scrollHeight -
242+
this.scrollElement.scrollTop -
243+
this.scrollElement.clientHeight <=
244+
30;
212245
},
213246
scrollToBottom(force = false) {
214247
if (force || this.isAtBottom) {
215-
this.scrollElement.scrollTo({ top: this.scrollElement.scrollHeight, behavior: "smooth" });
248+
this.scrollElement.scrollTo({
249+
top: this.scrollElement.scrollHeight,
250+
behavior: "smooth",
251+
});
216252
}
217253
},
218254
updated() {
219255
this.scrollToBottom();
220256
},
221257
destroyed() {
222-
this.scrollElement.removeEventListener("scroll", () => this.checkIfAtBottom());
223-
}
258+
this.scrollElement.removeEventListener("scroll", () =>
259+
this.checkIfAtBottom(),
260+
);
261+
},
224262
};
225263

226264
Hooks.NicknamePicker = {
@@ -244,7 +282,7 @@ Hooks.NicknamePicker = {
244282
clicked(e) {
245283
let nickname = prompt(
246284
this.el.dataset.prompt,
247-
localStorage.getItem("nickname") || ""
285+
localStorage.getItem("nickname") || "",
248286
);
249287

250288
if (nickname) {
@@ -354,7 +392,7 @@ Hooks.Pickr = {
354392
const utc = moment(date).utc().format("YYYY-MM-DDTHH:mm:ss");
355393
utcTime.value = utc;
356394
},
357-
locale: airdatepickerLocale[locale],
395+
locale: airdatePickrLocales[airdatepickrLocale],
358396
});
359397
},
360398
updated() {},
@@ -393,7 +431,7 @@ Hooks.OpenPresenter = {
393431
window.open(
394432
this.el.dataset.url,
395433
"newwindow",
396-
"width=" + window.screen.width + ",height=" + window.screen.height
434+
"width=" + window.screen.width + ",height=" + window.screen.height,
397435
);
398436
},
399437
mounted() {
@@ -418,7 +456,12 @@ Hooks.GlobalReacts = {
418456
const container = document.createElement("div");
419457
container.innerHTML = svgContent;
420458
const svgElement = container.firstChild;
421-
svgElement.classList.add("react-animation", "absolute", "transform", "opacity-0");
459+
svgElement.classList.add(
460+
"react-animation",
461+
"absolute",
462+
"transform",
463+
"opacity-0",
464+
);
422465
svgElement.classList.add(...this.el.className.split(" "));
423466
this.el.appendChild(svgElement);
424467
}
@@ -430,15 +473,17 @@ Hooks.GlobalReacts = {
430473

431474
preloadSVGs() {
432475
const svgTypes = ["heart", "hundred", "clap", "raisehand"];
433-
svgTypes.forEach(type => {
476+
svgTypes.forEach((type) => {
434477
fetch(`/images/icons/${type}.svg`)
435-
.then(response => response.text())
436-
.then(svgContent => {
478+
.then((response) => response.text())
479+
.then((svgContent) => {
437480
this.svgCache[type] = svgContent;
438481
})
439-
.catch(error => console.error(`Error loading SVG for ${type}:`, error));
482+
.catch((error) =>
483+
console.error(`Error loading SVG for ${type}:`, error),
484+
);
440485
});
441-
}
486+
},
442487
};
443488
Hooks.JoinEvent = {
444489
mounted() {
@@ -630,7 +675,6 @@ window.addEventListener("phx:page-loading-stop", (info) => {
630675
topbar.hide();
631676
});
632677

633-
634678
const onlineUserTemplate = function (user) {
635679
return `
636680
<div id="online-user">

config/runtime.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ allow_unlink_external_provider =
129129
logout_redirect_url = get_var_from_path_or_env(config_dir, "LOGOUT_REDIRECT_URL", nil)
130130

131131
languages =
132-
get_var_from_path_or_env(config_dir, "LANGUAGES", "en,fr,es")
132+
get_var_from_path_or_env(config_dir, "LANGUAGES", "en,fr,es,it,de")
133133
|> String.split(",")
134134
|> Enum.map(&String.trim/1)
135135

lib/claper_web/live/user_settings_live/show.html.heex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,19 @@
259259
{"English", "en"},
260260
{"Español", "es"},
261261
{"Français", "fr"},
262+
{"Hungarian", "hu"},
262263
{"Italiano", "it"},
264+
{"Latvian", "lv"},
263265
{"Nederlands", "nl"}
264266
]
265267
|> Enum.filter(fn {_name, code} ->
266-
code in Application.get_env(:claper, :languages, ["en", "fr", "es"])
268+
code in Application.get_env(:claper, :languages, [
269+
"en",
270+
"fr",
271+
"es",
272+
"it",
273+
"de"
274+
])
267275
end)
268276
}
269277
key={:locale}

lib/claper_web/templates/layout/root.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<link phx-track-static rel="stylesheet" href="/assets/custom.css" />
1212
<script>
1313
window.claperConfig = {
14-
supportedLocales: <%= Jason.encode!(Application.get_env(:claper, :languages, ["en", "fr", "es"])) %>
14+
supportedLocales: <%= Jason.encode!(Application.get_env(:claper, :languages, ["en", "fr", "es", "it", "de"])) %>
1515
};
1616
</script>
1717
<script defer phx-track-static type="text/javascript" src="/assets/app.js">

0 commit comments

Comments
 (0)