budde377/Part

View on GitHub
dart/part/lib/src/elements_dialog.dart

Summary

Maintainability
Test Coverage
part of elements;

class DialogBox {
  final Element element;

  StreamController<DialogBox> _controller = new StreamController<DialogBox>();

  Stream<DialogBox> _stream;

  DialogBox(this.element);

  close() {
    element.remove();
    _controller.add(this);
  }

  Stream<DialogBox> get onClose => _stream == null ? _stream = _controller.stream.asBroadcastStream() : _stream;

  void open() {
  }

}

class AlertDialogBox extends DialogBox {
  DivElement _alertText = new DivElement();

  ButtonElement _okButton = new ButtonElement();

  AlertDialogBox(String alertText) : super(new DivElement()) {
    element.classes..add('dialog')..add('alert');
    _okButton..onClick.listen((_) {
      close();
    })..text = "OK";
    _alertText.innerHtml = alertText;
    element..append(_alertText)..append(_okButton);

  }

}


class ConfirmDialogBox extends DialogBox {
  DivElement _confirmText = new DivElement();

  ButtonElement _confirmButton = new ButtonElement(), _cancelButton = new ButtonElement();

  Completer<bool> _completer = new Completer<bool>();

  ConfirmDialogBox(String confirmText) : super(new DivElement()) {
    element.classes..add('dialog')..add('confirm');
    _confirmButton..onClick.listen((_) => _completer.complete(true))..text = "Ja";
    _cancelButton..onClick.listen((_) => _completer.complete(false))..text = "Nej";
    _confirmText.innerHtml = confirmText;
    element..append(_confirmText)..append(_confirmButton)..append(_cancelButton);
    result.then((_) => close());
  }


  Future<bool> get result => _completer.future;

}

class TextInputDialogBox extends DialogBox {
  DivElement _text = new DivElement();

  ButtonElement _doneButton = new ButtonElement();

  InputElement _textInput = new InputElement();

  Completer<String> _completer = new Completer<String>();

  TextInputDialogBox(String message, {String value:"", bool password:false}) : super(new DivElement()) {
    element.classes..add('dialog')..add('text');
    _textInput..type = (password?"password":"text")..value = value;
    _doneButton..onClick.listen((_) {
      _completer.complete(_textInput.value);
      close();
    })..text = "Udfør";
    _text.innerHtml = message;
    element..append(_text)..append(_textInput)..append(_doneButton);
    _textInput.onKeyDown.listen((KeyboardEvent kev) {
      if (kev.keyCode != 13) {
        return;
      }
      _doneButton.focus();

    });
  }

  void open() {
    new Timer(Duration.ZERO, () {
      _textInput.focus();
    });
  }

  Future<String> get result => _completer.future;

}

class LoadingDialog extends DialogBox{

  LoadingDialog(String loadingText) :super(new DivElement()){
    element.classes..add('dialog')..add('loading');
    element.innerHtml = loadingText;
  }

  void open(){
    core.escQueue.enabled = false;
  }

  void close(){
    core.escQueue.enabled = true;
    super.close();

  }

  void stopLoading(){
    element.classes.remove("loading");
  }

  void startLoading(){
    element.classes.add("loading");
  }



}


class DialogContainer {
  static final _cache = new DialogContainer._internal();

  List<DialogBox> _pendingDialogs = new List<DialogBox>();

  DivElement dialogBg = new DivElement(), _container = new DivElement(), _cell = new DivElement();

  DialogBox _currentDialog;

  factory DialogContainer() => _cache;

  DialogContainer._internal(){
    _cell.classes.add('cell');
    dialogBg.classes..add('full_background')..add('dialog_bg');
    dialogBg.append(_container);
    _container.append(_cell);
    _container.classes.add('container');


  }

  DialogBox dialog(Element element){
    var dialog = new DialogBox(element);
    addDialogBox(dialog);
    return dialog;
  }

  ConfirmDialogBox confirm(String text) {
    var dialog = new ConfirmDialogBox(text);
    addDialogBox(dialog);
    return dialog;
  }

  AlertDialogBox alert(String text) {
    var dialog = new AlertDialogBox(text);
    addDialogBox(dialog);
    return dialog;
  }


  TextInputDialogBox text(String message, {String value:""}) {
    var dialog = new TextInputDialogBox(message, value:value);
    addDialogBox(dialog);
    return dialog;
  }

  TextInputDialogBox password(String message, {String value:""}) {
    var dialog = new TextInputDialogBox(message, value:value, password:true);
    addDialogBox(dialog);
    return dialog;
  }

  LoadingDialog loading(String text){
    var dialog = new LoadingDialog(text);
    addDialogBox(dialog);
    return dialog;
  }

  void addDialogBox(DialogBox dialog) {
    dialog.onClose.listen(_closeListener);
    if (dialogBg.parent != null) {
      _pendingDialogs.add(dialog);
      return;
    }
    _appendDialog(dialog);
    querySelector('body').append(dialogBg);
    enableNoScrollBody();

  }

  void _appendDialog(DialogBox dialog) {
    _cell.append(dialog.element);
    dialog.open();
    _currentDialog = dialog;
    core.escQueue.add(() {
      if (dialog != _currentDialog) {
        return false;
      }
      dialog.close();
      return true;
    });

  }

  void _closeListener(DialogBox dialog) {
    if (_pendingDialogs.length > 0) {
      _appendDialog(_pendingDialogs.removeAt(0));
    } else {
      _currentDialog = null;
      dialogBg.remove();
      disableNoScrollBody();

    }

  }


}

DialogContainer get dialogContainer => new DialogContainer();


void enableNoScrollBody(){
  var body = querySelector('body');
  if(window.innerHeight >= body.scrollHeight){
    return;
  }
  body.style.top = "${-window.scrollY}px";
  body.classes.add('no_scroll');
}


void disableNoScrollBody(){
  var body = querySelector('body');
  body.classes.remove('no_scroll');
  var y = core.parseNumber(body.style.top);
  body.style.removeProperty('top');
  window.scrollTo(window.scrollX,y);


}