diff --git a/src/components/AggregateGrid/AggregateGridPage.tsx b/src/components/AggregateGrid/AggregateGridPage.tsx index ffb5233a..4ec9c389 100644 --- a/src/components/AggregateGrid/AggregateGridPage.tsx +++ b/src/components/AggregateGrid/AggregateGridPage.tsx @@ -240,21 +240,21 @@ export function filterDateStringWithOperator( } export function getCountryIdMapFromLangTagData( - langData: ILangTagData[] + langTagData: ILangTagData[] ): Map { const countryIdMap = new Map(); - langData.forEach((lng) => { + langTagData.forEach((lng) => { if (lng.region && lng.regionname) { countryIdMap.set(lng.region, lng.regionname); } }); return countryIdMap; } -export function fixLanguageRegionDataAndGetMap( - rawLangData: ILangTagData[] +export function fixLangTagRegionDataAndGetMap( + rawLangTagData: ILangTagData[] ): Map { const map = new Map(); - rawLangData.forEach((lng) => { + rawLangTagData.forEach((lng) => { map.set(lng.tag, lng); // Override some primary region settings that seem misguided. if (lng.tag === "en") { @@ -263,42 +263,6 @@ export function fixLanguageRegionDataAndGetMap( lng.region = "PT"; // Portuguese originated in Portugal, not Brazil. } }); - // // // Add regions to the original language entries from the -Dupl and -Brai scripts. - // // // I'm not sure what Dupl is, but Brai is Braille. It makes sense that the Braille - // // // script shouldn't be considered a separate language, and that it would used only - // // // where the language is actually spoken. - // // // This ensures that Spanish is known to be spoken in Mexico and the US, for example. - // // // Also, that English is spoken in the UK, Australia, and Canada. - // // // Other languages such as German and French also get additional regions added by this - // // // processing. - // // rawLangData.forEach((lng) => { - // // if (lng.tag.endsWith("-Dupl") || lng.tag.endsWith("-Brai")) { - // // if (lng.regions && lng.regions.length > 0) { - // // const tag = lng.tag.substring(0, lng.tag.length - 5); - // // const origLang = map.get(tag); - // // if (!origLang) { - // // console.warn("No original lang for ", tag); - // // return; - // // } - // // if (!origLang.regions) { - // // origLang.regions = []; - // // } - // // if (!origLang.regions.includes(lng.region)) { - // // console.log(`Adding region ${lng.region} to ${tag}`); - // // origLang.regions.push(lng.region); - // // } - // // lng.regions.forEach((r) => { - // // if (!origLang.regions) { - // // origLang.regions = []; - // // } - // // if (!origLang.regions.includes(r)) { - // // console.log(`Adding region ${r} to ${tag}`); - // // origLang.regions.push(r); - // // } - // // }); - // // } - // // } - // // }); // // Restrict the regions for some major languages to the most common ones. // // REVIEW: are these copilot suggestions good enough? // const english = map.get("en"); @@ -326,6 +290,73 @@ export function fixLanguageRegionDataAndGetMap( return map; } +export function getLangTagDataForIrregularLangCode( + code: string, + langDataMap: Map, + countryIdMap: Map +): ILangTagData | undefined { + const langTagData = {} as ILangTagData; + const codeSections = code.split("-x-"); + const tagPieces = codeSections[0].split("-"); + langTagData.tag = code; + if (tagPieces.length > 1) { + const reg = tagPieces.find((piece) => { + return /[A-Z]{2}/.test(piece); + }); + if (reg) { + langTagData.region = reg; + langTagData.regionname = countryIdMap.get(reg) || reg; + } + } + if (codeSections.length > 1) { + langTagData.name = codeSections[1]; + } + // replace obsolete codes with current ones. + // or possibly specific with generic due to general confusion + let newCode = tagPieces[0]; + switch (newCode) { + // swh / Swahili (Tanzania) shares the macrolanguage code sw with swc / Swahili (Congo) + case "swh": + newCode = "sw"; + break; + // kmr / Northern Kurdish shares the macrolanguage code ku with ckb / Central Kurdish and sdh / Southern Kurdish + case "kmr": + newCode = "ku"; + break; + // obsolete code for Southern Balochi + case "bcc": + newCode = "bal"; + break; + // obsolete code for Luyia, sometimes called Bukusu + case "bxk": + newCode = "luy"; + break; + // obsolete code for Cusco Quechua + // que / (Cuzco) Quechua shares the macrolanguage code qu with qub, qud, quf, quk, qul, qup, qur, qus, and many more + case "quz": + newCode = "qu"; + break; + // obsolete code for Marwari, sometimes called Dhundari + case "dhd": + newCode = "mwr"; + break; + // obsolete code for Eastern Yiddish + // yid / (Eastern) Yiddish shares the macrolanguage code yi with yih / Western Yiddish + case "ydd": + newCode = "yi"; + break; + } + const tagData = langDataMap.get(newCode); + if (tagData) { + if (!langTagData.name) langTagData.name = tagData.name; + if (!langTagData.region) { + langTagData.region = tagData.region; + langTagData.regionname = tagData.regionname; + } + } + return langTagData; +} + export const ModeratorStatusToolbarPlugin = ( theme: Theme, user: User | undefined diff --git a/src/components/CountryGrid/CountryGridControlInternal.tsx b/src/components/CountryGrid/CountryGridControlInternal.tsx index 340d8fb3..a306c1c6 100644 --- a/src/components/CountryGrid/CountryGridControlInternal.tsx +++ b/src/components/CountryGrid/CountryGridControlInternal.tsx @@ -49,8 +49,9 @@ import { ICountryGridControlProps } from "./CountryGridControl"; import { CachedTablesContext } from "../../model/CacheProvider"; import { CachedBookDataContext, - fixLanguageRegionDataAndGetMap, + fixLangTagRegionDataAndGetMap, getCountryIdMapFromLangTagData, + getLangTagDataForIrregularLangCode, ModeratorStatusToolbarPlugin, } from "../AggregateGrid/AggregateGridPage"; import { @@ -82,7 +83,7 @@ const CountryGridControlInternal: React.FunctionComponent([]); const fullLangDataMap = useMemo(() => { - return fixLanguageRegionDataAndGetMap(rawLangData); + return fixLangTagRegionDataAndGetMap(rawLangData); }, []); const countryIdMap = useMemo(() => { return getCountryIdMapFromLangTagData(rawLangData); @@ -173,7 +174,14 @@ const CountryGridControlInternal: React.FunctionComponent { - const hrefValue = `https://bloomlibrary.org/language:${lang.langTag}`; + const hrefValue = `/language:${lang.langTag}`; return ( - + // we don't need rel="noreferrer" because the destination is on the same website, + // and we want to preserve the login status for the new tab + // eslint-disable-next-line react/jsx-no-target-blank + {lang.exonym} ); @@ -254,18 +253,17 @@ export function getLanguageGridColumnsDefinitions(): IGridColumn[] { sortingEnabled: true, getCellValue: (lang: ILanguageGridRowData) => { const links = lang.uploaderEmails.map((email, index) => { - const hrefValue = `https://bloomlibrary.org/:search:uploader:${email}`; + const hrefValue = `/:search:uploader:${email}`; let separator = ""; if (index < lang.uploaderEmails.length - 1) { separator = ", "; } return ( - + {/* we don't need rel="noreferrer" because the destination is on the same website, + and we want to preserve the login status for the new tab */} + {/*eslint-disable-next-line react/jsx-no-target-blank*/} + {email} {separator} diff --git a/src/components/LanguageGrid/LanguageGridControlInternal.tsx b/src/components/LanguageGrid/LanguageGridControlInternal.tsx index 349cd58d..3377c299 100644 --- a/src/components/LanguageGrid/LanguageGridControlInternal.tsx +++ b/src/components/LanguageGrid/LanguageGridControlInternal.tsx @@ -50,7 +50,8 @@ import { ILanguageGridControlProps } from "./LanguageGridControl"; import { CachedTablesContext } from "../../model/CacheProvider"; import { CachedBookDataContext, - fixLanguageRegionDataAndGetMap, + fixLangTagRegionDataAndGetMap, + getLangTagDataForIrregularLangCode, ModeratorStatusToolbarPlugin, } from "../AggregateGrid/AggregateGridPage"; import { ILangTagData } from "../AggregateGrid/AggregateGridInterfaces"; @@ -77,7 +78,7 @@ const LanguageGridControlInternal: React.FunctionComponent([]); const fullLangDataMap = useMemo(() => { - return fixLanguageRegionDataAndGetMap(rawLangData); + return fixLangTagRegionDataAndGetMap(rawLangData); }, []); const countriesMap = useMemo(() => { const map = new Map(); @@ -123,10 +124,14 @@ const LanguageGridControlInternal: React.FunctionComponent([]); const fullLangDataMap = useMemo(() => { - return fixLanguageRegionDataAndGetMap(rawLangData); + return fixLangTagRegionDataAndGetMap(rawLangData); }, []); // extract a country name map from the language data @@ -160,9 +161,16 @@ const UploaderGridControlInternal: React.FunctionComponent