{ "id": "114449", "key": "TIMOB-13966", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "19882", "name": "Release 8.0.0", "archived": false, "released": true, "releaseDate": "2019-03-14" }, { "id": "20238", "description": "", "name": "Release 7.5.0", "archived": false, "released": true, "releaseDate": "2018-11-15" }, { "id": "20429", "name": "Release 7.5.1", "archived": false, "released": true, "releaseDate": "2019-02-26" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2019-01-10T18:59:25.000+0000", "created": "2013-05-16T10:13:41.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "language", "localization", "runtime" ], "versions": [ { "id": "14162", "description": "Release 3.1.0", "name": "Release 3.1.0", "archived": true, "released": true, "releaseDate": "2013-04-16" } ], "issuelinks": [], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2021-03-15T18:43:30.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "12305", "name": "Core", "description": "Central component of the Platform (outside of Tooling, or platform specific implementation details)" } ], "description": "*Problem*\r\nIt would be great if it was possible to let the user select which language to use at runtime. So instead the L() would only look at device language, it could also check if a Ti.App.LanguageXMLSetting property has been defined. That way we do not need to create homemade localization systems anymore.\r\n\r\nThe use case is included below. The problem is that L is undefined in style.tss because I redefine it in the controller.\r\n\r\n*alloy.js*\r\n{code:javascript}\r\n// Language helper\r\nAlloy.LanguageHelper = require('languageHelper');\r\nAlloy.L = Alloy.LanguageHelper.fetchString;\r\n{code}\r\n\r\n*Controller*\r\n{code:javascript}\r\n//top of the controller\r\nvar L = require(\"languageHelper\");\r\n{code} \r\n\r\n*Style*\r\n{code:javascript} \r\n\"#menuBtn\":{\r\n\ttitle: L(\"MenuButton\")\r\n}\r\n{code}\r\n\r\n*View*\r\n{code:xml}\r\n\r\n\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n\r\n*Custom languageHelper*\r\n{code:javascript}\r\n/**\r\n * Language Helper\r\n * Makes it possible to change language at runtime \r\n * @version 1.0\r\n */\r\n\r\nvar lookup = null;\r\nexports.locale = Ti.App.Properties.getString('SETTING_LANGUAGE', Ti.Locale.getCurrentLanguage() );\r\n\r\n\r\n/**\r\n * Private function\r\n * Loads the language xml file.\r\n * It has fallback for english if file does not exist.\r\n */\r\nfunction loadFile() {\r\n\tlookup = {};\r\n\t\r\n\t// LOAD FILE\r\n\tvar file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'i18n/' + exports.locale + '/strings.xml');\r\n\tif (!file.exists()) {\r\n\t\tfile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'i18n/en/strings.xml');\r\n\t\tif (!file.exists()) {\r\n\t\t\tTi.API.warn(\"Language file for both '\" + exports.locale + \"' and 'en' fallback do not exist\");\r\n\t\t\treturn;\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t// PARSE XML\r\n\tvar xml_string = file.read().text;\r\n \tvar doc = Ti.XML.parseString(xml_string);\r\n\tvar strings = doc.getElementsByTagName(\"string\");\r\n\tfor (var i = 0; i < strings.length; i++) {\r\n\t\tvar node = strings.item(i);\r\n\t\tvar value = node.text;\r\n\t\tif (node.hasAttributes()) {\r\n\t\t\tfor (var att_index = 0; att_index < node.attributes.length; att_index++) {\r\n\t\t\t\tvar att = node.attributes.item(att_index);\r\n\t\t\t\tif (att.nodeName === \"name\") {\r\n\t\t\t\t\tlookup[att.nodeValue] = value;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t\r\n}\r\n\r\n/**\r\n * Set the current language of the app. \r\n * @param {String} language\r\n */\r\nexports.setLanguage = function(language){\r\n\tif(language === null){\r\n\t\treturn;\r\n\t}\r\n\t// clean old lookup\r\n\texports.clear();\r\n\t\r\n\t// save language\r\n\tTi.App.Properties.setString('SETTING_LANGUAGE', language);\r\n\texports.locale = language;\r\n\t\r\n\t\r\n\t// parse new lookup\r\n\tloadFile();\r\n\t\r\n\t\r\n\treturn lookup;\r\n}\r\n\r\n/**\r\n * Clear the parsed xml translations\r\n */\r\nexports.clear = function() {\r\n\tlookup = null;\r\n};\r\n\r\n/**\r\n * Lookup function. require this at each controller\r\n * Example usage:\r\n * var L = require('languageHelper').fetchString;\r\n * @param {Object} string\r\n * @param {Object} hint\r\n */\r\nexports.fetchString = function(string, hint) {\r\n\tif (lookup === null) {\r\n\t\tloadFile();\r\n\t}\r\n\treturn lookup[string] !== undefined ? lookup[string].replace(/\\\\n/g, \"\\n\") : (hint || string);\r\n}; \r\n{code}", "attachment": [], "flagged": false, "summary": "TiAPI: Select Locale for L() at runtime", "creator": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "environment": "3.1.0.GA", "closedSprints": [ { "id": 1058, "state": "closed", "name": "2018 Sprint 16 SDK", "startDate": "2018-07-29T22:26:06.486Z", "endDate": "2018-08-12T22:26:00.000Z", "completeDate": "2018-08-13T17:38:16.757Z", "originBoardId": 114 }, { "id": 1028, "state": "closed", "name": "2018 Sprint 09 SDK", "startDate": "2018-04-22T22:53:08.928Z", "endDate": "2018-05-06T22:53:00.000Z", "completeDate": "2018-05-07T00:02:15.883Z", "originBoardId": 114 }, { "id": 1045, "state": "closed", "name": "2018 Sprint 13 SDK", "startDate": "2018-06-17T20:47:13.621Z", "endDate": "2018-07-01T20:47:00.000Z", "completeDate": "2018-07-02T18:40:05.029Z", "originBoardId": 114 }, { "id": 1034, "state": "closed", "name": "2018 Sprint 10 SDK", "startDate": "2018-05-07T00:03:21.636Z", "endDate": "2018-05-21T00:03:00.000Z", "completeDate": "2018-05-20T20:54:58.928Z", "originBoardId": 114 }, { "id": 1050, "state": "closed", "name": "2018 Sprint 14 SDK", "startDate": "2018-07-01T18:40:57.193Z", "endDate": "2018-07-15T18:40:00.000Z", "completeDate": "2018-07-16T03:27:08.720Z", "originBoardId": 114 }, { "id": 1035, "state": "closed", "name": "2018 Sprint 11 SDK", "startDate": "2018-05-20T20:57:43.542Z", "endDate": "2018-06-03T20:57:00.000Z", "completeDate": "2018-06-04T15:13:14.425Z", "originBoardId": 114 }, { "id": 1021, "state": "closed", "name": "2018 Sprint 08 SDK", "startDate": "2018-04-08T17:57:36.122Z", "endDate": "2018-04-22T17:57:00.000Z", "completeDate": "2018-04-22T22:51:19.120Z", "originBoardId": 114 }, { "id": 1053, "state": "closed", "name": "2018 Sprint 15 SDK", "startDate": "2018-07-15T21:52:05.453Z", "endDate": "2018-07-29T21:52:00.000Z", "completeDate": "2018-07-29T22:25:11.723Z", "originBoardId": 114 }, { "id": 1039, "state": "closed", "name": "2018 Sprint 12 SDK", "startDate": "2018-06-03T15:22:23.401Z", "endDate": "2018-06-17T15:22:00.000Z", "completeDate": "2018-06-18T20:45:36.363Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "252267", "author": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "body": "The big issue here is Alloy. \nI can write my own localization function, and use the i18n structure, if I place the folder inside Resources. But in Alloy, the controller code is compiled after the view/style. \n\nThis means that I cannot have use L() in mycontroller.tss or markup. I will need to have all my text in the controller.\n\nThis is bad design, and not really useful. ", "updateAuthor": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-05-16T13:42:19.000+0000", "updated": "2013-05-16T13:42:19.000+0000" }, { "id": "252268", "author": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Can you include some code that exhibits the issue? Particularly can you show me what you are shopping now to work appc the issue, and what you would expect to be able to do when this issue is resolved. The more clear and concise in these samples toy can be, the more likely it is that they can be implemented sooner rather than later. ", "updateAuthor": { "name": "tlukasavage", "key": "tlukasavage", "displayName": "Tony Lukasavage", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-05-16T14:18:20.000+0000", "updated": "2013-05-16T14:18:20.000+0000" }, { "id": "253601", "author": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "body": "Hi Tony,\n\nThis issue is not just an Alloy bug/feature. \nThe best solution is the ability to change locale at runtime. If thats possible, then Alloy can just continue working as it does. \n\n{code:javascript}\n// this is the best and most flexible solution. \nTi.Locale.setString(\"da\");\n{code}\n\ncheers, \nMads", "updateAuthor": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "created": "2013-05-23T07:03:17.000+0000", "updated": "2013-05-23T07:03:17.000+0000" }, { "id": "296230", "author": { "name": "rborn", "key": "rborn", "displayName": "Dan Tamas", "active": true, "timeZone": "Europe/Berlin" }, "body": "This should work out of the box using\r\n{code}\r\nTi.Locale.setLanguage('es');\r\n{code}\r\n\r\nThis is an undocumented method that exists in Ti [here|https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/LocaleModule.m#L73] for iOS. \r\nOn android seems [not to be supported|https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java#L89] :(\r\n\r\nI works for me in [AsturPlaya|https://itunes.apple.com/es/app/asturplaya/id662587421?ls=1&mt=8] combined with [this module|https://github.com/rborn/tiapprestart]\r\n\r\nHowever this is a classic Ti app, not an Alloy one, and didn't test it yet. But because the app is restarted it should work with no issues.", "updateAuthor": { "name": "rborn", "key": "rborn", "displayName": "Dan Tamas", "active": true, "timeZone": "Europe/Berlin" }, "created": "2014-03-08T14:18:12.000+0000", "updated": "2014-03-08T14:20:34.000+0000" }, { "id": "439684", "author": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "body": "Hurrah @Hans Knöchel. After 5 years its now in progress ;)", "updateAuthor": { "name": "viezel", "key": "viezel", "displayName": "Mads Moller", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-08-02T07:30:28.000+0000", "updated": "2018-08-02T07:30:28.000+0000" }, { "id": "439685", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Ha, I know. It's even reported by you, funny. Let get this party started.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-08-02T07:32:24.000+0000", "updated": "2018-08-02T07:32:24.000+0000" }, { "id": "439687", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR: https://github.com/appcelerator/titanium_mobile/pull/10227\r\n\r\nTest-Setup (requires a {{hello_world}} language file in i18n/de and i18n/en):\r\n{code:js}\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: '#fff'\r\n });\r\n\r\n var label = Ti.UI.createLabel({\r\n text: 'Current Locale: ' + Ti.Locale.currentLanguage + ' (' + L('hello_world') + ')',\r\n top: 100\r\n })\r\n \r\n var btn = Ti.UI.createButton({\r\n title: 'Change to German'\r\n });\r\n \r\n btn.addEventListener('click', function() {\r\n Ti.Locale.setLanguage('de');\r\n });\r\n \r\n win.add(btn);\r\n win.add(label);\r\n win.open();\r\n{code}\r\n\r\n\r\nSome notes here:\r\n- It seems like (different to the initial discussion) the API [is documented|https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Locale-method-setLanguage] by now\r\n- It seems like (different to the initial discussion) the API is also [supported on Android|https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/locale/src/java/ti/modules/titanium/locale/LocaleModule.java#L95] already\r\n\r\nThis PR will fix one remaining issue on iOS that prevents the locale to be forgotten across app-launches. I added a simple {{UserDefaults}} setting to hook into that behavior and clean it up. The only remaining thing I am wondering is if we should expose the {{Ti.App.restart()}} method as well, to restart the app for the user. This is pretty much against the native behavior and could lead in an app rejection, so I'd like to put down my vote against this for now.\r\n \r\n[~gmathews] [~jquick] Are we good on Android? ", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-08-02T08:19:51.000+0000", "updated": "2018-08-02T08:19:51.000+0000" }, { "id": "442794", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified feature on SDK Version {{7.5.0.v20181018133006}}. Tested using the test case provided by [~hknoechel] on iOS.\r\n\r\n*Test Environment*\r\n{code:java}\r\nAPPC Studio: 5.1.0.201808080937\r\niPhone 6 Sim (iOS 12)\r\nAPPC CLI: 7.0.6\r\nOperating System Name: Mac OS Mojave\r\nOperating System Version: 10.14\r\nNode.js Version: 8.9.1\r\nXcode 10.0{code}\r\n", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-10-19T13:29:05.000+0000", "updated": "2018-10-19T13:29:05.000+0000" }, { "id": "442981", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "*Closing ticket* If any issue remains please reopen.", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-10-26T11:20:19.000+0000", "updated": "2018-10-26T11:20:19.000+0000" }, { "id": "443684", "author": { "name": "teunklijn@telfort.nl", "key": "teunklijn@telfort.nl", "displayName": "Teun Klijn", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Doesn't seem to work correctly on *Android*, setting the textid directly does work. When you get a string with L('key') it doesn't work, what is strange is that it does seem to work when you run the app with liveview enabled.\r\n\r\nTest on: Samung s9 (Android 8.0.0) and emulator (Android 8.0.0).\r\nSDK: 7.5.0.GA\r\n\r\nExample (does need to have the strings.xml file):\r\n{code:java}\r\n// est-Setup (requires a hello_world language file in i18n/de and i18n/en)\r\n\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: '#fff'\r\n});\r\n\r\nvar label = Ti.UI.createLabel({\r\n text: 'Current Locale: ' + Ti.Locale.currentLanguage + ' (' + L('hello_world') + ')',\r\n top: 100,\r\n color: 'black'\r\n});\r\n\r\nvar btn = Ti.UI.createButton({\r\n title: 'Change'\r\n});\r\n\r\nbtn.addEventListener('click', function () {\r\n var newLang = Ti.Locale.currentLanguage == 'de' ? 'en' : 'de';\r\n Ti.Locale.setLanguage(newLang);\r\n label.text = 'Current Locale: ' + Ti.Locale.currentLanguage + ' (' + L('hello_world') + ')';\r\n});\r\n\r\nwin.add(btn);\r\nwin.add(label);\r\nwin.open();\r\n{code}\r\n", "updateAuthor": { "name": "teunklijn@telfort.nl", "key": "teunklijn@telfort.nl", "displayName": "Teun Klijn", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2018-11-16T11:18:36.000+0000", "updated": "2018-11-16T11:18:36.000+0000" }, { "id": "444580", "author": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "body": "Also doesn't work with me but it was working great with 7.4.1", "updateAuthor": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "created": "2018-12-13T15:40:07.000+0000", "updated": "2018-12-13T15:40:07.000+0000" }, { "id": "444598", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "Verified that it is an issue on {{7.5.0.GA}} on android, it has been fixed on master tested with {{SDK 8.0.0.v20181213061450}}", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2018-12-14T15:36:05.000+0000", "updated": "2018-12-14T15:36:05.000+0000" }, { "id": "444599", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Will this be backported into 7.5.1?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-12-14T15:42:50.000+0000", "updated": "2018-12-14T15:42:50.000+0000" }, { "id": "444623", "author": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~vijaysingh] Can you please create a 7.5.1 backport?", "updateAuthor": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-12-15T02:13:34.000+0000", "updated": "2018-12-15T02:13:34.000+0000" }, { "id": "444624", "author": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Reopened to update fix version to include 7.5.1 backport", "updateAuthor": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-12-15T02:14:52.000+0000", "updated": "2018-12-15T02:14:52.000+0000" }, { "id": "444634", "author": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "body": "Did this backport has been merged yet?", "updateAuthor": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "created": "2018-12-17T00:23:22.000+0000", "updated": "2018-12-17T00:23:22.000+0000" }, { "id": "444653", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Can someone clarify if locales are stable in 7.5.1 (both iOS and Android)?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-12-17T20:05:40.000+0000", "updated": "2018-12-17T20:05:40.000+0000" }, { "id": "444681", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "I found that it was specific to the android version, results are below.\r\n\r\n|| ||7.4.1.GA||7.5.0.GA||8.0.0.v20181217103214||\r\n|4.4.2|(/)|(/)|(/)|\r\n|6.0|(/)|(/)|(/)|\r\n|8.1|(/)|(x)|(x)|\r\n|9.0|(/)|(x)|(x)|", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2018-12-18T12:13:56.000+0000", "updated": "2018-12-18T12:13:56.000+0000" }, { "id": "444749", "author": { "name": "ybanev", "key": "ybanev", "displayName": "Yordan Banev", "active": true, "timeZone": "Europe/Athens" }, "body": "This PR should fix this.\r\nhttps://github.com/appcelerator/titanium_mobile/pull/10549\r\nCurrently for master. We will discuss a backport in case it passes CR and FR.", "updateAuthor": { "name": "ybanev", "key": "ybanev", "displayName": "Yordan Banev", "active": true, "timeZone": "Europe/Athens" }, "created": "2018-12-19T18:18:07.000+0000", "updated": "2018-12-19T18:18:07.000+0000" }, { "id": "445050", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Please note that changing language on Android broke in Titanium 7.5.0 due to an undocumented breaking-change on Google's end. It'll only happen if your app targets Android P/9 (aka: API Level 28).\r\n\r\nYordan's above PR fixes it in Titanium 8.0.0.\r\n\r\nYou can also work-around the issue by \"targeting\" API Level 27.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-07T22:15:36.000+0000", "updated": "2019-01-07T22:15:36.000+0000" }, { "id": "445057", "author": { "name": "prashant_saini_1", "key": "prashant_saini_1", "displayName": "Prashant Saini", "active": true, "timeZone": "Asia/Kolkata" }, "body": "@Joshua, if we change the targetSDK version to 27 with SDK 7.5.x, will our app continue to work fine on Android OS 28 as well?\r\nI would like to stick to L('string') method so that when we get 8.x.x release, we won't need to change anything. so what is the best possible solution at present as we can't go back to any SDK than 7.5.x?", "updateAuthor": { "name": "prashant_saini_1", "key": "prashant_saini_1", "displayName": "Prashant Saini", "active": true, "timeZone": "Asia/Kolkata" }, "created": "2019-01-08T07:14:16.000+0000", "updated": "2019-01-08T07:14:16.000+0000" }, { "id": "445058", "author": { "name": "prashant_saini_1", "key": "prashant_saini_1", "displayName": "Prashant Saini", "active": true, "timeZone": "Asia/Kolkata" }, "body": "@Joshua, I just changed the Target-SDK with 7.5.1.RC build and it still doesn't work properly.", "updateAuthor": { "name": "prashant_saini_1", "key": "prashant_saini_1", "displayName": "Prashant Saini", "active": true, "timeZone": "Asia/Kolkata" }, "created": "2019-01-08T07:31:25.000+0000", "updated": "2019-01-08T07:31:25.000+0000" }, { "id": "445080", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "*FR Passed*. \r\nWaiting on Jenkins to merge.", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2019-01-08T15:58:55.000+0000", "updated": "2019-01-08T15:58:55.000+0000" }, { "id": "445083", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "merged to master/8_0_X", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2019-01-08T18:45:23.000+0000", "updated": "2019-01-08T18:45:23.000+0000" }, { "id": "445115", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Re-opening...\r\n\r\nYordan's PR does fix the issue with {{L()}}, but now {{titleid}} and {{textid}} no longer read from the selected language/locale. And it happens on all Android OS versions when building with Titanium 8.0.0. (Building with 7.5.0 is fine.)\r\n\r\n_*Edit:*_\r\n_I've isolated the issue. The problem is that the old code (before the last merged PR) did not load resources from the same context objects. The {{L()}} function loaded strings from the application context. The localized string ID properties load strings from the top-most or previous activity context. The issue here is that Android 8.0 and above's context objects no longer share the same resources/configuration objects. Best solution is to have them load resources from the same object for consistency. Yordan's last PR which updates the language/locale of the application context is the right move since backing out of the app and relaunch the main activity will preserve the last set language/locale setting._\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-09T00:07:48.000+0000", "updated": "2019-01-09T03:35:16.000+0000" }, { "id": "445117", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/10591\r\nPR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10592\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-09T03:36:14.000+0000", "updated": "2019-01-09T03:36:14.000+0000" }, { "id": "445189", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed.\r\nPR's merged.", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-10T18:59:19.000+0000", "updated": "2019-01-10T18:59:19.000+0000" }, { "id": "445225", "author": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "body": "Will this PR merge to 7.5.1?", "updateAuthor": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "created": "2019-01-11T17:27:44.000+0000", "updated": "2019-01-11T17:27:44.000+0000" }, { "id": "445235", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~ahmed.mohamed20320], no plans at the moment. Currently, all resources are on 8.0.0 to get a release candidate out in the near future. Stay tuned.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-11T22:26:30.000+0000", "updated": "2019-01-11T22:26:30.000+0000" }, { "id": "445237", "author": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "body": "Ok, I will check it out, I ask because the fix version is for 8.0.0,7.5.0 and 7.51", "updateAuthor": { "name": "ahmed.mohamed20320", "key": "ahmed.mohamed20320", "displayName": "Ahmed Mohamed", "active": true, "timeZone": "Africa/Cairo" }, "created": "2019-01-12T00:29:40.000+0000", "updated": "2019-01-12T00:29:40.000+0000" }, { "id": "445238", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~ahmed.mohamed20320],\r\n\r\nThis issue was resolved on iOS in 7.5.0.\r\nhttps://github.com/appcelerator/titanium_mobile/pull/10227\r\n\r\nThis issue will be resolved on Android in 8.0.0.\r\nhttps://github.com/appcelerator/titanium_mobile/pull/10549\r\nhttps://github.com/appcelerator/titanium_mobile/pull/10592\r\n\r\nWe don't normally mix platforms and fixed releases like this in the same ticket. I apologize for the confusion. We should have split this into 2 separate tickets.\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-01-12T01:49:05.000+0000", "updated": "2019-01-12T01:49:05.000+0000" }, { "id": "445272", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "*Closing ticket.*\r\n\r\nFixes from [PR/10227|https://github.com/appcelerator/titanium_mobile/pull/10227], [PR/10549|https://github.com/appcelerator/titanium_mobile/pull/10549] and [PR/10592|https://github.com/appcelerator/titanium_mobile/pull/10592] are all present in SDK\r\n\r\n{noformat}\r\n8.0.0.v20190114020205\r\n{noformat}", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2019-01-14T11:45:44.000+0000", "updated": "2019-01-14T11:45:44.000+0000" }, { "id": "446057", "author": { "name": "saidCh", "key": "saidch", "displayName": "said chaouche", "active": true, "timeZone": "Africa/Algiers" }, "body": "workaround in 7.5.0\r\nhttps://github.com/genocsb/titanium_i18n", "updateAuthor": { "name": "saidCh", "key": "saidch", "displayName": "said chaouche", "active": true, "timeZone": "Africa/Algiers" }, "created": "2019-02-13T22:46:47.000+0000", "updated": "2019-02-13T22:46:47.000+0000" }, { "id": "458408", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Quick question in the round: Does this work across app launches? Or does it have to be manually applied on each app start?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-03-13T11:25:19.000+0000", "updated": "2021-03-13T11:25:19.000+0000" }, { "id": "458414", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~hknoechel], on Android, you have to call {{setLanguage()}} manually on every app startup or else it'll use the system's locale/language.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2021-03-15T18:43:30.000+0000", "updated": "2021-03-15T18:43:30.000+0000" } ], "maxResults": 46, "total": 46, "startAt": 0 } } }