Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control for users to switch languages #622

Merged
merged 20 commits into from
Dec 19, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@
"chai": "^4.3.7",
"create-serve": "^1.0.1",
"esbuild": "^0.15.15",
"events": "^3.3.0",
"maplibre-gl": "^2.1.9",
"mocha": "^10.1.0",
"openmapsamples": "github:adamfranco/OpenMapSamples",
"openmapsamples-maplibre": "github:adamfranco/OpenMapSamples-MapLibre",
"prettier": "2.3.2",
"shx": "^0.3.4",
"svgo": "^2.8.0"
"svgo": "^2.8.0",
"tokenfield": "^1.5.2"
},
"engines": {
"npm": ">=8.3.0",
Expand Down
20 changes: 14 additions & 6 deletions src/americana.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ function buildLayers() {
return layers;
}

function buildStyle() {
export function buildStyle() {
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host + getUrl.pathname;

Expand Down Expand Up @@ -326,10 +326,18 @@ map.on("styleimagemissing", function (e) {
Shield.missingIconHandler(map, e);
});

window.addEventListener("languagechange", (event) => {
console.log(`Changed to ${navigator.languages}`);
export function hotReloadMap() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn’t have to be exported anymore.

map.setStyle(buildStyle());
}

export function updateLanguageLabel() {
languageLabel.displayLocales(Label.getLocales());
}

window.addEventListener("languagechange", (event) => {
console.log(`Changed to ${navigator.languages}`);
hotReloadMap();
updateLanguageLabel();
});

window.addEventListener("hashchange", (event) => {
Expand All @@ -338,8 +346,8 @@ window.addEventListener("hashchange", (event) => {
let newLanguage = Label.getLanguageFromURL(new URL(event.newURL));
if (oldLanguage !== newLanguage) {
console.log(`Changed to ${newLanguage}`);
map.setStyle(buildStyle());
languageLabel.displayLocales(Label.getLocales());
hotReloadMap();
updateLanguageLabel();
}
});

Expand Down Expand Up @@ -373,4 +381,4 @@ map.addControl(sampleControl, "bottom-left");

map.getCanvas().focus();

languageLabel.displayLocales(Label.getLocales());
updateLanguageLabel();
7 changes: 7 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,19 @@
bottom: 10px;
z-index: 100;
}
#language-picker {
width: 13em;
}
.openmapsamples-control-container {
margin-left: 70px !important;
}
</style>
<script type="module" src="americana.js"></script>
<link rel="stylesheet" href="americana.css" />
<link
rel="stylesheet"
href="https://kanecohen.github.io/tokenfield/css/tokenfield.css"
/>
</head>

<body>
Expand Down
171 changes: 168 additions & 3 deletions src/js/language_label.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,176 @@
"use strict";

var langField = document.createElement("div");
langField.id = "language-field";
import Tokenfield from "tokenfield";
import { hotReloadMap, updateLanguageLabel } from "../americana";

var langField = labelControlElement("span", "language-field");

var langChanger = labelControlElement("button", "language-switcher");
langChanger.textContent = "Change";

var langPicker = labelControlElement("input", "language-picker");
hide(langPicker);

var langHeader = labelControlElement("span", "lang-header");
var langHints = labelControlElement("span", "lang-hints");
langHints.textContent = "Begin typing to add languages";

var langCancel = labelControlElement("button", "language-cancel");
langCancel.textContent = "X";
Object.assign(langCancel.style, {
"margin-top": "0.3em",
});

langHeader.appendChild(langCancel);
langHeader.appendChild(langHints);

hide(langHeader);

function hide(element) {
Object.assign(element.style, {
display: "none",
});
}
function show(element) {
element.style.removeProperty("display");
}

var langCodes = [
{ id: "am", name: "Amharic" },
{ id: "ar", name: "Arabic" },
{ id: "az", name: "Azerbaijani" },
{ id: "be", name: "Belarusian" },
{ id: "bg", name: "Bulgarian" },
{ id: "br", name: "Breton" },
{ id: "bs", name: "Bosnian" },
{ id: "ca", name: "Catalan; Valencian" },
{ id: "co", name: "Corsican" },
{ id: "cs", name: "Czech" },
{ id: "cy", name: "Welsh" },
{ id: "da", name: "Danish" },
{ id: "de", name: "German" },
{ id: "el", name: "Greek, Modern" },
{ id: "en", name: "English" },
{ id: "eo", name: "Esperanto" },
{ id: "es", name: "Spanish" },
{ id: "et", name: "Estonian" },
{ id: "eu", name: "Basque" },
{ id: "fi", name: "Finnish" },
{ id: "fr", name: "French" },
{ id: "fy", name: "Western Frisian" },
{ id: "ga", name: "Irish" },
{ id: "gd", name: "Gaelic" },
{ id: "he", name: "Hebrew" },
{ id: "hi", name: "Hindi" },
{ id: "hr", name: "Croatian" },
{ id: "hu", name: "Hungarian" },
{ id: "hy", name: "Armenian" },
{ id: "id", name: "Indonesian" },
{ id: "is", name: "Icelandic" },
{ id: "it", name: "Italian" },
{ id: "ja", name: "Japanese" },
{ id: "ja_kana", name: "Japanese Kana" },
{ id: "ja-Latn", name: "Japanese Romanized" },
{ id: "ja-Hira", name: "Japanese Hiragana" },
{ id: "ka", name: "Georgian" },
{ id: "kk", name: "Kazakh" },
{ id: "kn", name: "Kannada" },
{ id: "ko", name: "Korean" },
{ id: "ko-Latn", name: "Korean Romanized" },
{ id: "ku", name: "Kurdish" },
{ id: "la", name: "Latin" },
{ id: "lb", name: "Luxembourgish" },
{ id: "lt", name: "Lithuanian" },
{ id: "lv", name: "Latvian" },
{ id: "mk", name: "Macedonian" },
{ id: "mt", name: "Maltese" },
{ id: "ml", name: "Malayalam" },
{ id: "nl", name: "Dutch" },
{ id: "no", name: "Norwegian" },
{ id: "oc", name: "Occitan" },
{ id: "pl", name: "Polish" },
{ id: "pt", name: "Portuguese" },
{ id: "rm", name: "Romansh" },
{ id: "ro", name: "Romanian" },
{ id: "ru", name: "Russian" },
{ id: "sk", name: "Slovak" },
{ id: "sl", name: "Slovenian" },
{ id: "sq", name: "Albanian" },
{ id: "sr", name: "Serbian" },
{ id: "sr-Latn", name: "Serbian Romanized" },
{ id: "sv", name: "Swedish" },
{ id: "ta", name: "Tamil" },
{ id: "te", name: "Telugu" },
{ id: "th", name: "Thai" },
{ id: "tr", name: "Turkish" },
{ id: "uk", name: "Ukrainian" },
{ id: "zh", name: "Chinese" },
];
ZeLonewolf marked this conversation as resolved.
Show resolved Hide resolved

function labelControlElement(tag, id) {
var element = document.createElement(tag);
element.id = id;
Object.assign(element.style, {
margin: "0 2.5px",
color: "#444",
});
Comment on lines +119 to +122
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually we should move non-dynamic CSS styling to a stylesheet or at least the <style> element in index.html. But this is OK for now if we’re going to redesign the feature soon anyways.

return element;
}

var tf = null;

langChanger.onclick = function () {
hide(langChanger);
show(langHeader);

if (tf == null) {
tf = new Tokenfield({
el: document.querySelector("#language-picker"), // Attach Tokenfield to the input element with class "text-input"
items: langCodes,
newItems: false,
});
document.querySelectorAll(".tokenfield").forEach((e) => {
Object.assign(e.style, {
height: "5em",
width: "20em",
"margin-bottom": "4em",
"margin-top": "0.3em",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only see a couple of the suggestions at a time, because the suggestion menu only appears below the textbox that’s already pretty far down the page. If Tokenfield doesn’t support automatically flipping the menu above the textbox, we should find a different place for the setting as tail work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not appear to have that option unfortunately:
https://github.com/KaneCohen/tokenfield

});
e.setAttribute("placeholder", "hi");
1ec5 marked this conversation as resolved.
Show resolved Hide resolved
});
tf.on("change", function () {
let items = tf.getItems();
let langCodes = [];
items.forEach((element) => langCodes.push(element.id));
let langQuery = langCodes.join(",");
let rawHash = window.location.hash.split("&")[0];
let langQueryString =
langCodes.length > 0 ? `&language=${langQuery}` : "";
var currentURL = `${window.location.protocol}//${window.location.host}${window.location.pathname}${rawHash}${langQueryString}`;
window.history.pushState({ path: currentURL }, "", currentURL);
updateLanguageLabel();
hotReloadMap();
ZeLonewolf marked this conversation as resolved.
Show resolved Hide resolved
});
}

document.querySelectorAll(".tokenfield").forEach((e) => show(e));
tf.focus();
};

langCancel.onclick = function () {
document.querySelectorAll(".tokenfield").forEach((e) => hide(e));
hide(langHeader);
updateLanguageLabel();
show(langChanger);
};

/**
* Label for displaying the current language being used
*/
class LanguageControl {
onAdd(map) {
this._map = map;
this._container = langField;
this._container = document.createElement("div");
this._container.className = "maplibregl-ctrl";
Object.assign(this._container.style, {
margin: "0",
Expand All @@ -18,6 +179,10 @@ class LanguageControl {
backgroundColor: "#ffffff80",
});
this._container.textContent = "";
this._container.appendChild(langHeader);
this._container.appendChild(langPicker);
this._container.appendChild(langField);
this._container.appendChild(langChanger);
return this._container;
}

Expand Down