* Wed Jan 29 2025 Brian Read <brianr@koozali.org> 11.0.0-48.sme

- Make Country flag display independant of the internet. [SME: 12893]
This commit is contained in:
Brian Read 2025-01-29 12:04:38 +00:00
parent a62968d2d9
commit 642d013437
3 changed files with 306 additions and 274 deletions

View File

@ -68,9 +68,18 @@ color: #8ebe43;
background-color: #8ebe43; background-color: #8ebe43;
} }
/* flag container no flag */ /* flag container*/
#flag-container span { #flag-container span {
font-size: 24px; font-size: 24px;
display: flex; /* Allows for easy centering */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
width: 100%; /* Full width of parent */
height: 24px; /* Set a fixed height */
border: 1px solid #ccc; /* Light gray border */
border-radius: 5px; /* Rounded corners */
cursor: default; /* Prevent text cursor */
} }
.fallback-box { .fallback-box {
@ -84,4 +93,4 @@ background-color: #8ebe43;
} }
HERE HERE
} }

View File

@ -1,278 +1,298 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const flagContainer = document.getElementById('flag-container'); const flagContainer = document.getElementById('flag-container');
// Mapping of language codes to country codes and their names
async function getCountryName(countryCode) { const languageToCountryMap = {
try { "af": { code: "NA", name: "Namibia" },
const response = await fetch(`https://restcountries.com/v3.1/alpha/${countryCode}`); "agq": { code: "CM", name: "Cameroon" },
if (!response.ok) throw new Error('Country not found'); "ak": { code: "GH", name: "Ghana" },
const data = await response.json(); "am": { code: "ET", name: "Ethiopia" },
// Return the name in the native language "ar": { code: "SA", name: "Saudi Arabia" },
return data[0].name.common; "as": { code: "IN", name: "India" },
} catch (error) { "asa": { code: "TZ", name: "Tanzania" },
console.error(error); "ast": { code: "ES", name: "Spain" },
return 'Unknown Country'; "az": { code: "AZ", name: "Azerbaijan" },
} "bas": { code: "CM", name: "Cameroon" },
} "be": { code: "BY", name: "Belarus" },
"bem": { code: "ZM", name: "Zambia" },
function getFlagEmoji(locale) { "bez": { code: "TZ", name: "Tanzania" },
// Split the locale to get the language and country code "bg": { code: "BG", name: "Bulgaria" },
const parts = locale.split('-'); "bm": { code: "ML", name: "Mali" },
let countryCode; "bn": { code: "BD", name: "Bangladesh" },
"bo": { code: "CN", name: "China" },
// Handle single subtag (language only) or double subtag (language-country) "br": { code: "FR", name: "France" },
if (parts.length === 1) { "brx": { code: "IN", name: "India" },
countryCode = getCountryCodeFromLanguage(parts[0]); "bs": { code: "BA", name: "Bosnia and Herzegovina" },
} else if (parts.length === 2) { "ca": { code: "AD", name: "Andorra" },
countryCode = parts[1].toLowerCase(); // Use the country code "ccp": { code: "BD", name: "Bangladesh" },
} "ce": { code: "RU", name: "Russia" },
"cgg": { code: "UG", name: "Uganda" },
// If country code is not found, set a fallback output "chr": { code: "US", name: "United States" },
if (!countryCode) { "ckb": { code: "IQ", name: "Iraq" },
const fallback = `? ${locale.toUpperCase()}`; // Just a question mark and the full locale "cs": { code: "CZ", name: "Czech Republic" },
return { flag: fallback, isUnknown: true, countryName: 'Unknown Country' }; "cy": { code: "GB", name: "United Kingdom" },
} "da": { code: "DK", name: "Denmark" },
"dav": { code: "KE", name: "Kenya" },
// Convert the country code to a flag emoji "de": { code: "DE", name: "Germany" },
return { "dje": { code: "NE", name: "Niger" },
flag: String.fromCodePoint(...[...countryCode.toUpperCase()].map(char => 0x1F1E6 + char.charCodeAt(0) - 'A'.charCodeAt(0))), "dsb": { code: "DE", name: "Germany" },
isUnknown: false, "dua": { code: "CM", name: "Cameroon" },
countryCode: countryCode "dyo": { code: "SN", name: "Senegal" },
}; "dz": { code: "BT", name: "Bhutan" },
} "ebu": { code: "KE", name: "Kenya" },
"ee": { code: "GH", name: "Ghana" },
function getCountryCodeFromLanguage(language) { "el": { code: "CY", name: "Cyprus" },
// Map languages to countries (this is an example, extend as needed) "en": { code: "US", name: "United States" }, // Assume US for English if unspecified
const languageToCountryMap = { "es": { code: "ES", name: "Spain" },
// Add more mappings as needed "et": { code: "EE", name: "Estonia" },
"af": "NA", "eu": { code: "ES", name: "Spain" },
"agq": "CM", "ewo": { code: "CM", name: "Cameroon" },
"ak": "GH", "fa": { code: "AF", name: "Afghanistan" },
"am": "ET", "ff": { code: "CM", name: "Cameroon" },
"ar": "01", "fi": { code: "FI", name: "Finland" },
"as": "IN", "fil": { code: "PH", name: "Philippines" },
"asa": "TZ", "fo": { code: "FO", name: "Faroe Islands" },
"ast": "ES", "fr": { code: "FR", name: "France" },
"az": "rl", "fur": { code: "IT", name: "Italy" },
"bas": "CM", "fy": { code: "NL", name: "Netherlands" },
"be": "BY", "ga": { code: "IE", name: "Ireland" },
"bem": "ZM", "gd": { code: "GB", name: "United Kingdom" },
"bez": "TZ", "gl": { code: "ES", name: "Spain" },
"bg": "BG", "gsw": { code: "CH", name: "Switzerland" },
"bm": "ML", "gu": { code: "IN", name: "India" },
"bn": "BD", "guz": { code: "KE", name: "Kenya" },
"bo": "CN", "gv": { code: "IM", name: "Isle of Man" },
"br": "FR", "ha": { code: "GH", name: "Ghana" },
"brx": "IN", "haw": { code: "US", name: "United States" },
"bs": "rl", "he": { code: "IL", name: "Israel" },
"ca": "AD", "hi": { code: "IN", name: "India" },
"ccp": "BD", "hr": { code: "HR", name: "Croatia" },
"ce": "RU", "hsb": { code: "DE", name: "Germany" },
"cgg": "UG", "hu": { code: "HU", name: "Hungary" },
"chr": "US", "hy": { code: "AM", name: "Armenia" },
"ckb": "IQ", "id": { code: "ID", name: "Indonesia" },
"cs": "CZ", "ig": { code: "NG", name: "Nigeria" },
"cy": "GB", "ii": { code: "CN", name: "China" },
"da": "DK", "is": { code: "IS", name: "Iceland" },
"dav": "KE", "it": { code: "IT", name: "Italy" },
"de": "DE", "ja": { code: "JP", name: "Japan" },
"dje": "NE", "jgo": { code: "CM", name: "Cameroon" },
"dsb": "DE", "jmc": { code: "TZ", name: "Tanzania" },
"dua": "CM", "ka": { code: "GE", name: "Georgia" },
"dyo": "SN", "kab": { code: "DZ", name: "Algeria" },
"dz": "BT", "kam": { code: "KE", name: "Kenya" },
"ebu": "KE", "kde": { code: "TZ", name: "Tanzania" },
"ee": "GH", "kea": { code: "CV", name: "Cabo Verde" },
"el": "CY", "khq": { code: "ML", name: "Mali" },
"en": "01", "ki": { code: "KE", name: "Kenya" },
"es": "ES", "kk": { code: "KZ", name: "Kazakhstan" },
"et": "EE", "kkj": { code: "CM", name: "Cameroon" },
"eu": "ES", "kl": { code: "GL", name: "Greenland" },
"ewo": "CM", "kln": { code: "KE", name: "Kenya" },
"fa": "AF", "km": { code: "KH", name: "Cambodia" },
"ff": "CM", "kn": { code: "IN", name: "India" },
"fi": "FI", "ko": { code: "KP", name: "North Korea" },
"fil": "PH", "kok": { code: "IN", name: "India" },
"fo": "FO", "ks": { code: "IN", name: "India" },
"fr": "FR", "ksb": { code: "TZ", name: "Tanzania" },
"fur": "IT", "ksf": { code: "CM", name: "Cameroon" },
"fy": "NL", "ksh": { code: "DE", name: "Germany" },
"ga": "IE", "kw": { code: "GB", name: "United Kingdom" },
"gd": "GB", "ky": { code: "KG", name: "Kyrgyzstan" },
"gl": "ES", "lag": { code: "TZ", name: "Tanzania" },
"gsw": "CH", "lb": { code: "LU", name: "Luxembourg" },
"gu": "IN", "lg": { code: "UG", name: "Uganda" },
"guz": "KE", "lkt": { code: "US", name: "United States" },
"gv": "IM", "ln": { code: "AO", name: "Angola" },
"ha": "GH", "lo": { code: "LA", name: "Laos" },
"haw": "US", "lrc": { code: "IQ", name: "Iraq" },
"he": "IL", "lt": { code: "LT", name: "Lithuania" },
"hi": "IN", "lu": { code: "CD", name: "Democratic Republic of the Congo" },
"hr": "HR", "luo": { code: "KE", name: "Kenya" },
"hsb": "DE", "Luo": { code: "KE", name: "Kenya" },
"hu": "HU", "luy": { code: "KE", name: "Kenya" },
"hy": "AM", "lv": { code: "LV", name: "Latvia" },
"id": "ID", "mas": { code: "KE", name: "Kenya" },
"ig": "NG", "mer": { code: "KE", name: "Kenya" },
"ii": "CN", "mfe": { code: "MU", name: "Mauritius" },
"is": "IS", "mg": { code: "MG", name: "Madagascar" },
"it": "IT", "mgh": { code: "MZ", name: "Mozambique" },
"ja": "JP", "mgo": { code: "CM", name: "Cameroon" },
"jgo": "CM", "mk": { code: "MK", name: "North Macedonia" },
"jmc": "TZ", "ml": { code: "IN", name: "India" },
"ka": "GE", "mn": { code: "MN", name: "Mongolia" },
"kab": "DZ", "mr": { code: "IN", name: "India" },
"kam": "KE", "ms": { code: "BN", name: "Brunei" },
"kde": "TZ", "mt": { code: "MT", name: "Malta" },
"kea": "CV", "mua": { code: "CM", name: "Cameroon" },
"khq": "ML", "my": { code: "MM", name: "Myanmar" },
"ki": "KE", "mzn": { code: "IR", name: "Iran" },
"kk": "KZ", "naq": { code: "NA", name: "Namibia" },
"kkj": "CM", "nb": { code: "NO", name: "Norway" },
"kl": "GL", "nd": { code: "ZW", name: "Zimbabwe" },
"kln": "KE", "nds": { code: "DE", name: "Germany" },
"km": "KH", "ne": { code: "IN", name: "India" },
"kn": "IN", "nl": { code: "NL", name: "Netherlands" },
"ko": "KP", "nmg": { code: "CM", name: "Cameroon" },
"kok": "IN", "nn": { code: "NO", name: "Norway" },
"ks": "IN", "nnh": { code: "CM", name: "Cameroon" },
"ksb": "TZ", "nus": { code: "SS", name: "South Sudan" },
"ksf": "CM", "nyn": { code: "UG", name: "Uganda" },
"ksh": "DE", "om": { code: "ET", name: "Ethiopia" },
"kw": "GB", "or": { code: "IN", name: "India" },
"ky": "KG", "os": { code: "GE", name: "Georgia" },
"lag": "TZ", "pa": { code: "PK", name: "Pakistan" },
"lb": "LU", "pl": { code: "PL", name: "Poland" },
"lg": "UG", "ps": { code: "AF", name: "Afghanistan" },
"lkt": "US", "pt": { code: "PT", name: "Portugal" },
"ln": "AO", "qu": { code: "BO", name: "Bolivia" },
"lo": "LA", "rm": { code: "CH", name: "Switzerland" },
"lrc": "IQ", "rn": { code: "BI", name: "Burundi" },
"lt": "LT", "ro": { code: "RO", name: "Romania" },
"lu": "CD", "rof": { code: "TZ", name: "Tanzania" },
"luo": "KE", "ru": { code: "RU", name: "Russia" },
"Luo": "KE", "rw": { code: "RW", name: "Rwanda" },
"luy": "KE", "rwk": { code: "TZ", name: "Tanzania" },
"lv": "LV", "sah": { code: "RU", name: "Russia" },
"mas": "KE", "saq": { code: "KE", name: "Kenya" },
"mer": "KE", "sbp": { code: "TZ", name: "Tanzania" },
"mfe": "MU", "se": { code: "SE", name: "Sweden" },
"mg": "MG", "seh": { code: "MZ", name: "Mozambique" },
"mgh": "MZ", "ses": { code: "ML", name: "Mali" },
"mgo": "CM", "sg": { code: "CF", name: "Central African Republic" },
"mk": "MK", "shi": { code: "TN", name: "Tunisia" },
"ml": "IN", "si": { code: "LK", name: "Sri Lanka" },
"mn": "MN", "sk": { code: "SK", name: "Slovakia" },
"mr": "IN", "sl": { code: "SI", name: "Slovenia" },
"ms": "BN", "smn": { code: "FI", name: "Finland" },
"mt": "MT", "sn": { code: "ZW", name: "Zimbabwe" },
"mua": "CM", "so": { code: "SO", name: "Somalia" },
"my": "MM", "sq": { code: "AL", name: "Albania" },
"mzn": "IR", "sr": { code: "RS", name: "Serbia" },
"naq": "NA", "sv": { code: "SE", name: "Sweden" },
"nb": "NO", "sw": { code: "CD", name: "Democratic Republic of the Congo" },
"nd": "ZW", "ta": { code: "IN", name: "India" },
"nds": "DE", "te": { code: "IN", name: "India" },
"ne": "IN", "teo": { code: "KE", name: "Kenya" },
"nl": "NL", "tg": { code: "TJ", name: "Tajikistan" },
"nmg": "CM", "th": { code: "TH", name: "Thailand" },
"nn": "NO", "ti": { code: "ER", name: "Eritrea" },
"nnh": "CM", "to": { code: "TO", name: "Tonga" },
"nus": "SS", "tr": { code: "TR", name: "Turkey" },
"nyn": "UG", "tt": { code: "RU", name: "Russia" },
"om": "ET", "twq": { code: "NE", name: "Niger" },
"or": "IN", "tzm": { code: "MA", name: "Morocco" },
"os": "GE", "ug": { code: "CN", name: "China" },
"pa": "ab", "uk": { code: "UA", name: "Ukraine" },
"pl": "PL", "ur": { code: "IN", name: "India" },
"ps": "AF", "uz": { code: "UZ", name: "Uzbekistan" },
"pt": "PT", "vai": { code: "TN", name: "Tunisia" },
"qu": "BO", "Vai": { code: "TN", name: "Tunisia" },
"rm": "CH", "vi": { code: "VN", name: "Vietnam" },
"rn": "BI", "vun": { code: "TZ", name: "Tanzania" },
"ro": "RO", "wae": { code: "CH", name: "Switzerland" },
"rof": "TZ", "wo": { code: "SN", name: "Senegal" },
"ru": "RU", "xog": { code: "UG", name: "Uganda" },
"rw": "RW", "yav": { code: "CM", name: "Cameroon" },
"rwk": "TZ", "yi": { code: "01", name: "Unknown" }, // Placeholder for unspecified region
"sah": "RU", "yo": { code: "BJ", name: "Benin" },
"saq": "KE", "yue": { code: "CN", name: "China" },
"sbp": "TZ", "zgh": { code: "MA", name: "Morocco" },
"se": "SE", "zh": { code: "CN", name: "China" },
"seh": "MZ", "zu": { code: "ZA", name: "South Africa" },
"ses": "ML", };
"sg": "CF",
"shi": "tn",
"si": "LK",
"sk": "SK",
"sl": "SI",
"smn": "FI",
"sn": "ZW",
"so": "SO",
"sq": "AL",
"sr": "rl",
"sv": "AX",
"sw": "CD",
"ta": "IN",
"te": "IN",
"teo": "KE",
"tg": "TJ",
"th": "TH",
"ti": "ER",
"to": "TO",
"tr": "TR",
"tt": "RU",
"twq": "NE",
"tzm": "MA",
"ug": "CN",
"uk": "UA",
"ur": "IN",
"uz": "ab",
"vai": "tn",
"Vai": "tn",
"vi": "VN",
"vun": "TZ",
"wae": "CH",
"wo": "SN",
"xog": "UG",
"yav": "CM",
"yi": "01",
"yo": "BJ",
"yue": "ns",
"zgh": "MA",
"zh": "ns",
"zu": "ZA"
}; //async function getCountryName(countryCode) {
//try {
//const response = await fetch(`https://restcountries.com/v3.1/alpha/${countryCode}`);
//if (!response.ok) throw new Error('Country not found');
//const data = await response.json();
//// Return the name in the native language
//return data[0].name.common;
//} catch (error) {
//console.error(error);
//return 'Unknown Country';
//}
//}
return languageToCountryMap[language] || null; function getCountryNameFromLanguage(language) {
} return languageToCountryMap[language] ? languageToCountryMap[language].name : null;
}
async function displayLocaleAndFlag() { function getCountryCodeFromLanguage(language) {
// Get the browser locale return languageToCountryMap[language] ? languageToCountryMap[language].code : null;
const userLocale = navigator.language || navigator.userLanguage; }
const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale);
function getCountryNameFromCountryCode(countryCode) {
//alert(`Country code: ${countryCode}`);
for (const language in languageToCountryMap) {
if (languageToCountryMap.hasOwnProperty(language)) {
if (languageToCountryMap[language].code === countryCode) {
return languageToCountryMap[language].name;
}
}
}
return null; // Return null if country code not found
}
// Display the locale and the corresponding flag (or fallback) function getFlagEmoji(locale) {
//document.getElementById('locale').textContent = `Your Locale: ${userLocale}`; // Split the locale to get the language and country code
const parts = locale.split('-');
let countryCode;
if (isUnknown) { // Handle single subtag (language only) or double subtag (language-country)
const fallbackDiv = document.createElement('div'); if (parts.length === 1) {
fallbackDiv.className = 'fallback-box'; countryCode = getCountryCodeFromLanguage(parts[0]);
fallbackDiv.textContent = `? ${userLocale.toUpperCase()}`; // Only show ? and locale code inside the box } else if (parts.length === 2) {
//document.getElementById('flag-container').textContent = "Flag: "; countryCode = parts[1].toLowerCase(); // Use the country code
document.getElementById('flag-container').appendChild(fallbackDiv); }
// Tooltip for fallback
fallbackDiv.title = "Unknown Country"; // Tooltip for fallback
} else {
const countryName = await getCountryName(countryCode);
const flagSpan = document.createElement('span');
flagSpan.textContent = flag; // Use flag emoji
flagSpan.title = countryName; // Tooltip for the flag in country language
//document.getElementById('flag-container').textContent = "Flag: ";
document.getElementById('flag-container').appendChild(flagSpan);
}
}
displayLocaleAndFlag(); // If country code is not found, set a fallback output
}); if (!countryCode) {
const fallback = `? ${locale.toUpperCase()}`; // Just a question mark and the full locale
return { flag: fallback, isUnknown: true, countryName: 'Unknown Country' };
}
// Convert the country code to a flag emoji
return {
flag: String.fromCodePoint(...[...countryCode.toUpperCase()].map(char => 0x1F1E6 + char.charCodeAt(0) - 'A'.charCodeAt(0))),
isUnknown: false,
countryCode: countryCode
};
}
function displayLocaleAndFlag() {
// Get the browser locale
const userLocale = navigator.language || navigator.userLanguage;
//alert(`User Locale: ${userLocale}`); // Alert the detected locale
const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale);
//alert(`Country Code: ${countryCode}, Is Unknown: ${isUnknown}`); // Debug country code and unknown flag status
// Display the locale and the corresponding flag (or fallback)
//document.getElementById('locale').textContent = `Your Locale: ${userLocale}`;
if (isUnknown) {
const fallbackDiv = document.createElement('div');
fallbackDiv.className = 'fallback-box';
fallbackDiv.textContent = `? ${userLocale.toUpperCase()}`; // Show ? and locale code inside the box
document.getElementById('flag-container').appendChild(fallbackDiv);
// Tooltip for fallback
fallbackDiv.title = "Unknown Country"; // Tooltip for fallback
//alert('Fallback triggered: Unknown Country'); // Debug fallback
} else {
const countryName = getCountryNameFromCountryCode(countryCode.toUpperCase());
//alert(`Country Name from Country Code: ${countryName}`); // Alert the country name
const flagSpan = document.createElement('span');
flagSpan.textContent = flag; // Use flag emoji
flagSpan.title = countryName; // Tooltip for the flag in country language
document.getElementById('flag-container').appendChild(flagSpan);
//alert(`Flag Emoji: ${flag}`); // Debug flag emoji display
}
}
displayLocaleAndFlag();
});

View File

@ -2,7 +2,7 @@ Summary: Sme server navigation module : manager 2
%define name smeserver-manager %define name smeserver-manager
Name: %{name} Name: %{name}
%define version 11.0.0 %define version 11.0.0
%define release 47 %define release 48
Version: %{version} Version: %{version}
Release: %{release}%{?dist} Release: %{release}%{?dist}
License: GPL License: GPL
@ -143,6 +143,9 @@ true
%defattr(-,root,root) %defattr(-,root,root)
%changelog %changelog
* Wed Jan 29 2025 Brian Read <brianr@koozali.org> 11.0.0-48.sme
- Make Country flag display independant of the internet. [SME: 12893]
* Tue Jan 28 2025 Brian Read <brianr@koozali.org> 11.0.0-47.sme * Tue Jan 28 2025 Brian Read <brianr@koozali.org> 11.0.0-47.sme
- Temp (we hope) remove CSRF protection plugin [SME: ] - Temp (we hope) remove CSRF protection plugin [SME: ]
- Fix comparison in footer with config->mode - Fix comparison in footer with config->mode