File:  [LON-CAPA] / modules / damieng / graphical_editor / loncapa_daxe / web / lcd_strings.dart
Revision 1.4: download - view: text, annotated - select for diffs
Mon Mar 25 17:29:22 2024 UTC (2 months, 1 week ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- In Daxe Editor use current language for user determined by LON-CAPA,
  if available, otherwise default to en.

/*
  This file is part of LONCAPA-Daxe.

  LONCAPA-Daxe is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  LONCAPA-Daxe is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Daxe.  If not, see <http://www.gnu.org/licenses/>.
*/

// $Id: lcd_strings.dart,v 1.4 2024/03/25 17:29:22 raeburn Exp $

/// Provides localized strings.
library LCDStrings;

import 'dart:async';
import 'dart:collection';
import 'dart:html' as h;
import 'package:intl/intl_browser.dart'; // or intl-standalone (see findSystemLocale)


/**
 * Provides localized strings read from properties files.
 * The current language file is read at application loading time.
 */
class LCDStrings {
  
  static String resourcePath = "LocalStrings";
  static HashMap<String, String> map = null;
  static String systemLocale;
  static const defaultLocale = 'en';
  
  static Future<bool> load() {
    Completer<bool> completer = new Completer<bool>();
    getLCLanguage().then((String ul) {
      if (ul != null)
        systemLocale = ul;
      else
        systemLocale = defaultLocale;
      String language = systemLocale.split('_')[0];
      String fullFilePath = "${resourcePath}_$language.properties";
      _request(fullFilePath, completer);
    });
    return(completer.future);
  }

/*
 * Customization to use a user's language preference in LON-CAPA if available,
 * otherwise default to en.
 *
 * Post a message from the iframe to the parent with userlclang as data passed
 * Listen for message posted back from parent with userlclang:locale
 * where locale is one of LON-CAPA's supported languages:
 * en de ar fa fr he ja ko pt ru tr zh.  systemLocale will be set to this in
 * load().  If no message is received within 500 ms, then completer completes
 * and returns null, and load() will set systemLocale to default (en). 
 *
 * A similar function is needed in strings.dart in daxe/lib/src because the UI
 * contains strings from LocalStrings_<lang>.properties in daxe/lib/src
 * and also from LocalStrings_<lang>.properties in loncapa_daxe/web
 */
  
  static Future<String> getLCLanguage() {
    Completer<String> completer = new Completer<String>();
    String ul = null;
    Duration delay = new Duration(milliseconds:500);
    Timer lctimer = new Timer(delay,() {
      if (!completer.isCompleted)
        completer.complete(ul);
    });
    if (!completer.isCompleted) {
      String msgtarget = h.window.location.protocol+'//'+h.window.location.hostname;
      h.window.parent.postMessage('userlclang',msgtarget);
      h.window.onMessage.listen((event) {
        if (event.origin == msgtarget) {
          List<String> msgdata = event.data.split(':');
          if (msgdata[0] == 'userlclang') {
            final RegExp usablelang = new RegExp("^(en|de|ar|fa|fr|he|ja|ko|pt|ru|tr|zh)\$");
            if (usablelang.hasMatch(msgdata[1]))
              ul = msgdata[1];
            lctimer.cancel();
            if (!completer.isCompleted)
              completer.complete(ul);
          }
        }
      });
    }
    return(completer.future);
  }
  
  static String get(String key) {
    return(map[key]);
  }
  
  static void _request(String fullFilePath, Completer<bool> completer) {
    h.HttpRequest request = new h.HttpRequest();
    request.open("GET", fullFilePath);
    request.onLoad.listen((h.ProgressEvent event) {
      if (request.status == 404) {
        // no localization for this language, use default instead
        String defaultLanguage = defaultLocale.split('_')[0];
        String defaultFullFilePath = "${resourcePath}_$defaultLanguage.properties";
        if (fullFilePath == defaultFullFilePath)
          completer.completeError("Error when reading the strings in $resourcePath");
        else
          _request(defaultFullFilePath, completer);
      } else if (request.status != 200) {
        completer.completeError("Error when reading the strings in $resourcePath");
      } else {
        _parseResponse(request.responseText);
        completer.complete(true);
      }
    });
    request.onError.listen((h.ProgressEvent event) {
      completer.completeError("Error when reading the strings in $resourcePath");
    });
    request.send();
  }
  
  static void _parseResponse(String txt) {
    map = new HashMap<String, String>();
    List<String> lines = txt.split("\n");
    for (String line in lines) {
      if (line.startsWith('#'))
        continue;
      int ind = line.indexOf('=');
      if (ind == -1)
        continue;
      String key = line.substring(0, ind).trim();
      String value = line.substring(ind + 1).trim();
      map[key] = value;
    }
  }
}

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