{"action":"created","issue":{"url":"https://api.github.com/repos/uProxy/uproxy/issues/2705","repository_url":"https://api.github.com/repos/uProxy/uproxy","labels_url":"https://api.github.com/repos/uProxy/uproxy/issues/2705/labels{/name}","comments_url":"https://api.github.com/repos/uProxy/uproxy/issues/2705/comments","events_url":"https://api.github.com/repos/uProxy/uproxy/issues/2705/events","html_url":"https://github.com/uProxy/uproxy/pull/2705","id":171519584,"number":2705,"title":"Update strings in UI without reloading (fixes translation on Android!)","user":{"login":"lucyhe","id":8723127,"avatar_url":"https://avatars.githubusercontent.com/u/8723127?v=3","gravatar_id":"","url":"https://api.github.com/users/lucyhe","html_url":"https://github.com/lucyhe","followers_url":"https://api.github.com/users/lucyhe/followers","following_url":"https://api.github.com/users/lucyhe/following{/other_user}","gists_url":"https://api.github.com/users/lucyhe/gists{/gist_id}","starred_url":"https://api.github.com/users/lucyhe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lucyhe/subscriptions","organizations_url":"https://api.github.com/users/lucyhe/orgs","repos_url":"https://api.github.com/users/lucyhe/repos","events_url":"https://api.github.com/users/lucyhe/events{/privacy}","received_events_url":"https://api.github.com/users/lucyhe/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"bemasc","id":191945,"avatar_url":"https://avatars.githubusercontent.com/u/191945?v=3","gravatar_id":"","url":"https://api.github.com/users/bemasc","html_url":"https://github.com/bemasc","followers_url":"https://api.github.com/users/bemasc/followers","following_url":"https://api.github.com/users/bemasc/following{/other_user}","gists_url":"https://api.github.com/users/bemasc/gists{/gist_id}","starred_url":"https://api.github.com/users/bemasc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bemasc/subscriptions","organizations_url":"https://api.github.com/users/bemasc/orgs","repos_url":"https://api.github.com/users/bemasc/repos","events_url":"https://api.github.com/users/bemasc/events{/privacy}","received_events_url":"https://api.github.com/users/bemasc/received_events","type":"User","site_admin":false},"assignees":[{"login":"bemasc","id":191945,"avatar_url":"https://avatars.githubusercontent.com/u/191945?v=3","gravatar_id":"","url":"https://api.github.com/users/bemasc","html_url":"https://github.com/bemasc","followers_url":"https://api.github.com/users/bemasc/followers","following_url":"https://api.github.com/users/bemasc/following{/other_user}","gists_url":"https://api.github.com/users/bemasc/gists{/gist_id}","starred_url":"https://api.github.com/users/bemasc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bemasc/subscriptions","organizations_url":"https://api.github.com/users/bemasc/orgs","repos_url":"https://api.github.com/users/bemasc/repos","events_url":"https://api.github.com/users/bemasc/events{/privacy}","received_events_url":"https://api.github.com/users/bemasc/received_events","type":"User","site_admin":false}],"milestone":null,"comments":2,"created_at":"2016-08-16T21:13:56Z","updated_at":"2016-08-18T02:36:49Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/uProxy/uproxy/pulls/2705","html_url":"https://github.com/uProxy/uproxy/pull/2705","diff_url":"https://github.com/uProxy/uproxy/pull/2705.diff","patch_url":"https://github.com/uProxy/uproxy/pull/2705.patch"},"body":"Problem in a nutshell:\r\n- The only way to force Polymer bindings to update is by updating a function parameter in the bound Polymer expression.\r\n- Before this change, we mostly had constants in the translation Polymer expressions, e.g. {{ \"APP_MISSING_TITLE\" | $$ }}\r\n- Therefore, changing languages required saving the new language to local storage, and then refreshing the UI\r\n- If loading from global storage took too long, the UI would get stuck in a reload loop: first, the default language (English) would load, another language French (for example) is loaded from storage, the UI reloads, but then English is used again while waiting for storage to load...etc\r\n\r\nSolution:\r\n- Add model.globalSettings.language to each translation Polymer expression, forcing it to update if the language updates\r\n- Remove reloading code related to i18n\r\n- important Remove all calls to ui.i18n_t made at start up time. This is because there are no observers on the input or output of ui.i18n_t and we can not refresh strings created by ui.i18n_t when the language has changed. Instead, ui.i18n_t should only be used when we are adding new text to the DOM (after start up), for example, in a dialog. This will work because when calls to ui.i18n_t are made on the fly, the translator module will be able to refer to the most recently set language.\r\n- Example: connectedNetworks was a string in settings.ts/settings.html that would get translated with ui.i18n_t at start up. It was referred to in Polymer by {{ connectedNetworks }} <-- without a reference to the globalSettings.language, this string will not know to update if the user changes the language! Instead we need to move the logic for setting connectedNetworks into Polymer translation expressions.\r\n\r\n**Most important things (will add to docs):**\r\nTranslation in HTML files before: {{ \"PLACEHOLDER\" | $$({param1: value1...}) }}\r\nTranslation in HTML files after:{{ \"PLACEHOLDER\" | $$(model.globalSettings.language, {param1: value1...}) }}\r\nTranslation in JS files before: translator.i18n_t(\"PLACEHOLDER\", {param1: value1...})\r\nTranslation in JS files after: ui.i18n_t(\"PLACEHOLDER\", {param1: value1...}) <-- same but you cant do this for any strings needed at start up time.\n\n<!-- Reviewable:start -->\n---\nThis change is [<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/uproxy/uproxy/2705)\n<!-- Reviewable:end -->\n"},"comment":{"url":"https://api.github.com/repos/uProxy/uproxy/issues/comments/240608033","html_url":"https://github.com/uProxy/uproxy/pull/2705#issuecomment-240608033","issue_url":"https://api.github.com/repos/uProxy/uproxy/issues/2705","id":240608033,"user":{"login":"lucyhe","id":8723127,"avatar_url":"https://avatars.githubusercontent.com/u/8723127?v=3","gravatar_id":"","url":"https://api.github.com/users/lucyhe","html_url":"https://github.com/lucyhe","followers_url":"https://api.github.com/users/lucyhe/followers","following_url":"https://api.github.com/users/lucyhe/following{/other_user}","gists_url":"https://api.github.com/users/lucyhe/gists{/gist_id}","starred_url":"https://api.github.com/users/lucyhe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lucyhe/subscriptions","organizations_url":"https://api.github.com/users/lucyhe/orgs","repos_url":"https://api.github.com/users/lucyhe/repos","events_url":"https://api.github.com/users/lucyhe/events{/privacy}","received_events_url":"https://api.github.com/users/lucyhe/received_events","type":"User","site_admin":false},"created_at":"2016-08-18T02:36:49Z","updated_at":"2016-08-18T02:36:49Z","body":"Chatted in person, but for reference:\r\n\r\nI couldn't get this to work in uProxy, so I tried out the basic concept in a Polymer fiddle: https://jsfiddle.net/uq238zu7/2/. It seems like changing the function referenced by the filter will not cause the bound expression to refresh/update. This can be confirmed in the fiddle because calling the filter function (via the \"alert\" button) can produce a different result than the string bound in the template (which never updates).\r\n\r\nI suspect that updating the filter function will not update the bound expressions because Polymer elements have no \"watcher\" for a global Polymer filter. Because of this, we tried two other approaches:\r\n\r\n1) Use {{ ui.i18n_t(\"MESSAGE_STR\") }} instead of {{ \"MESSAGE_STR\" | $$ }}, since this.ui *should* be watched for updates. Unfortunately this produced a `Only identifier function invocations are allowed` error; quick search showed that Polymer doesn't allow us to call functions of other objects in expressions, but only functions defined in that element (i.e. any foo for this.foo).\r\n\r\n2) Given the insight learned from 1), I added a new (local) function, $$, to the Polymer element. this.$$ is set to ui.i18n_t initially, and then when the language changed, we updated the pointer of this.$$ to a new i18n_t of the new language. Unfortunately this also didn't work. I again tried the basic concept in a Polymer fiddle: https://jsfiddle.net/jtmu5v3u/1/\r\n\r\nI think Polymer just must not watch for function reference changes at all, or at least they are disregarded wrt when to update bound expressions. The [expression documentation](https://docs-05-dot-polymer-project.appspot.com/0.5/docs/polymer/expressions.html#expression-syntax) does only mention that refreshes happen when parameters update: \"The function’s arguments are observed for changes, and the expression is re-evaluated whenever one of the arguments changes.\""}}
{"actor":{"display_login":"lucyhe"}}