-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
gui: Fix incorrect UI language auto detection (fixes #9668) #9669
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
gui: Fix incorrect UI language auto detection (fixes #9668) #9669
Conversation
Currently, the code only checks whether the detected language partially matches one of the available languages. This means that if the detected language is "fi" but among the available languages there is only "fil" and no "fi", then it will match "fi" with "fil", even though the two are completely different languages. With this change, the matching is only done when there is a hyphen in the language code, e.g. "en" will match with "en-US", and the other way round, "en-US" will match with "en" (if "en-US" is not available). Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be easier to just strip off anything following a -
character, and then doing an exact comparison?
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Done, I think so. |
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Until now, we did not fall back to a lesser specified variant automatically. For example, if a browser is configured to prefer "en-US", then we should not fall back to "en" automatically, just as we don't fall back from one to another "zh-*" variant. I'd expect browsers to either automatically specify the broader codes ("en") in addition, or the user to configure them next to the more specific variant. This avoids wrong conclusions and allows an actual preference ordering. We should not introduce this fallback direction IMHO. At least that's how I understand the existing code comment: I do have some ideas how to simplify the code, but first we need to agree on that goal. Should our "en" language be matched by any "en-XX" variant that the browser sent? I think it should not. |
The current code is broken though, i.e. it does specifically that. The browser requests
It already does fall back to
Why not? This should happen only if the specific variant of Edit: Basically, what happens in real life is that the browser requests |
That should be fixed while we're at it, IMHO.
Yes, this direction is fine. The preference basically says "Korean, but I don't care about the exact variant", and we give it the one we have. If the preference were If the browser says the user prefers Canadian French ( I for example have configured English (US) and German in Firefox. The resulting preference includes See here for the related specification: https://www.rfc-editor.org/rfc/rfc4647.html#section-3.3.1 |
Just to get things straight then:
Is this direction correct? From less specific to more specific only?
Yeah, it does this for English specifically but not for other languages. For example, if you select Chinese (Hong Kong), it requests just |
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
I've rewritten the whole thing. Now it only matches I've also changed some variable names, mainly |
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is getting too complicated with the reverse sort order and all. Let's take it back to a prototype and test concrete scenarios outside of the Syncthing GUI, then discuss any results that need changing. Here's my experimentation code, tested on https://www.jsplayground.dev/
function foo(langs) {
// Find the first language in the list provided by the user's browser
// that is a prefix of a language we have available. That is, "en"
// sent by the browser will match "en" or "en-US", while "zh-TW" will
// match only "zh-TW" and not "zh" or "zh-CN".
var i,
browserLang,
matching,
locale = _defaultLocale; // Fallback if nothing matched
for (i = 0; i < langs.length; i++) {
browserLang = langs[i];
if (browserLang.length < 2) {
continue;
}
matching = _availableLocales.find(function (possibleLang) {
// The langs returned by the /svc/langs call will be in lower
// case. We compare to the lowercase version of the language
// code we have as well.
possibleLang = possibleLang.toLowerCase();
if (possibleLang.indexOf(browserLang) !== 0) {
// Prefix does not match
return false;
}
console.log("compare", browserLang, possibleLang);
if (possibleLang.length > browserLang.length) {
// Must match up to the next hyphen separator
return possibleLang[browserLang.length] === '-';
}
console.log("same length, exact match");
// Same length, exact match
return true;
});
if (matching) {
console.log("matching", browserLang, matching);
locale = matching;
break;
}
}
useLocale(locale);
}
var _availableLocales = ["ar","bg","ca","ca@valencia","cs","da","de","el","en","en-GB","es","eu","fil","fr","fy","ga","hi","hu","id","it","ja","ko-KR","lt","nl","pl","pt-BR","pt-PT","ro-RO","ru","sk","sl","sv","tr","uk","zh-CN","zh-HK","zh-TW"];
var _defaultLocale = "en";
function useLocale(locale) { console.log("Result:", locale, "\n") }
foo(["zh-tw", "ko", "en-gb!"]);
foo(["zh!", "ko", "en-us"]);
foo(["zh", "ko!", "en-us"]);
foo(["pt", "!en", "de"]);
I can make a separate PR with these changes if you like and find it functional in your testing. Otherwise, please provide parameter sets that fail and what you think the result should be. Of course, you can integrate that variant into this PR as well.
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I'm not super happy with using .filter()
because it seems enough to abort on first match. But in this case at least it's easier to see all possible matches and validate the algorithm works as intended.
Some comment fixes, see below.
Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
* main: gui, man, authors: Update docs, translations, and contributors gui: Actually filter scope ID out of IPv6 address when using Remote GUI (ref syncthing#8084) (syncthing#9688) Revert "lib/fs: Put the caseFS as the outermost layer (syncthing#9648)" lib/api: Correct ordering of Accept-Language codes by weight (fixes syncthing#9670) (syncthing#9671) gui, man, authors: Update docs, translations, and contributors gui: Fix incorrect UI language auto detection (fixes syncthing#9668) (syncthing#9669) lib/model, lib/protocol: Index sending/receiving debugging (syncthing#9657) lib/upgrade: Send OS version header to upgrade server (syncthing#9663) lib/upgrade: Send OS version header to upgrade server (syncthing#9663) gui, man, authors: Update docs, translations, and contributors
gui: Fix incorrect UI language auto detection (fixes #9668)
Currently, the code only checks whether the detected language partially
matches one of the available languages. This means that if the detected
language is "fi" but among the available languages there is only "fil"
and no "fi", then it will match "fi" with "fil", even though the two are
completely different languages.
With this change, the matching is only done when there is a hyphen in
the language code, e.g. "en" will match with "en-US".
Signed-off-by: Tomasz Wilczyński twilczynski@naver.com