Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REQUEST] Remove indicator icon from status when there are no containers #30

Open
eyalch opened this issue Aug 25, 2018 · 1 comment
Open

Comments

@eyalch
Copy link

eyalch commented Aug 25, 2018

Since there's no functionality when there are no containers, could we please have an option to remove the icon from the status bar when in such condition?

@webmastak
Copy link

webmastak commented Feb 5, 2019

In the src/dockerMenu.js file, in fact, partially. If we delete the last container and click on the extension icon, the icon is hidden. When launching a new container, then you need Alt + F2 to restart the shell so that the icon appears again.

'use strict';

const St = imports.gi.St;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const DockerSubMenuMenuItem = Me.imports.src.dockerSubMenuMenuItem;
const DockerMenuStatusItem = Me.imports.src.dockerMenuStatusItem;

// Docker icon on status menu
const DockerMenu = new Lang.Class({
    Name: 'DockerMenu.DockerMenu',
    Extends: PanelMenu.Button,

    // Init the docker menu
    _init: function() {
        this.parent(0.0, _("Docker containers"));
        let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' }); 
        let gicon = Gio.icon_new_for_string(Me.path + "/docker.svg");
        let dockerIcon = new St.Icon({ gicon: gicon, icon_size: '24'});
        hbox.add_child(dockerIcon);
        hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
        this.actor.add_child(hbox);
        this.actor.connect('button_press_event', Lang.bind(this, this._refreshMenu));
        this._renderMenu(); 
        this._indicatorHide();            
    },

    // Refresh  the menu everytime the user click on it
    // It allows to have up-to-date information on docker containers
    _refreshMenu: function() {
        if(this.menu.isOpen) {
            this.menu.removeAll();
            this._renderMenu();
            this._indicatorHide();
        }
    },

    // Checks if docker is installed on the host machine
    _isDockerInstalled: function() {
        return GLib.find_program_in_path('docker') != undefined;
    },

    // Checks if the docker daemon is running or not
    _isDockerRunning: function() {
        let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ps', 'cax'], null, 0, null);

        let out_reader = new Gio.DataInputStream({
          base_stream: new Gio.UnixInputStream({fd: out_fd})
        });

        // Look for the docker process running
        let dockerRunning = false;
        let hasLine = true;
        do {
            let [out, size] = out_reader.read_line(null);
            if(out != null && out.toString().indexOf("docker") > -1) {
                dockerRunning = true;
            } else if(size <= 0) {
                hasLine = false;
            }

        } while(!dockerRunning && hasLine);

        return dockerRunning;
    },

    // Show docker menu icon only if installed and append docker containers
    _renderMenu: function() {
        if(this._isDockerInstalled()) {
          if(this._isDockerRunning()) {
              this._feedMenu();
          } else {
              let errMsg = _("Докер не запущен");
              this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
              log(errMsg);
          }

          // Add Turn On / Turn Off Switch always
          let statusSwitch = new DockerMenuStatusItem.DockerMenuStatusItem('Статус докера');
          this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
          this.menu.addMenuItem(statusSwitch);
        } else {
          let errMsg = _("Двоичный файл докера не найден в PATH");
          this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
          log(errMsg);
        }
        this.actor.show();
    },

    // Append containers to menu
    _feedMenu: function() {

        let delimiter = ',';
        let [res, out, err, status] = GLib.spawn_command_line_sync("docker ps -a --format '{{.Names}}" + delimiter + "{{.Status}}'");

        if(status == 0) {
            let outStr = String.fromCharCode.apply(String, out);
            let dockerContainers = outStr.split('\n');
            let numberContainers = dockerContainers.length-1;

            if (numberContainers) {
              // foreach container, add an entry in the menu
              for(let i = 0; i < numberContainers; i++) {
                  let [containerName, containerStatusMessage] = dockerContainers[i].split(delimiter);
                  let subMenu = new DockerSubMenuMenuItem.DockerSubMenuMenuItem(containerName, containerStatusMessage);
                  this.menu.addMenuItem(subMenu);
              }
            } 

        } else {
            let errMsg = "Ошибка при получении контейнеров";
            this.menu.addMenuItem(new PopupMenu.PopupMenuItem(errMsg));
            log(errMsg);
            log(err);
        }
    },
    
    // Docker hide indicator if there are no containers
   _indicatorHide() {
       let delimiter = ',';
       let [res, out, err, status] = GLib.spawn_command_line_sync("docker ps -a --format '{{.Names}}" + delimiter + "{{.Status}}'");
       if(status == 0) {
           let outStr = String.fromCharCode.apply(String, out);
           let dockerContainers = outStr.split('\n');
           let numberContainers = dockerContainers.length-1;
           if (numberContainers) {
           this.actor.visible = true; 
       } else {
           this.actor.visible = false;
       }
    } 
  }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants