From 69fa7a4edbb8dcdfa25c9e6c4071b886b7d6c7d3 Mon Sep 17 00:00:00 2001 From: valer23 Date: Fri, 17 Apr 2026 10:39:33 +0200 Subject: [PATCH] fix: handle parenthetical qualifiers and multi-comma server names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parse server names more robustly for sorting: - "City, Country, Provider" → use second part as country - "City, Country (1) (Hetzner)" → strip parentheticals from country - "Frankfurt, Germany (FRA01)" → country is "Germany" not "Germany (FRA01)" --- frontend/javascript/index.js | 33 +++++++++++++++++++++++---------- index-classic.html | 30 +++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/frontend/javascript/index.js b/frontend/javascript/index.js index e7f4aa4..9935bd4 100644 --- a/frontend/javascript/index.js +++ b/frontend/javascript/index.js @@ -230,17 +230,30 @@ function populateDropdown(servers) { }); } - // Sort servers by country, then by city within the same country + // Sort servers by country, then by city within the same country. + // Name formats: "City, Country", "City, Country (qualifier)", "City, Country, Provider", "Country" + const parseServerName = (name) => { + const parts = (name || "").split(",").map((s) => s.trim()); + let country, city; + if (parts.length >= 3) { + // "City, Country, Provider" — use second part as country + country = parts[1]; + city = parts[0]; + } else if (parts.length === 2) { + country = parts[1]; + city = parts[0]; + } else { + country = parts[0]; + city = ""; + } + // Strip parenthetical qualifiers for sorting: "Germany (1) (Hetzner)" → "Germany" + country = country.replace(/\s*\([^)]*\)\s*/g, "").trim(); + return { country, city }; + }; const sorted = [...servers].sort((a, b) => { - const nameA = a.name || ""; - const nameB = b.name || ""; - const commaA = nameA.lastIndexOf(","); - const commaB = nameB.lastIndexOf(","); - const countryA = commaA >= 0 ? nameA.substring(commaA + 1).trim() : nameA; - const countryB = commaB >= 0 ? nameB.substring(commaB + 1).trim() : nameB; - const cityA = commaA >= 0 ? nameA.substring(0, commaA).trim() : ""; - const cityB = commaB >= 0 ? nameB.substring(0, commaB).trim() : ""; - return countryA.localeCompare(countryB) || cityA.localeCompare(cityB); + const pa = parseServerName(a.name); + const pb = parseServerName(b.name); + return pa.country.localeCompare(pb.country) || pa.city.localeCompare(pb.city); }); // Populate the list to choose from diff --git a/index-classic.html b/index-classic.html index 9a8c0fd..036191c 100644 --- a/index-classic.html +++ b/index-classic.html @@ -51,16 +51,28 @@ if (server != null) { //at least 1 server is available I("loading").className = "hidden"; //hide loading message //sort servers by country, then by city + //name formats: "City, Country", "City, Country (qualifier)", "City, Country, Provider", "Country" + function parseServerName(name) { + var parts = (name || "").split(","); + for (var p = 0; p < parts.length; p++) parts[p] = parts[p].trim(); + var country, city; + if (parts.length >= 3) { + country = parts[1]; + city = parts[0]; + } else if (parts.length === 2) { + country = parts[1]; + city = parts[0]; + } else { + country = parts[0]; + city = ""; + } + country = country.replace(/\s*\([^)]*\)\s*/g, "").trim(); + return { country: country, city: city }; + } var sortedServers = SPEEDTEST_SERVERS.slice().sort(function (a, b) { - var nameA = a.name || ""; - var nameB = b.name || ""; - var commaA = nameA.lastIndexOf(","); - var commaB = nameB.lastIndexOf(","); - var countryA = commaA >= 0 ? nameA.substring(commaA + 1).trim() : nameA; - var countryB = commaB >= 0 ? nameB.substring(commaB + 1).trim() : nameB; - var cityA = commaA >= 0 ? nameA.substring(0, commaA).trim() : ""; - var cityB = commaB >= 0 ? nameB.substring(0, commaB).trim() : ""; - return countryA.localeCompare(countryB) || cityA.localeCompare(cityB); + var pa = parseServerName(a.name); + var pb = parseServerName(b.name); + return pa.country.localeCompare(pb.country) || pa.city.localeCompare(pb.city); }); //populate server list for manual selection for (var i = 0; i < sortedServers.length; i++) {