Annotation of modules/damieng/graphical_editor/loncapa_daxe/web/lcd_strings.dart, revision 1.4

1.1       damieng     1: /*
                      2:   This file is part of LONCAPA-Daxe.
                      3: 
                      4:   LONCAPA-Daxe is free software: you can redistribute it and/or modify
                      5:   it under the terms of the GNU General Public License as published by
                      6:   the Free Software Foundation, either version 3 of the License, or
                      7:   (at your option) any later version.
                      8: 
                      9:   LONCAPA-Daxe is distributed in the hope that it will be useful,
                     10:   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:   GNU General Public License for more details.
                     13: 
                     14:   You should have received a copy of the GNU General Public License
                     15:   along with Daxe.  If not, see <http://www.gnu.org/licenses/>.
                     16: */
                     17: 
1.4     ! raeburn    18: // $Id: lcd_strings.dart,v 1.3 2024/03/25 17:21:14 raeburn Exp $
1.3       raeburn    19: 
1.1       damieng    20: /// Provides localized strings.
                     21: library LCDStrings;
                     22: 
                     23: import 'dart:async';
                     24: import 'dart:collection';
                     25: import 'dart:html' as h;
                     26: import 'package:intl/intl_browser.dart'; // or intl-standalone (see findSystemLocale)
                     27: 
                     28: 
                     29: /**
                     30:  * Provides localized strings read from properties files.
                     31:  * The current language file is read at application loading time.
                     32:  */
                     33: class LCDStrings {
                     34:   
                     35:   static String resourcePath = "LocalStrings";
                     36:   static HashMap<String, String> map = null;
                     37:   static String systemLocale;
                     38:   static const defaultLocale = 'en';
                     39:   
                     40:   static Future<bool> load() {
                     41:     Completer<bool> completer = new Completer<bool>();
1.4     ! raeburn    42:     getLCLanguage().then((String ul) {
        !            43:       if (ul != null)
        !            44:         systemLocale = ul;
1.1       damieng    45:       else
                     46:         systemLocale = defaultLocale;
                     47:       String language = systemLocale.split('_')[0];
                     48:       String fullFilePath = "${resourcePath}_$language.properties";
1.2       damieng    49:       _request(fullFilePath, completer);
1.1       damieng    50:     });
                     51:     return(completer.future);
                     52:   }
1.4     ! raeburn    53: 
        !            54: /*
        !            55:  * Customization to use a user's language preference in LON-CAPA if available,
        !            56:  * otherwise default to en.
        !            57:  *
        !            58:  * Post a message from the iframe to the parent with userlclang as data passed
        !            59:  * Listen for message posted back from parent with userlclang:locale
        !            60:  * where locale is one of LON-CAPA's supported languages:
        !            61:  * en de ar fa fr he ja ko pt ru tr zh.  systemLocale will be set to this in
        !            62:  * load().  If no message is received within 500 ms, then completer completes
        !            63:  * and returns null, and load() will set systemLocale to default (en). 
        !            64:  *
        !            65:  * A similar function is needed in strings.dart in daxe/lib/src because the UI
        !            66:  * contains strings from LocalStrings_<lang>.properties in daxe/lib/src
        !            67:  * and also from LocalStrings_<lang>.properties in loncapa_daxe/web
        !            68:  */
        !            69:   
        !            70:   static Future<String> getLCLanguage() {
        !            71:     Completer<String> completer = new Completer<String>();
        !            72:     String ul = null;
        !            73:     Duration delay = new Duration(milliseconds:500);
        !            74:     Timer lctimer = new Timer(delay,() {
        !            75:       if (!completer.isCompleted)
        !            76:         completer.complete(ul);
        !            77:     });
        !            78:     if (!completer.isCompleted) {
        !            79:       String msgtarget = h.window.location.protocol+'//'+h.window.location.hostname;
        !            80:       h.window.parent.postMessage('userlclang',msgtarget);
        !            81:       h.window.onMessage.listen((event) {
        !            82:         if (event.origin == msgtarget) {
        !            83:           List<String> msgdata = event.data.split(':');
        !            84:           if (msgdata[0] == 'userlclang') {
        !            85:             final RegExp usablelang = new RegExp("^(en|de|ar|fa|fr|he|ja|ko|pt|ru|tr|zh)\$");
        !            86:             if (usablelang.hasMatch(msgdata[1]))
        !            87:               ul = msgdata[1];
        !            88:             lctimer.cancel();
        !            89:             if (!completer.isCompleted)
        !            90:               completer.complete(ul);
        !            91:           }
        !            92:         }
        !            93:       });
        !            94:     }
        !            95:     return(completer.future);
        !            96:   }
1.1       damieng    97:   
                     98:   static String get(String key) {
                     99:     return(map[key]);
                    100:   }
                    101:   
1.2       damieng   102:   static void _request(String fullFilePath, Completer<bool> completer) {
                    103:     h.HttpRequest request = new h.HttpRequest();
                    104:     request.open("GET", fullFilePath);
                    105:     request.onLoad.listen((h.ProgressEvent event) {
                    106:       if (request.status == 404) {
                    107:         // no localization for this language, use default instead
                    108:         String defaultLanguage = defaultLocale.split('_')[0];
                    109:         String defaultFullFilePath = "${resourcePath}_$defaultLanguage.properties";
                    110:         if (fullFilePath == defaultFullFilePath)
                    111:           completer.completeError("Error when reading the strings in $resourcePath");
                    112:         else
                    113:           _request(defaultFullFilePath, completer);
                    114:       } else if (request.status != 200) {
                    115:         completer.completeError("Error when reading the strings in $resourcePath");
                    116:       } else {
                    117:         _parseResponse(request.responseText);
                    118:         completer.complete(true);
                    119:       }
                    120:     });
                    121:     request.onError.listen((h.ProgressEvent event) {
                    122:       completer.completeError("Error when reading the strings in $resourcePath");
                    123:     });
                    124:     request.send();
                    125:   }
                    126:   
                    127:   static void _parseResponse(String txt) {
                    128:     map = new HashMap<String, String>();
                    129:     List<String> lines = txt.split("\n");
                    130:     for (String line in lines) {
                    131:       if (line.startsWith('#'))
                    132:         continue;
                    133:       int ind = line.indexOf('=');
                    134:       if (ind == -1)
                    135:         continue;
                    136:       String key = line.substring(0, ind).trim();
                    137:       String value = line.substring(ind + 1).trim();
                    138:       map[key] = value;
                    139:     }
                    140:   }
1.1       damieng   141: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>