<commit_before>'use strict';

const electron = require('electron');
const app = electron.app;  // Module to control application life.
const BrowserWindow = electron.BrowserWindow;  // Module to create native browser window.
const Menu = electron.Menu;
const Tray = electron.Tray;
const ipcMain = require('electron').ipcMain;
const fs = require('fs');
const path = require('path');

var windowOpts;

let appIcon = null;
let checkTimer = null;
let isActive = false;
let idler = require('node-system-idle-time');
let parseArgs = require('minimist');
let saverWindows = [];
let argv = parseArgs(process.argv);
let releaseChecker = require('./lib/release_check.js');
let power = require('./lib/power.js');

let debugMode = ( argv.debug === true );

var appReady = false;
var configLoaded = false;

var grabber;

// track total displays so that when the screensaver is
// running everywhere we can handle some background work
var totalDisplays = 0;

var wakeupTimer;

var paused = false;
var lastIdle = 0;

// load a few global variables
require('./bootstrap.js');

// store our root path as a global variable so we can access it from screens
global.basePath = app.getPath('appData') + "/" + global.APP_NAME;
global.savers = require('./lib/savers.js');

/**
 * Open the preferences window
 */
var openPrefsWindow = function() {
  var electronScreen = electron.screen;
  var primary = electronScreen.getPrimaryDisplay();
  var displays = [
    primary
  ];

  ipcMain.once("screenshot-" + primary.id, function(e, message) {
    grabber.reload();

    // call savers.reload to make sure our data is properly refreshed
    // and check for any system updates
    global.savers.reload(function() {
      var prefsUrl = 'file://' + __dirname + '/ui/prefs.html';
      var w = new BrowserWindow({
        width:800,
        height:675,
        resizable:false,
        icon: path.join(__dirname, 'assets', 'icon.png')
      });

      prefsUrl = prefsUrl + "?screenshot=" + encodeURIComponent("file://" + message.url);

      w.loadURL(prefsUrl);

      if ( typeof(app.dock) !== "undefined" ) {
        app.dock.show();
      }

      if ( debugMode === true ) {
        w.webContents.openDevTools();
      }

      w.on('closed', function() {
        w = null;
        global.savers.reload();
        if ( typeof(app.dock) !== "undefined" ) {
          app.dock.hide();
        }
      });
    });
  });

  grabber.webContents.send('screengrab-request', displays);
};

/**
 * Open the (very simple) About window for the app
 */
var openAboutWindow = function() {
  var prefsUrl = 'file://' + __dirname + '/ui/about.html';
  var w = new BrowserWindow({
    width:450,
    height:300,
    resizable:false,
    icon: path.join(__dirname, 'assets', 'icon.png')
  });

  w.loadURL(prefsUrl);
  if ( typeof(app.dock) !== "undefined" ) {
    app.dock.show();
  }

  if ( debugMode === true ) {
    w.webContents.openDevTools();
  }
  w.on('closed', function() {
    w = null;
    if ( typeof(app.dock) !== "undefined" ) {
      app.dock.hide();
    }
  });
};

/**
 * open our screen grabber tool. this should run in the background,
 * waiting to take screenshots.
 */
var openScreenGrabber = function() {
  var grabberUrl = 'file://' + __dirname + '/ui/grabber.html';
  grabber = new BrowserWindow({
    show: debugMode === true,
    width:800,
    height:600
  });

  grabber.loadURL(grabberUrl);

  if ( debugMode === true ) {
    grabber.webContents.openDevTools();
  }
  grabber.on('closed', function() {
    grabber = null;
  });
};

var updateActiveState = function() {
  if ( saverWindows.length <= 0 ) {
    isActive = false;
  }
};

/**
 * run the specified screensaver on the specified screen
 */
var runScreenSaverOnDisplay = function(saver, s) {
  var globalJSCode = fs.readFileSync( path.join(__dirname, 'assets', 'global-js-handlers.js'), 'ascii');

  var size = s.bounds;
  var url_opts = {
    width: size.width,
    height: size.height,
    platform: process.platform
  };

  var windowOpts = {
    fullscreen: ( debugMode !== true ),
    preload: path.join(__dirname, 'assets', 'global.js'),
    'auto-hide-menu-bar': true,
    x: s.bounds.x,
    y: s.bounds.y
  };

  // listen for an event that we have an image of the display we will run on before completing setup
  ipcMain.once("screenshot-" + s.id, function(e, message) {
    var w = new BrowserWindow(windowOpts);

    saverWindows.push(w);

    if ( debugMode === true ) {
      w.webContents.openDevTools();
    }

    // Emitted when the window is closed.
    w.on('closed', function() {
      var index = saverWindows.indexOf(w);
      saverWindows.splice(index, 1);
      w = null;
      updateActiveState();
    });

    url_opts.screenshot = encodeURIComponent("file://" + message.url);

    var url = saver.getUrl(url_opts);
    console.log("loading " + url);

    // and load the index.html of the app.
    w.loadURL(url);

    // windows is having some issues with putting the window behind existing
    // stuff -- @see https://github.com/atom/electron/issues/2867
    if ( process.platform == "win32" ) {
      w.minimize();
    }
    w.focus();

    // inject our custom JS and CSS here
    w.webContents.executeJavaScript(globalJSCode);

    // reload the screengrabber window to keep it from churning
    // CPU, until I can figure out why that is even happening
    if ( saverWindows.length >= totalDisplays ) {
      console.log("Reloading screengrabber");
      grabber.reload();
    }

  });
};

var getDisplays = function() {
  var electronScreen = electron.screen;
  var displays = [];
  if ( debugMode === true ) {
    displays = [
      electronScreen.getPrimaryDisplay()
    ];
  }
  else {
    displays = electronScreen.getAllDisplays();
  }

  return displays;
};

/**
 * run the user's chosen screensaver on any available screens
 */
var runScreenSaver = function() {
  var displays = getDisplays();
  var saver = global.savers.getCurrentData();

  // @todo maybe add an option to only run on a single display?

  // limit to a single screen when debugging
  if ( debugMode === true ) {
    if ( typeof(app.dock) !== "undefined" ) {
      app.dock.show();
    }
  }

  totalDisplays = displays.length;

  try {
    for ( var i in displays ) {
      runScreenSaverOnDisplay(saver, displays[i]);
    } // for

    console.log("send event screengrab-request");
    grabber.webContents.send('screengrab-request', displays);
  }
  catch (e) {
    console.log(e);
  }

  isActive = true;
  wakeupTimer = setInterval(checkForWakeup, 100);
};

/**
 * should we lock the user's screen when returning from running the saver?
 */
var shouldLockScreen = function() {
  return ( savers.getLock() === true );
};

/**
 * lock the screen when the saver deactivates. currently this only works on OSX and Windows
 */
var doLockScreen = function() {
  var exec = require('child_process').exec;
  var cmd;

  if ( process.platform === 'darwin' ) {
    cmd = "'/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession' -suspend";
  }
  else if ( process.platform === 'win32' ) {
    // @see http://superuser.com/questions/21179/command-line-cmd-command-to-lock-a-windows-machine
    cmd = "rundll32.exe user32.dll,LockWorkStation";
  }
  else {
    return;
  }

  exec(cmd, function(error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
  });
};

/**
 * stop the running screensaver
 */
var stopScreenSaver = function() {
  console.log("received stopScreenSaver call");

  clearInterval(wakeupTimer);
  lastIdle = 0;

  if ( saverWindows.length <= 0 || debugMode === true ) {
    return;
  }

  // trigger lock screen before actually closing anything
  if ( shouldLockScreen() ) {
    doLockScreen();
  }

  for ( var s in saverWindows ) {
    saverWindows[s].close();
  }
};

var checkForWakeup = function() {
  var idle;

  if ( paused === true || isActive !== true ) {
    return;
  }

  idle = idler.getIdleTime();
  if ( idle < lastIdle ) {
    console.log("wake up!");
    stopScreenSaver();
  }
};

var checkIdle = function() {
  var idle, waitTime;

  // check if we're already running, or paused
  if ( paused === true || isActive === true ) {
    return;
  }

  // check that we are actually supposed to be running
  waitTime = savers.getDelay() * 60000;
  if ( waitTime <= 0 ) {
    return;
  }

  // are we past our idle time
  idle = idler.getIdleTime();
  if ( idle > waitTime ) {
    // check if we are on battery, and if we should be running in that case
    if ( savers.getDisableOnBattery() ) {
      power.charging().then((is_powered) => {
        if ( is_powered ) {
          runScreenSaver();
        }
      });
    }
    else {
      runScreenSaver();
    }
  }

  lastIdle = idle;
};

var trayMenu = Menu.buildFromTemplate([
  {
    label: 'Run Now',
    click: function() { runScreenSaver(); }
  },
  {
    label: 'Disable',
    click: function() {
      paused = true;
      trayMenu.items[1].visible = false;
      trayMenu.items[2].visible = true;
    }
  },
  {
    label: 'Enable',
    click: function() {
      paused = false;
      trayMenu.items[1].visible = true;
      trayMenu.items[2].visible = false;
    },
    visible: false
  },
  {
    label: 'Update Available!',
    click: function() {
      require('electron').shell.openExternal('https://github.com/' + global.APP_REPO + '/releases/latest');
    },
    visible: (global.NEW_RELEASE_AVAILABLE === true)
  },
  {
    label: 'Preferences',
    click: function() { openPrefsWindow(); }
  },
  {
    label: 'About ' + global.APP_NAME,
    click: function() { openAboutWindow(); }
  },
  {
    label: 'Quit',
    click: function() { app.quit(); }
  }
]);

/**
 * make sure we're only running a single instance
 */
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
  return true;
});

if (shouldQuit) {
  app.quit();
}

// don't show app in dock
if ( typeof(app.dock) !== "undefined" ) {
  app.dock.hide();
}

// seems like we need to catch this event to keep OSX from exiting app after screensaver runs?
app.on('window-all-closed', function() {
  console.log("window-all-closed");
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.once('ready', function() {
  appIcon = new Tray(__dirname + '/assets/icon.png');
  appIcon.setToolTip(global.APP_NAME);
  appIcon.setContextMenu(trayMenu);

  //var menuTemplate = [];
  var menuTemplate = require("./ui/menu_template.js").buildMenuTemplate(app);
  var menu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(menu);

  openScreenGrabber();

  checkTimer = setInterval(checkIdle, 2500);

  if ( argv.screen === "prefs" ) {
    openPrefsWindow();
  }
  else if ( argv.screen === "about" ) {
    openAboutWindow();
  }
  else if ( argv.screen === "saver" ) {
    runScreenSaver();
  }

  appReady = true;

  openPrefsOnFirstLoad();
});

//
// listen for a message from global.js that we should stop running the screensaver
//
ipcMain.on('asynchronous-message', function(event, arg) {
  if ( arg === "stopScreenSaver" ) {
    stopScreenSaver();
  }
});

/**
 * once the app is ready and our config is loaded, check to see if the app
 * has been loaded before. if not, let's go ahead and open the prefs window now.
 */
var openPrefsOnFirstLoad = function() {
  if ( appReady === false || configLoaded === false ) {
    return;
  }
  if ( savers.firstLoad() === true ) {
    setTimeout(openPrefsWindow, 1000);
  }
};

/**
 * handle initial startup of app
 */
var bootApp = function(_basePath) {
  if ( typeof(_basePath) !== "undefined" ) {
    global.basePath = _basePath;
  }

  trayMenu.items[3].visible = global.NEW_RELEASE_AVAILABLE;

  global.savers.init(global.basePath, function() {
    configLoaded = true;
    openPrefsOnFirstLoad();
  });
};

/**
 * check for a release and then boot!
 */
releaseChecker.checkLatestRelease(
  global.APP_REPO, global.APP_VERSION,
  function() {
    global.NEW_RELEASE_AVAILABLE = true;
    bootApp();
  },
  function() {
    bootApp();
  });

//exports.bootApp = bootApp;
//exports.openPrefsWindow = openPrefsWindow;
<commit_msg>Get window closing working again<commit_after>'use strict';

const electron = require('electron');
const app = electron.app;  // Module to control application life.
const BrowserWindow = electron.BrowserWindow;  // Module to create native browser window.
const Menu = electron.Menu;
const Tray = electron.Tray;
const ipcMain = require('electron').ipcMain;
const fs = require('fs');
const path = require('path');

var windowOpts;

let appIcon = null;
let checkTimer = null;
let isActive = false;
let idler = require('node-system-idle-time');
let parseArgs = require('minimist');
let saverWindows = [];
let argv = parseArgs(process.argv);
let releaseChecker = require('./lib/release_check.js');
let power = require('./lib/power.js');

let debugMode = ( argv.debug === true );

var appReady = false;
var configLoaded = false;

var grabber;

// track total displays so that when the screensaver is
// running everywhere we can handle some background work
var totalDisplays = 0;

var wakeupTimer;

var paused = false;
var lastIdle = 0;

// load a few global variables
require('./bootstrap.js');

// store our root path as a global variable so we can access it from screens
global.basePath = app.getPath('appData') + "/" + global.APP_NAME;
global.savers = require('./lib/savers.js');

/**
 * Open the preferences window
 */
var openPrefsWindow = function() {
  var electronScreen = electron.screen;
  var primary = electronScreen.getPrimaryDisplay();
  var displays = [
    primary
  ];

  ipcMain.once("screenshot-" + primary.id, function(e, message) {
    grabber.reload();

    // call savers.reload to make sure our data is properly refreshed
    // and check for any system updates
    global.savers.reload(function() {
      var prefsUrl = 'file://' + __dirname + '/ui/prefs.html';
      var w = new BrowserWindow({
        width:800,
        height:675,
        resizable:false,
        icon: path.join(__dirname, 'assets', 'icon.png')
      });

      prefsUrl = prefsUrl + "?screenshot=" + encodeURIComponent("file://" + message.url);

      w.loadURL(prefsUrl);

      if ( typeof(app.dock) !== "undefined" ) {
        app.dock.show();
      }

      if ( debugMode === true ) {
        w.webContents.openDevTools();
      }

      w.on('closed', function() {
        w = null;
        global.savers.reload();
        if ( typeof(app.dock) !== "undefined" ) {
          app.dock.hide();
        }
      });
    });
  });

  grabber.webContents.send('screengrab-request', displays);
};

/**
 * Open the (very simple) About window for the app
 */
var openAboutWindow = function() {
  var prefsUrl = 'file://' + __dirname + '/ui/about.html';
  var w = new BrowserWindow({
    width:450,
    height:300,
    resizable:false,
    icon: path.join(__dirname, 'assets', 'icon.png')
  });

  w.loadURL(prefsUrl);
  if ( typeof(app.dock) !== "undefined" ) {
    app.dock.show();
  }

  if ( debugMode === true ) {
    w.webContents.openDevTools();
  }
  w.on('closed', function() {
    w = null;
    if ( typeof(app.dock) !== "undefined" ) {
      app.dock.hide();
    }
  });
};

/**
 * open our screen grabber tool. this should run in the background,
 * waiting to take screenshots.
 */
var openScreenGrabber = function() {
  var grabberUrl = 'file://' + __dirname + '/ui/grabber.html';
  grabber = new BrowserWindow({
    show: debugMode === true,
    width:800,
    height:600
  });

  grabber.loadURL(grabberUrl);

  if ( debugMode === true ) {
    grabber.webContents.openDevTools();
  }
  grabber.on('closed', function() {
    grabber = null;
  });
};

var updateActiveState = function() {
  var openWindows = saverWindows.filter(function(w) {
    return (typeof(w) !== "undefined" && w.isClosed !== true);
  });

  if ( openWindows.length == 0 ) {
    saverWindows = [];
    isActive = false;
  }
};

/**
 * run the specified screensaver on the specified screen
 */
var runScreenSaverOnDisplay = function(saver, s) {
  var globalJSCode = fs.readFileSync( path.join(__dirname, 'assets', 'global-js-handlers.js'), 'ascii');

  var size = s.bounds;
  var url_opts = {
    width: size.width,
    height: size.height,
    platform: process.platform
  };

  var windowOpts = {
    fullscreen: ( debugMode !== true ),
    preload: path.join(__dirname, 'assets', 'global.js'),
    'auto-hide-menu-bar': true,
    x: s.bounds.x,
    y: s.bounds.y
  };

  // listen for an event that we have an image of the display we will run on before completing setup
  ipcMain.once("screenshot-" + s.id, function(e, message) {
    var w = new BrowserWindow(windowOpts);

    saverWindows.push(w);

    if ( debugMode === true ) {
      w.webContents.openDevTools();
    }

    // Emitted when the window is closed.
    w.on('closed', function() {
      w.isClosed = true;
      updateActiveState();
    });

    url_opts.screenshot = encodeURIComponent("file://" + message.url);

    var url = saver.getUrl(url_opts);
    console.log("loading " + url);

    // and load the index.html of the app.
    w.loadURL(url);

    // windows is having some issues with putting the window behind existing
    // stuff -- @see https://github.com/atom/electron/issues/2867
    if ( process.platform == "win32" ) {
      w.minimize();
    }
    w.focus();

    // inject our custom JS and CSS here
    w.webContents.executeJavaScript(globalJSCode);

    // reload the screengrabber window to keep it from churning
    // CPU, until I can figure out why that is even happening
    if ( saverWindows.length >= totalDisplays ) {
      console.log("Reloading screengrabber");
      grabber.reload();
    }

  });
};

var getDisplays = function() {
  var electronScreen = electron.screen;
  var displays = [];
  if ( debugMode === true ) {
    displays = [
      electronScreen.getPrimaryDisplay()
    ];
  }
  else {
    displays = electronScreen.getAllDisplays();
  }

  return displays;
};

/**
 * run the user's chosen screensaver on any available screens
 */
var runScreenSaver = function() {
  var displays = getDisplays();
  var saver = global.savers.getCurrentData();

  // @todo maybe add an option to only run on a single display?

  // limit to a single screen when debugging
  if ( debugMode === true ) {
    if ( typeof(app.dock) !== "undefined" ) {
      app.dock.show();
    }
  }

  totalDisplays = displays.length;

  try {
    for ( var i in displays ) {
      runScreenSaverOnDisplay(saver, displays[i]);
    } // for

    console.log("send event screengrab-request");
    grabber.webContents.send('screengrab-request', displays);
  }
  catch (e) {
    console.log(e);
  }

  // set the idle timer to something > 0
  if ( lastIdle < 99 ) {
    lastIdle = 99;
  }

  isActive = true;
  wakeupTimer = setInterval(checkForWakeup, 100);
};

/**
 * should we lock the user's screen when returning from running the saver?
 */
var shouldLockScreen = function() {
  return ( savers.getLock() === true );
};

/**
 * lock the screen when the saver deactivates. currently this only works on OSX and Windows
 */
var doLockScreen = function() {
  var exec = require('child_process').exec;
  var cmd;

  if ( process.platform === 'darwin' ) {
    cmd = "'/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession' -suspend";
  }
  else if ( process.platform === 'win32' ) {
    // @see http://superuser.com/questions/21179/command-line-cmd-command-to-lock-a-windows-machine
    cmd = "rundll32.exe user32.dll,LockWorkStation";
  }
  else {
    return;
  }

  exec(cmd, function(error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
  });
};

/**
 * stop the running screensaver
 */
var stopScreenSaver = function() {
  console.log("received stopScreenSaver call");

  clearInterval(wakeupTimer);
  lastIdle = 0;

  if ( saverWindows.length <= 0 || debugMode === true ) {
    return;
  }

  // trigger lock screen before actually closing anything
  if ( shouldLockScreen() ) {
    doLockScreen();
  }

  console.log("closing " + saverWindows.length + " windows");
  for ( var s in saverWindows ) {
    console.log("close", s);
    saverWindows[s].close();
  }
};

var checkForWakeup = function() {
  var idle;

  if ( paused === true || isActive !== true ) {
    return;
  }

  idle = idler.getIdleTime();
  if ( idle < lastIdle ) {
    stopScreenSaver();
  }
};

var checkIdle = function() {
  var idle, waitTime;

  // check if we're already running, or paused
  if ( paused === true || isActive === true ) {
    return;
  }

  // check that we are actually supposed to be running
  waitTime = savers.getDelay() * 60000;
  if ( waitTime <= 0 ) {
    return;
  }

  // are we past our idle time
  idle = idler.getIdleTime();
  if ( idle > waitTime ) {
    // check if we are on battery, and if we should be running in that case
    if ( savers.getDisableOnBattery() ) {
      power.charging().then((is_powered) => {
        if ( is_powered ) {
          runScreenSaver();
        }
      });
    }
    else {
      runScreenSaver();
    }
  }

  lastIdle = idle;
};

var trayMenu = Menu.buildFromTemplate([
  {
    label: 'Run Now',
    click: function() { runScreenSaver(); }
  },
  {
    label: 'Disable',
    click: function() {
      paused = true;
      trayMenu.items[1].visible = false;
      trayMenu.items[2].visible = true;
    }
  },
  {
    label: 'Enable',
    click: function() {
      paused = false;
      trayMenu.items[1].visible = true;
      trayMenu.items[2].visible = false;
    },
    visible: false
  },
  {
    label: 'Update Available!',
    click: function() {
      require('electron').shell.openExternal('https://github.com/' + global.APP_REPO + '/releases/latest');
    },
    visible: (global.NEW_RELEASE_AVAILABLE === true)
  },
  {
    label: 'Preferences',
    click: function() { openPrefsWindow(); }
  },
  {
    label: 'About ' + global.APP_NAME,
    click: function() { openAboutWindow(); }
  },
  {
    label: 'Quit',
    click: function() { app.quit(); }
  }
]);

/**
 * make sure we're only running a single instance
 */
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) {
  return true;
});

if (shouldQuit) {
  app.quit();
}

// don't show app in dock
if ( typeof(app.dock) !== "undefined" ) {
  app.dock.hide();
}

// seems like we need to catch this event to keep OSX from exiting app after screensaver runs?
app.on('window-all-closed', function() {
  console.log("window-all-closed");
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.once('ready', function() {
  appIcon = new Tray(__dirname + '/assets/icon.png');
  appIcon.setToolTip(global.APP_NAME);
  appIcon.setContextMenu(trayMenu);

  //var menuTemplate = [];
  var menuTemplate = require("./ui/menu_template.js").buildMenuTemplate(app);
  var menu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(menu);

  openScreenGrabber();

  checkTimer = setInterval(checkIdle, 2500);

  if ( argv.screen === "prefs" ) {
    openPrefsWindow();
  }
  else if ( argv.screen === "about" ) {
    openAboutWindow();
  }
  else if ( argv.screen === "saver" ) {
    runScreenSaver();
  }

  appReady = true;

  openPrefsOnFirstLoad();
});

//
// listen for a message from global.js that we should stop running the screensaver
//
ipcMain.on('asynchronous-message', function(event, arg) {
  if ( arg === "stopScreenSaver" ) {
    stopScreenSaver();
  }
});

/**
 * once the app is ready and our config is loaded, check to see if the app
 * has been loaded before. if not, let's go ahead and open the prefs window now.
 */
var openPrefsOnFirstLoad = function() {
  if ( appReady === false || configLoaded === false ) {
    return;
  }
  if ( savers.firstLoad() === true ) {
    setTimeout(openPrefsWindow, 1000);
  }
};

/**
 * handle initial startup of app
 */
var bootApp = function(_basePath) {
  if ( typeof(_basePath) !== "undefined" ) {
    global.basePath = _basePath;
  }

  trayMenu.items[3].visible = global.NEW_RELEASE_AVAILABLE;

  global.savers.init(global.basePath, function() {
    configLoaded = true;
    openPrefsOnFirstLoad();
  });
};

/**
 * check for a release and then boot!
 */
releaseChecker.checkLatestRelease(
  global.APP_REPO, global.APP_VERSION,
  function() {
    global.NEW_RELEASE_AVAILABLE = true;
    bootApp();
  },
  function() {
    bootApp();
  });
<|endoftext|>


<commit_before>import Controller from '@ember/controller';
import {action} from '@ember/object';
import {getSymbol} from 'ghost-admin/utils/currency';
import {inject as service} from '@ember/service';
import {tracked} from '@glimmer/tracking';

export default class DashboardController extends Controller {
    @service feature;
    @service session;
    @service membersStats;
    @service store;
    @service settings;
    @service whatsNew;

    @tracked
    eventsData = null;
    @tracked
    eventsError = null;
    @tracked
    eventsLoading = false;

    @tracked
    mrrStatsData = null;
    @tracked
    mrrStatsError = null;
    @tracked
    mrrStatsLoading = false;

    @tracked
    memberCountStatsData = null;
    @tracked
    memberCountStatsError = null;
    @tracked
    memberCountStatsLoading = false;

    @tracked
    topMembersData = null;
    @tracked
    topMembersError = null;
    @tracked
    topMembersLoading = false;

    @tracked
    newsletterOpenRatesData = null;
    @tracked
    newsletterOpenRatesError = null;
    @tracked
    newsletterOpenRatesLoading = false;

    @tracked
    whatsNewEntries = null;
    @tracked
    whatsNewEntriesLoading = null;
    @tracked
    whatsNewEntriesError = null;

    get topMembersDataHasOpenRates() {
        return this.topMembersData && this.topMembersData.find((member) => {
            return member.emailOpenRate !== null;
        });
    }

    initialise() {
        this.loadEvents();
        this.loadTopMembers();
        this.loadCharts();
        this.loadWhatsNew();
    }

    loadMRRStats() {
        this.mrrStatsLoading = true;
        this.membersStats.fetchMRR().then((stats) => {
            this.mrrStatsLoading = false;
            const statsData = stats.data;
            let currencyStats = statsData[0] || {
                data: [],
                currency: 'usd'
            };
            if (currencyStats) {
                const currencyStatsData = this.membersStats.fillDates(currencyStats.data) || {};
                const dateValues = Object.values(currencyStatsData).map(val => val / 100);
                const currentMRR = dateValues.length ? dateValues[dateValues.length - 1] : 0;
                const rangeStartMRR = dateValues.length ? dateValues[0] : 0;
                const percentGrowth = rangeStartMRR !== 0 ? ((currentMRR - rangeStartMRR) / rangeStartMRR) * 100 : 0;
                this.mrrStatsData = {
                    current: `${getSymbol(currencyStats.currency)}${currentMRR}`,
                    percentGrowth: percentGrowth.toFixed(1),
                    percentClass: (percentGrowth > 0 ? 'positive' : (percentGrowth < 0 ? 'negative' : '')),
                    options: {
                        rangeInDays: 30
                    },
                    data: {
                        label: 'MRR',
                        dateLabels: Object.keys(currencyStatsData),
                        dateValues
                    },
                    title: 'MRR',
                    stats: currencyStats
                };
            }
        }, (error) => {
            this.mrrStatsError = error;
            this.mrrStatsLoading = false;
        });
    }

    loadMemberCountStats() {
        this.memberCountStatsLoading = true;
        this.membersStats.fetchCounts().then((stats) => {
            this.memberCountStatsLoading = false;

            if (stats) {
                const statsDateObj = this.membersStats.fillCountDates(stats.data) || {};
                const dateValues = Object.values(statsDateObj);
                const currentAllCount = dateValues.length ? dateValues[dateValues.length - 1].total : 0;
                const currentPaidCount = dateValues.length ? dateValues[dateValues.length - 1].paid : 0;
                const rangeStartAllCount = dateValues.length ? dateValues[0].total : 0;
                const rangeStartPaidCount = dateValues.length ? dateValues[0].paid : 0;
                const allCountPercentGrowth = rangeStartAllCount !== 0 ? ((currentAllCount - rangeStartAllCount) / rangeStartAllCount) * 100 : 0;
                const paidCountPercentGrowth = rangeStartPaidCount !== 0 ? ((currentPaidCount - rangeStartPaidCount) / rangeStartPaidCount) * 100 : 0;

                this.memberCountStatsData = {
                    all: {
                        percentGrowth: allCountPercentGrowth.toFixed(1),
                        percentClass: (allCountPercentGrowth > 0 ? 'positive' : (allCountPercentGrowth < 0 ? 'negative' : '')),
                        total: dateValues.length ? dateValues[dateValues.length - 1].total : 0,
                        options: {
                            rangeInDays: 30
                        },
                        data: {
                            label: 'Members',
                            dateLabels: Object.keys(statsDateObj),
                            dateValues: dateValues.map(d => d.total)
                        },
                        title: 'Total Members',
                        stats: stats
                    },
                    paid: {
                        percentGrowth: paidCountPercentGrowth.toFixed(1),
                        percentClass: (paidCountPercentGrowth > 0 ? 'positive' : (paidCountPercentGrowth < 0 ? 'negative' : '')),
                        total: dateValues.length ? dateValues[dateValues.length - 1].paid : 0,
                        options: {
                            rangeInDays: 30
                        },
                        data: {
                            label: 'Members',
                            dateLabels: Object.keys(statsDateObj),
                            dateValues: dateValues.map(d => d.paid)
                        },
                        title: 'Paid Members',
                        stats: stats
                    }
                };
            }
        }, (error) => {
            this.memberCountStatsError = error;
            this.memberCountStatsLoading = false;
        });
    }

    loadCharts() {
        this.loadMRRStats();
        this.loadMemberCountStats();
        this.loadNewsletterOpenRates();
    }

    loadEvents() {
        this.eventsLoading = true;
        this.membersStats.fetchTimeline({limit: 5}).then(({events}) => {
            this.eventsData = events;
            this.eventsLoading = false;
        }, (error) => {
            this.eventsError = error;
            this.eventsLoading = false;
        });
    }

    loadNewsletterOpenRates() {
        this.newsletterOpenRatesLoading = true;
        this.membersStats.fetchNewsletterStats().then((results) => {
            const rangeStartOpenRate = results.length > 1 ? results[results.length - 2].openRate : 0;
            const rangeEndOpenRate = results.length > 0 ? results[results.length - 1].openRate : 0;
            const percentGrowth = rangeStartOpenRate !== 0 ? ((rangeEndOpenRate - rangeStartOpenRate) / rangeStartOpenRate) * 100 : 0;
            this.newsletterOpenRatesData = {
                percentGrowth: percentGrowth.toFixed(1),
                current: rangeEndOpenRate,
                options: {
                    rangeInDays: 30
                },
                data: {
                    label: 'Open rate',
                    dateLabels: results.map(d => d.subject),
                    dateValues: results.map(d => d.openRate)
                },
                title: 'Open rate',
                stats: results
            };
            this.newsletterOpenRatesLoading = false;
        }, (error) => {
            this.newsletterOpenRatesError = error;
            this.newsletterOpenRatesLoading = false;
        });
    }

    loadTopMembers() {
        this.topMembersLoading = true;
        let query = {
            filter: 'email_open_rate:-null',
            order: 'email_open_rate desc',
            limit: 10
        };
        this.store.query('member', query).then((result) => {
            if (!result.length) {
                return this.store.query('member', {
                    filter: 'status:paid',
                    order: 'created_at asc',
                    limit: 10
                });
            }
            return result;
        }).then((result) => {
            this.topMembersData = result;
            this.topMembersLoading = false;
        }).catch((error) => {
            this.topMembersError = error;
            this.topMembersLoading = false;
        });
    }

    loadWhatsNew() {
        this.whatsNewEntriesLoading = true;
        this.whatsNew.fetchLatest.perform().then(() => {
            this.whatsNewEntriesLoading = false;
            this.whatsNewEntries = this.whatsNew.entries.slice(0, 3);
        }, (error) => {
            this.whatsNewEntriesError = error;
            this.whatsNewEntriesLoading = false;
        });
    }

    @action
    dismissLaunchBanner() {
        this.feature.set('launchComplete', true);
    }
}
<commit_msg>Changed top members limit to 5<commit_after>import Controller from '@ember/controller';
import {action} from '@ember/object';
import {getSymbol} from 'ghost-admin/utils/currency';
import {inject as service} from '@ember/service';
import {tracked} from '@glimmer/tracking';

export default class DashboardController extends Controller {
    @service feature;
    @service session;
    @service membersStats;
    @service store;
    @service settings;
    @service whatsNew;

    @tracked
    eventsData = null;
    @tracked
    eventsError = null;
    @tracked
    eventsLoading = false;

    @tracked
    mrrStatsData = null;
    @tracked
    mrrStatsError = null;
    @tracked
    mrrStatsLoading = false;

    @tracked
    memberCountStatsData = null;
    @tracked
    memberCountStatsError = null;
    @tracked
    memberCountStatsLoading = false;

    @tracked
    topMembersData = null;
    @tracked
    topMembersError = null;
    @tracked
    topMembersLoading = false;

    @tracked
    newsletterOpenRatesData = null;
    @tracked
    newsletterOpenRatesError = null;
    @tracked
    newsletterOpenRatesLoading = false;

    @tracked
    whatsNewEntries = null;
    @tracked
    whatsNewEntriesLoading = null;
    @tracked
    whatsNewEntriesError = null;

    get topMembersDataHasOpenRates() {
        return this.topMembersData && this.topMembersData.find((member) => {
            return member.emailOpenRate !== null;
        });
    }

    initialise() {
        this.loadEvents();
        this.loadTopMembers();
        this.loadCharts();
        this.loadWhatsNew();
    }

    loadMRRStats() {
        this.mrrStatsLoading = true;
        this.membersStats.fetchMRR().then((stats) => {
            this.mrrStatsLoading = false;
            const statsData = stats.data;
            let currencyStats = statsData[0] || {
                data: [],
                currency: 'usd'
            };
            if (currencyStats) {
                const currencyStatsData = this.membersStats.fillDates(currencyStats.data) || {};
                const dateValues = Object.values(currencyStatsData).map(val => val / 100);
                const currentMRR = dateValues.length ? dateValues[dateValues.length - 1] : 0;
                const rangeStartMRR = dateValues.length ? dateValues[0] : 0;
                const percentGrowth = rangeStartMRR !== 0 ? ((currentMRR - rangeStartMRR) / rangeStartMRR) * 100 : 0;
                this.mrrStatsData = {
                    current: `${getSymbol(currencyStats.currency)}${currentMRR}`,
                    percentGrowth: percentGrowth.toFixed(1),
                    percentClass: (percentGrowth > 0 ? 'positive' : (percentGrowth < 0 ? 'negative' : '')),
                    options: {
                        rangeInDays: 30
                    },
                    data: {
                        label: 'MRR',
                        dateLabels: Object.keys(currencyStatsData),
                        dateValues
                    },
                    title: 'MRR',
                    stats: currencyStats
                };
            }
        }, (error) => {
            this.mrrStatsError = error;
            this.mrrStatsLoading = false;
        });
    }

    loadMemberCountStats() {
        this.memberCountStatsLoading = true;
        this.membersStats.fetchCounts().then((stats) => {
            this.memberCountStatsLoading = false;

            if (stats) {
                const statsDateObj = this.membersStats.fillCountDates(stats.data) || {};
                const dateValues = Object.values(statsDateObj);
                const currentAllCount = dateValues.length ? dateValues[dateValues.length - 1].total : 0;
                const currentPaidCount = dateValues.length ? dateValues[dateValues.length - 1].paid : 0;
                const rangeStartAllCount = dateValues.length ? dateValues[0].total : 0;
                const rangeStartPaidCount = dateValues.length ? dateValues[0].paid : 0;
                const allCountPercentGrowth = rangeStartAllCount !== 0 ? ((currentAllCount - rangeStartAllCount) / rangeStartAllCount) * 100 : 0;
                const paidCountPercentGrowth = rangeStartPaidCount !== 0 ? ((currentPaidCount - rangeStartPaidCount) / rangeStartPaidCount) * 100 : 0;

                this.memberCountStatsData = {
                    all: {
                        percentGrowth: allCountPercentGrowth.toFixed(1),
                        percentClass: (allCountPercentGrowth > 0 ? 'positive' : (allCountPercentGrowth < 0 ? 'negative' : '')),
                        total: dateValues.length ? dateValues[dateValues.length - 1].total : 0,
                        options: {
                            rangeInDays: 30
                        },
                        data: {
                            label: 'Members',
                            dateLabels: Object.keys(statsDateObj),
                            dateValues: dateValues.map(d => d.total)
                        },
                        title: 'Total Members',
                        stats: stats
                    },
                    paid: {
                        percentGrowth: paidCountPercentGrowth.toFixed(1),
                        percentClass: (paidCountPercentGrowth > 0 ? 'positive' : (paidCountPercentGrowth < 0 ? 'negative' : '')),
                        total: dateValues.length ? dateValues[dateValues.length - 1].paid : 0,
                        options: {
                            rangeInDays: 30
                        },
                        data: {
                            label: 'Members',
                            dateLabels: Object.keys(statsDateObj),
                            dateValues: dateValues.map(d => d.paid)
                        },
                        title: 'Paid Members',
                        stats: stats
                    }
                };
            }
        }, (error) => {
            this.memberCountStatsError = error;
            this.memberCountStatsLoading = false;
        });
    }

    loadCharts() {
        this.loadMRRStats();
        this.loadMemberCountStats();
        this.loadNewsletterOpenRates();
    }

    loadEvents() {
        this.eventsLoading = true;
        this.membersStats.fetchTimeline({limit: 5}).then(({events}) => {
            this.eventsData = events;
            this.eventsLoading = false;
        }, (error) => {
            this.eventsError = error;
            this.eventsLoading = false;
        });
    }

    loadNewsletterOpenRates() {
        this.newsletterOpenRatesLoading = true;
        this.membersStats.fetchNewsletterStats().then((results) => {
            const rangeStartOpenRate = results.length > 1 ? results[results.length - 2].openRate : 0;
            const rangeEndOpenRate = results.length > 0 ? results[results.length - 1].openRate : 0;
            const percentGrowth = rangeStartOpenRate !== 0 ? ((rangeEndOpenRate - rangeStartOpenRate) / rangeStartOpenRate) * 100 : 0;
            this.newsletterOpenRatesData = {
                percentGrowth: percentGrowth.toFixed(1),
                current: rangeEndOpenRate,
                options: {
                    rangeInDays: 30
                },
                data: {
                    label: 'Open rate',
                    dateLabels: results.map(d => d.subject),
                    dateValues: results.map(d => d.openRate)
                },
                title: 'Open rate',
                stats: results
            };
            this.newsletterOpenRatesLoading = false;
        }, (error) => {
            this.newsletterOpenRatesError = error;
            this.newsletterOpenRatesLoading = false;
        });
    }

    loadTopMembers() {
        this.topMembersLoading = true;
        let query = {
            filter: 'email_open_rate:-null',
            order: 'email_open_rate desc',
            limit: 5
        };
        this.store.query('member', query).then((result) => {
            if (!result.length) {
                return this.store.query('member', {
                    filter: 'status:paid',
                    order: 'created_at asc',
                    limit: 5
                });
            }
            return result;
        }).then((result) => {
            this.topMembersData = result;
            this.topMembersLoading = false;
        }).catch((error) => {
            this.topMembersError = error;
            this.topMembersLoading = false;
        });
    }

    loadWhatsNew() {
        this.whatsNewEntriesLoading = true;
        this.whatsNew.fetchLatest.perform().then(() => {
            this.whatsNewEntriesLoading = false;
            this.whatsNewEntries = this.whatsNew.entries.slice(0, 3);
        }, (error) => {
            this.whatsNewEntriesError = error;
            this.whatsNewEntriesLoading = false;
        });
    }

    @action
    dismissLaunchBanner() {
        this.feature.set('launchComplete', true);
    }
}
<|endoftext|>


<commit_before>require('./vendor')();
require('./css/flex.css');
require('./css/armada.css');
require('./css/spinner-xl.css');
require('expose?FiltersNumbers!./js/filters/numbers.js');
require('expose?FiltersEveImage!./js/filters/eve-image.js');
require('./js/armada.js')();
require('./js/controllers/login.js')();
require('./js/controllers/navbar.js')();
require('./js/controllers/dashboard.js')();
require('./js/controllers/tour.js')();
require('./js/controllers/evemail.js')();
require('./js/controllers/apikeys.js')();
require('./js/controllers/character/list.js')();
require('./js/controllers/character/details.js')();
require('./js/controllers/character/skills.js')();
require('./js/controllers/character/economy/transactions.js')();
require('./js/controllers/character/economy/balance.js')();
require('./js/controllers/character/sheet.js')();
require('./js/controllers/assets/assets.js')();
require('./js/controllers/assets/summary/summary.js')();
require('./js/controllers/assets/browsing/view.js')();
require('./js/controllers/assets/browsing/toolbar.js')();
require('./js/controllers/assets/browsing/locations/list.js')();
require('./js/controllers/assets/browsing/locations/details.js')();
require('./js/controllers/assets/browsing/inventory/list.js')();
require('./js/controllers/assets/browsing/inventory/toolbar.js')();
require('./js/controllers/assets/searching/searching.js')();
require('./js/controllers/assets/searching/toolbar.js')();
require('./js/services/stationspinner.js')();
require('./js/services/settings.js')();
require('./js/services/account.js')();
require('./js/services/colorize.js')();
require('./js/services/asset-toolbar.js')();
require('./js/services/character-selector.js')();
require('./js/services/eve-icons.js')();
require('./js/directives/armada-login.js')();
require('./js/directives/armada-welcome.js')();
require('./js/directives/character-box.js')();
require('./js/directives/character-box-extended.js')();
require('./js/directives/eve-status.js')();
require('./js/directives/active-link.js')();
require('./js/directives/api-key.js')();
require('./js/directives/mail-display.js')();
require('./js/directives/eve-skill.js')();
require('./js/directives/eve-type.js')();
require('./js/directives/armada-id-selector.js')();
require('./js/directives/armada-ship-layout.js')();
require('./js/directives/armada-inventory-table.js')();
require('./js/directives/armada-inventory-icons.js')();
require('./js/directives/armada-chart-asset-distribution.js')();
require('./js/directives/armada-chart-asset-worth.js')();

<commit_msg>Remove redundant directive.<commit_after>require('./vendor')();
require('./css/flex.css');
require('./css/armada.css');
require('./css/spinner-xl.css');
require('expose?FiltersNumbers!./js/filters/numbers.js');
require('expose?FiltersEveImage!./js/filters/eve-image.js');
require('./js/armada.js')();
require('./js/controllers/login.js')();
require('./js/controllers/navbar.js')();
require('./js/controllers/dashboard.js')();
require('./js/controllers/tour.js')();
require('./js/controllers/evemail.js')();
require('./js/controllers/apikeys.js')();
require('./js/controllers/character/list.js')();
require('./js/controllers/character/details.js')();
require('./js/controllers/character/skills.js')();
require('./js/controllers/character/economy/transactions.js')();
require('./js/controllers/character/economy/balance.js')();
require('./js/controllers/character/sheet.js')();
require('./js/controllers/assets/assets.js')();
require('./js/controllers/assets/summary/summary.js')();
require('./js/controllers/assets/browsing/view.js')();
require('./js/controllers/assets/browsing/toolbar.js')();
require('./js/controllers/assets/browsing/locations/list.js')();
require('./js/controllers/assets/browsing/locations/details.js')();
require('./js/controllers/assets/browsing/inventory/list.js')();
require('./js/controllers/assets/browsing/inventory/toolbar.js')();
require('./js/controllers/assets/searching/searching.js')();
require('./js/controllers/assets/searching/toolbar.js')();
require('./js/services/stationspinner.js')();
require('./js/services/settings.js')();
require('./js/services/account.js')();
require('./js/services/colorize.js')();
require('./js/services/asset-toolbar.js')();
require('./js/services/character-selector.js')();
require('./js/services/eve-icons.js')();
require('./js/directives/armada-login.js')();
require('./js/directives/character-box.js')();
require('./js/directives/character-box-extended.js')();
require('./js/directives/eve-status.js')();
require('./js/directives/active-link.js')();
require('./js/directives/api-key.js')();
require('./js/directives/mail-display.js')();
require('./js/directives/eve-skill.js')();
require('./js/directives/eve-type.js')();
require('./js/directives/armada-id-selector.js')();
require('./js/directives/armada-ship-layout.js')();
require('./js/directives/armada-inventory-table.js')();
require('./js/directives/armada-inventory-icons.js')();
require('./js/directives/armada-chart-asset-distribution.js')();
require('./js/directives/armada-chart-asset-worth.js')();

<|endoftext|>


<commit_before>var React = require('react');
var ReactDOM = require('react-dom');

// var Break = React.createClass({
//   render: function() {
//     return (
//

//         *
//         Break
//         5:00
//         Break
//
//

//     );
//   }
// });

var TasksList = React.createClass({
  render: function() {
    var createItem = function(item) {
      return (

          {item.id}
          {item.task}
          25:00
          Pomodoro

      );
    };
    return (

              #
              Task
              Duration
              Type

            {this.props.tasksList.map(createItem)}

    );
  }
});

var Timer = React.createClass({
  getInitialState: function() {
    return {
      timeRemaining: 1500,
      tasksList: [],
      task: ''
    };
  },
  onChange: function(e) {
    this.setState({task: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    if (this.state.task === '') {
      return;
    }
    if (this.state.tasksList[0]) {
      this.state.tasksList[0].current = false;
    }
    var newItemArray = [{
      id: this.state.tasksList.length + 1,
      task: this.state.task,
      current: true,
      createdOn: Date.now()
    }];
    var nextItems = newItemArray.concat(this.state.tasksList);
    var nextText = '';
    this.setState({
      tasksList: nextItems,
      task: nextText
    });
    if (this.state.tasksList.length === 0) {
      this.start();
    }
  },
  tick: function() {
    this.setState({timeRemaining: this.state.timeRemaining - 1});
  },
  start: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  pause: function() {
    clearInterval(this.interval);
  },
  next: function() {
    clearInterval(this.interval);
    this.setState({timeRemaining: 1500});
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (

{Math.floor(this.state.timeRemaining / 60)}min

            <button type="button" className="btn btn-default btn-lg" onClick={this.start}>Start</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.pause}>Pause</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.next}>Next</button>

Pomodoros

                  2

Work time

                  50:00

Break time

                  10:00

Breaks

                  1

        <form onSubmit={this.handleSubmit}>

            <input type="text" className="form-control" placeholder="Add new task" onChange={this.onChange} value={this.state.task} />

              <button className="btn btn-default" type="button">{'Add #' + (this.state.tasksList.length + 1)}</button>

        </form>
        <TasksList tasksList={this.state.tasksList} />

    );
  }
});

ReactDOM.render(<Timer />, document.getElementById('app'));
<commit_msg>fix task submit with click<commit_after>var React = require('react');
var ReactDOM = require('react-dom');

// var Break = React.createClass({
//   render: function() {
//     return (
//

//         *
//         Break
//         5:00
//         Break
//
//

//     );
//   }
// });

var TasksList = React.createClass({
  render: function() {
    var createItem = function(item) {
      return (

          {item.id}
          {item.task}
          25:00
          Pomodoro

      );
    };
    return (

              #
              Task
              Duration
              Type

            {this.props.tasksList.map(createItem)}

    );
  }
});

var Timer = React.createClass({
  getInitialState: function() {
    return {
      timeRemaining: 1500,
      tasksList: [],
      task: ''
    };
  },
  onChange: function(e) {
    this.setState({task: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    if (this.state.task === '') {
      return;
    }
    if (this.state.tasksList[0]) {
      this.state.tasksList[0].current = false;
    }
    var newItemArray = [{
      id: this.state.tasksList.length + 1,
      task: this.state.task,
      current: true,
      createdOn: Date.now()
    }];
    var nextItems = newItemArray.concat(this.state.tasksList);
    var nextText = '';
    this.setState({
      tasksList: nextItems,
      task: nextText
    });
    if (this.state.tasksList.length === 0) {
      this.start();
    }
  },
  tick: function() {
    this.setState({timeRemaining: this.state.timeRemaining - 1});
  },
  start: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  pause: function() {
    clearInterval(this.interval);
  },
  next: function() {
    clearInterval(this.interval);
    this.setState({timeRemaining: 1500});
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (

{Math.floor(this.state.timeRemaining / 60)}min

            <button type="button" className="btn btn-default btn-lg" onClick={this.start}>Start</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.pause}>Pause</button>
            <button type="button" className="btn btn-default btn-lg" onClick={this.next}>Next</button>

Pomodoros

                  2

Work time

                  50:00

Break time

                  10:00

Breaks

                  1

        <form onSubmit={this.handleSubmit}>

            <input type="text" className="form-control" placeholder="Add new task" onChange={this.onChange} value={this.state.task} />

              <button className="btn btn-default" type="submit">{'Add #' + (this.state.tasksList.length + 1)}</button>

        </form>
        <TasksList tasksList={this.state.tasksList} />

    );
  }
});

ReactDOM.render(<Timer />, document.getElementById('app'));
<|endoftext|>


<commit_before>(function () {
    var game = new Phaser.Game(
        window.innerWidth, window.innerHeight, Phaser.AUTO, 'tankr',
        { preload: preload,
          create: create,
          update: update }
    );
    var map;
    var player;
    var cursors;

    function preload() {
        console.log('preload');
        // game.load.tilemap('tankr', 'assets/map/tanker-14x14.json', null,
        //                   Phaser.Tilemap.TILED_JSON);
        game.load.image('tankBlue', 'assets/img/Tanks/tankBlue.png');
        game.load.image('barrelBlue', 'assets/img/Tanks/barrelBlue.png');

        game.load.image('grass', 'assets/img/Environment/grass.png');
        game.load.image('sandbagBrown', 'assets/img/Obstacles/sandbagBrown.png');
    }

    function create() {
        console.log('create');
        game.world.setBounds(-1000, -1000, 2000, 2000);
        // game.physics.startSystem(Phaser.Physics.ARCADE);

        land = game.add.tileSprite(0, 0, 2000, 2000, 'grass');
        land.fixedToCamera = true;

        player = game.add.sprite(0, 0, 'tankBlue');
        // player.anchor.setTo(0.5, 0.5);
        game.physics.startSystem(Phaser.Physics.ARCADE);
        player = game.add.sprite(900, 500, 'tankBlue');
        player.anchor.setTo(1, 1);
        barrel = game.add.sprite(0, 0, 'barrelBlue');
        // barrel.anchor.setTo(0.3, 0.5);

        // game.physics.arcade.enable(player);
        game.physics.enable(player, Phaser.Physics.ARCADE);
        // player.body.drag.set(0.2);
        // player.body.maxVelocity.setTo(400, 400);
        // player.body.collideWorldBounds = true;
        game.camera.follow(player);
        // game.camera.focusOnXY(0, 0);
        sandbagBrown1 = game.add.sprite(200, 200, 'sandbagBrown');
        sandbagBrown2 = game.add.sprite(-200, -200, 'sandbagBrown');
        // map = game.add.tilemap('tankr');
        // map = this.game.add.tilemap('MyTilemap');
        // map.addTilesetImage('tiles', 'tiles');

        // layer = map.createLayer('MyTerrain');
        // layer.resizeWorld();
        // layer.wrap = true;

        // player.bringToTop();
        // barrel.bringToTop();
        cursors = game.input.keyboard.createCursorKeys();
    }

    function update() {
<<<<<<< HEAD
        var units = 50,
=======
        var units = 100,
>>>>>>> e1e62dcf15ff9be0bf5628c66d29c50616facae5
            angle = 3;

        if (cursors.left.isDown) {
            player.angle += -angle;
            player.animations.play('left');
        } else if (cursors.right.isDown) {
            player.angle += angle;
            player.animations.play('right');
        } else if (cursors.down.isDown) {
            game.physics.arcade.velocityFromAngle(
                player.angle + 90,
                units,
                player.body.velocity
            );
            player.animations.play('down');
        } else if (cursors.up.isDown) {
            game.physics.arcade.velocityFromAngle(
                player.angle + -90,
                units,
                player.body.velocity
            );
            player.animations.play('up');
        } else {
            player.animations.stop();
            player.frame = 4;
        }
        if (cursors.up.isDown && player.body.touching.down && hitPlatform)
        {
            player.body.velocity.y = -350;
        }
    }

    function render() {
        console.log('render');
    }

    PlayerTank = function (game) {
        this.game = game;
        this.tank = game.add.sprite(
            game.world.randomX, game.world.randomY,
            'tank', 'tankRed'
        );

        game.physics.enable(tank, Phaser.Physics.ARCADE);
        tank.angle = game.rnd.angle();
        game.physics.arcade.velocityFromRotation(
            this.tank.rotation,
            100,
            this.tank.body.velocity
        );
    };

}());
<commit_msg>fix conflict<commit_after>(function () {
    var game = new Phaser.Game(
        window.innerWidth, window.innerHeight, Phaser.AUTO, 'tankr',
        { preload: preload,
          create: create,
          update: update }
    );
    var map;
    var player;
    var cursors;

    function preload() {
        console.log('preload');
        // game.load.tilemap('tankr', 'assets/map/tanker-14x14.json', null,
        //                   Phaser.Tilemap.TILED_JSON);
        game.load.image('tankBlue', 'assets/img/Tanks/tankBlue.png');
        game.load.image('barrelBlue', 'assets/img/Tanks/barrelBlue.png');

        game.load.image('grass', 'assets/img/Environment/grass.png');
        game.load.image('sandbagBrown', 'assets/img/Obstacles/sandbagBrown.png');
    }

    function create() {
        console.log('create');
        game.world.setBounds(-1000, -1000, 2000, 2000);
        // game.physics.startSystem(Phaser.Physics.ARCADE);

        land = game.add.tileSprite(0, 0, 2000, 2000, 'grass');
        land.fixedToCamera = true;

        player = game.add.sprite(0, 0, 'tankBlue');
        // player.anchor.setTo(0.5, 0.5);
        game.physics.startSystem(Phaser.Physics.ARCADE);
        player = game.add.sprite(900, 500, 'tankBlue');
        player.anchor.setTo(1, 1);
        barrel = game.add.sprite(0, 0, 'barrelBlue');
        // barrel.anchor.setTo(0.3, 0.5);

        // game.physics.arcade.enable(player);
        game.physics.enable(player, Phaser.Physics.ARCADE);
        // player.body.drag.set(0.2);
        // player.body.maxVelocity.setTo(400, 400);
        // player.body.collideWorldBounds = true;
        game.camera.follow(player);
        // game.camera.focusOnXY(0, 0);
        sandbagBrown1 = game.add.sprite(200, 200, 'sandbagBrown');
        sandbagBrown2 = game.add.sprite(-200, -200, 'sandbagBrown');
        // map = game.add.tilemap('tankr');
        // map = this.game.add.tilemap('MyTilemap');
        // map.addTilesetImage('tiles', 'tiles');

        // layer = map.createLayer('MyTerrain');
        // layer.resizeWorld();
        // layer.wrap = true;

        // player.bringToTop();
        // barrel.bringToTop();
        cursors = game.input.keyboard.createCursorKeys();
    }

    function update() {
        var units = 100,
            angle = 3;

        if (cursors.left.isDown) {
            player.angle += -angle;
            player.animations.play('left');
        } else if (cursors.right.isDown) {
            player.angle += angle;
            player.animations.play('right');
        } else if (cursors.down.isDown) {
            game.physics.arcade.velocityFromAngle(
                player.angle + 90,
                units,
                player.body.velocity
            );
            player.animations.play('down');
        } else if (cursors.up.isDown) {
            game.physics.arcade.velocityFromAngle(
                player.angle + -90,
                units,
                player.body.velocity
            );
            player.animations.play('up');
        } else {
            player.animations.stop();
            player.frame = 4;
        }
        if (cursors.up.isDown && player.body.touching.down && hitPlatform)
        {
            player.body.velocity.y = -350;
        }
    }

    function render() {
        console.log('render');
    }

    PlayerTank = function (game) {
        this.game = game;
        this.tank = game.add.sprite(
            game.world.randomX, game.world.randomY,
            'tank', 'tankRed'
        );

        game.physics.enable(tank, Phaser.Physics.ARCADE);
        tank.angle = game.rnd.angle();
        game.physics.arcade.velocityFromRotation(
            this.tank.rotation,
            100,
            this.tank.body.velocity
        );
    };

}());
<|endoftext|>


<commit_before>console.time('noflo-ui-init');
console.time('polymer-ready');

window.addEventListener('polymer-ready', function() {
  var noflo = require('noflo');
  var runtime = require('noflo-runtime-webrtc');

  var baseDir = '/noflo-ui';
  var mainGraph = 'noflo-ui/graphs/main.fbp';

  var loadGraphs = function(callback) {
    noflo.graph.loadJSON(require(mainGraph), function (g) {
      g.baseDir = baseDir;
      noflo.createNetwork(g, function (n) {
        n.on('process-error', function (err) {
          console.log(err);
        });
        return callback();
      });
    });
  };
  var loadGraphsDebuggable = function(callback) {
    noflo.graph.loadJSON(require(mainGraph), function (graph) {
      graph.baseDir = baseDir;
      var runtimeOptions = {
        defaultGraph: graph,
        baseDir: graph.baseDir
      };
      var rt = runtime(null, runtimeOptions, true);
      rt.start();
      var ide = 'http://app.flowhub.io';
      var debugUrl = ide+'#runtime/endpoint?'+encodeURIComponent('protocol=webrtc&address='+rt.signaller+'#'+rt.id);
      var debugLink = document.getElementById('flowhub_debug_url');
      if (debugLink) {
        debugLink.href = debugUrl;
      } else {
        console.log(debugUrl);
      }
      rt.network.on('addnetwork', function () {
        return callback();
      });
    });
  };

  console.timeEnd('polymer-ready');
  document.body.classList.remove('loading');
  window.nofloStarted = false;
  console.time('noflo-prepare');
  var load = (true) ? loadGraphsDebuggable : loadGraphs;
  load(function() {
      console.timeEnd('noflo-prepare');
      console.timeEnd('noflo-ui-init');
  });
});
<commit_msg>Define a secret and provide capabilities for the WebRTC runtime<commit_after>console.time('noflo-ui-init');
console.time('polymer-ready');

window.addEventListener('polymer-ready', function() {
  var noflo = require('noflo');
  var runtime = require('noflo-runtime-webrtc');

  var baseDir = '/noflo-ui';
  var mainGraph = 'noflo-ui/graphs/main.fbp';

  var loadGraphs = function(callback) {
    noflo.graph.loadJSON(require(mainGraph), function (g) {
      g.baseDir = baseDir;
      noflo.createNetwork(g, function (n) {
        n.on('process-error', function (err) {
          console.log(err);
        });
        return callback();
      });
    });
  };
  var loadGraphsDebuggable = function(callback) {
    var secret = Math.random().toString(36).substring(7);
    noflo.graph.loadJSON(require(mainGraph), function (graph) {
      graph.baseDir = baseDir;
      var runtimeOptions = {
        defaultGraph: graph,
        baseDir: graph.baseDir,
        permissions: {}
      };
      runtimeOptions.permissions[secret] = [
        'protocol:component',
        'protocol:runtime',
        'protocol:graph',
        'protocol:network',
        'component:getsource',
        'component:setsource'
      ];
      var rt = runtime(null, runtimeOptions, true);
      rt.start();
      var ide = 'http://app.flowhub.io';
      var debugUrl = ide+'#runtime/endpoint?'+encodeURIComponent('protocol=webrtc&address='+rt.signaller+'#'+rt.id+'&secret='+secret);
      var debugLink = document.getElementById('flowhub_debug_url');
      if (debugLink) {
        debugLink.href = debugUrl;
      } else {
        console.log(debugUrl);
      }
      rt.network.on('addnetwork', function () {
        return callback();
      });
    });
  };

  console.timeEnd('polymer-ready');
  document.body.classList.remove('loading');
  window.nofloStarted = false;
  console.time('noflo-prepare');
  var load = (true) ? loadGraphsDebuggable : loadGraphs;
  load(function() {
      console.timeEnd('noflo-prepare');
      console.timeEnd('noflo-ui-init');
  });
});
<|endoftext|>


<commit_before>"use strict";

(function() {

    //
    // polyfill performance.now()
    //
    if(window.performance && window.performance.now) {
        var now = function() { return performance.now();
    } else if(Date.now) {
        var now = function() { return Date.now(); }
    } else {
        var now = function() { return Date().getTime(); }
    }

    //
    // Encapsulate a task
    //
    function Task(action) {
        this.start = action;
    }

    //
    // Encapsulate task priority logic
    //
    function TaskScheduler(parent) {

        this.isRunning = false;
        this.isScheduledNow = false;

        this.taskQueue = [];
        this.delayedTasks = 0;
        this.childSchedulers = [];
        this.parentScheduler = parent;
        if(parent) { parent.childSchedulers.push(this); }

        var This = this;
        This.tryRun = function() {
            if(This.parentScheduler) {
                This.parentScheduler.tryRun();
            } else {
                This.run();
            }
        }
        This.run = function() {

            This.isRunning = true;

            // calling code should not face scheduler errors
            try {

                //
                // walk through all tasks
                //
                if(This.taskQueue.length !== 0) {

                    var task; while(task=This.taskQueue.shift()) {

                        // run the task
                        // (the loop should not break if a task fails)
                        try { task.start(); }
                        catch(ex) { setImmediate(function() { throw ex; }) }

                    }

                }

                //
                // let child schedulers execute if no task is pending
                //
                if(This.delayedTasks !== 0) {

                    for(var i=0; i<This.childSchedulers.length; i++) {

                        // run the scheduler
                        // (the loop should not break if a scheduler fails)
                        try { child.run(); }
                        catch(ex) { setImmediate(function() { throw ex; }) }

                    }

                }

            } catch(ex) { setImmediate(function() { throw ex; }) }

            This.isRunning = false;

        }

    }

    TaskScheduler.prototype.pushTask = function(f) {

        // push the task
        this.taskQueue.push(f);

        // ensure the scheduler will run soon
        this.scheduleNow();

    };

    TaskScheduler.prototype.pushDelayedTask = function(f, scheduler) {

        // ask for a delayed execution
        var This = this;
        var result = scheduler(function() {

            // push the task
            This.pushTask(f);
            This.delayedTasks--;

            // empty the queue
            This.tryRun();

        });

        // record the future task
        this.delayedTasks++;

        // return scheduler-relative info
        return result;

    }

    // aliases for common web functions
    TaskScheduler.prototype.setImmediate = TaskScheduler.prototype.pushTask;
    TaskScheduler.prototype.setTimeout = function(f,d) {
        TaskScheduler.prototype.pushDelayedTask(f, function(f) { setTimeout(f,d) })
    }
    TaskScheduler.prototype.requestAnimationFrame = function(f,d) {
        TaskScheduler.prototype.pushDelayedTask(f, requestAnimationFrame);
    }

    TaskScheduler.prototype.scheduleNow = function() {

        // avoid creating multiple running
        // version of the scheduler
        if(this.isRunning) return;
        if(this.isScheduledNow) return;

        // schedule a new run
        setImmediate(this.tryRun);

    }

}());<commit_msg>First working implementation of the task scheduler<commit_after>"use strict";

(function() {

    //
    // polyfill performance.now()
    //
    if(window.performance && window.performance.now) {
        var now = function() { return performance.now(); }
    } else if(Date.now) {
        var now = function() { return Date.now(); }
    } else {
        var now = function() { return Date().getTime(); }
    }

    //
    // polyfill setImmediate
    //
    var setImmediate = window.setImmediate || function(f) {
        setTimeout(f,0);
    }

    //
    // polyfill rAF
    //
    var requestAnimationFrame = window.requestAnimationFrame || function(f) {
        setTimeout(f,16);
    }

    //
    // Encapsulate a task
    //
    function Task(action) {
        this.call = action;
    }

    //
    // Encapsulate task priority logic
    //
    function TaskScheduler(parent) {

        this.isRunning = false;
        this.isScheduledNow = false;

        this.taskQueue = [];
        this.delayedTasks = 0;
        this.childSchedulers = [];
        this.parentScheduler = parent;
        if(parent) { parent.childSchedulers.push(this); }

        var This = this;
        This.tryRun = function() {
            if(This.parentScheduler) {
                This.parentScheduler.tryRun();
            } else {
                This.run();
            }
        }
        This.run = function() {

            This.isRunning = true;

            // calling code should not face scheduler errors
            try {

                //
                // walk through all tasks
                //
                if(This.taskQueue.length !== 0) {

                    var task; while(task=This.taskQueue.shift()) {

                        // run the task
                        // (the loop should not break if a task fails)
                        try { task.call(); }
                        catch(ex) { setImmediate(function() { throw ex; }) }

                    }

                }

                //
                // let child schedulers execute if no task is pending
                //
                if(This.delayedTasks === 0) {

                    for(var i=0; i<This.childSchedulers.length; i++) {

                        // run the scheduler
                        // (the loop should not break if a scheduler fails)
                        try { This.childSchedulers[i].run(); }
                        catch(ex) { setImmediate(function() { throw ex; }) }

                    }

                }

                //
                // execute new immediates, if any
                //
                if(This.taskQueue.length !== 0) {

                    This.run();

                }

            } catch(ex) { setImmediate(function() { throw ex; }) }

            This.isRunning = false;

        }

    }

    TaskScheduler.prototype.pushTask = function(f) {

        // push the task
        this.taskQueue.push(f);

        // ensure the scheduler will run soon
        this.scheduleNow();

    };

    TaskScheduler.prototype.pushDelayedTask = function(f, scheduler) {

        // ask for a delayed execution
        var This = this;
        var result = scheduler(function() {

            // push the task
            This.pushTask(f);
            This.delayedTasks--;

            // empty the queue
            This.tryRun();

        });

        // record the future task
        this.delayedTasks++;

        // return scheduler-relative info
        return result;

    }

    // aliases for common web functions
    TaskScheduler.prototype.setImmediate = TaskScheduler.prototype.pushTask;
    TaskScheduler.prototype.setTimeout = function(f,d) {
        this.pushDelayedTask(f, function(f) { setTimeout(f,d) })
    }
    TaskScheduler.prototype.requestAnimationFrame = function(f,d) {
        this.pushDelayedTask(f, requestAnimationFrame);
    }

    TaskScheduler.prototype.scheduleNow = function() {

        // avoid creating multiple running
        // version of the scheduler
        if(this.isRunning) return;
        if(this.isScheduledNow) return;

        // schedule a new run
        setImmediate(this.tryRun);

    }

    window.JSTaskScheduler = TaskScheduler;

}());<|endoftext|>


<commit_before>var isPrimitive = require('../lang/isPrimitive')

function get (obj, prop) {
  var parts = prop.split('.')
  var last = parts.pop()

  while (prop = parts.shift()) {
    obj = obj[prop]
    if (obj == null) return
  }
  return obj[last]
}

module.exports = get
<commit_msg>update- clean<commit_after>// get nested object property

function get (obj, prop) {
  var parts = prop.split('.')
  var last = parts.pop()

  while (prop = parts.shift()) {
    obj = obj[prop]
    if (obj == null) return
  }
  return obj[last]
}

module.exports = get
<|endoftext|>


<commit_before>Openure = {
    allViews: [],
    currentView: "",
    listener: "",
    trackedViewsIDs: [],
    previousView: null,

    findViewsInRegion: function(region) {
        this.findViewsInView(region.currentView);
    },

    findViewsInView: function(view) {
        if (view.cid && _.lastIndexOf(this.trackedViewsIDs, view.cid) == -1) {
            this.trackedViewsIDs.push(view.cid);
            for(var prop in view) {
                this.findViewsAndRegionsInObject(view[prop]);
            }
            this.allViews.push(view);
        }
    },

    findViewsAndRegionsInObject: function(obj) {
        for(var prop in obj) {
            if (obj[prop] instanceof Backbone.ChildViewContainer) {
                obj[prop].each(function(subview) {
                    this.findViewsInView(subview);
                }, this);
            }
            else if (obj[prop] instanceof Marionette.Region) {
                this.findViewsInRegion(obj[prop]);
            }
            else if (obj[prop] instanceof Marionette.View) {
                this.findViewsInView(obj[prop]);
            }
            else if (obj[prop] instanceof Marionette.Application) {
                this.findViewsAndRegionsInObject(obj[prop]);
            }
        }
    },

    applySelectedView: function() {
        console.log("rock the view - " + Openure.currentView.cid);

        //Remove the current console when clicking a new one.
        if($('#console').length) {
            this.previousView.el.removeChild($('#console')[0]);
        }

        var jqconsole = document.createElement('div');

        var width = this.currentView.$el.css('width');
        width = width.substr(0, width.indexOf('px')); //pull off the px
        var consoleWidth = parseInt(width) - 5;
        jqconsole.style.cssText = 'width:' + consoleWidth + 'px;z-index:99';
        jqconsole.id = "console";

        this.currentView.el.appendChild(jqconsole);

// Creating the console.
        var header = 'Welcome to Openure in JQConsole!\n' +
            'The variable "view" is now in context\n' +
            'here and in the chrome console.\n' +
            'As is model, collection, and options.\n';
        this.jqconsole = $('#console').jqconsole(header, 'JS> ');

// Abort prompt on Ctrl+Z.
        this.jqconsole.RegisterShortcut('Z', function() {
            this.jqconsole.AbortPrompt();
            handler();
        });

// Move to line start Ctrl+A.
        this.jqconsole.RegisterShortcut('A', function() {
            this.jqconsole.MoveToStart();
            handler();
        });

// Move to line end Ctrl+E.
        this.jqconsole.RegisterShortcut('E', function() {
            this.jqconsole.MoveToEnd();
            handler();
        });

        this.jqconsole.RegisterMatching('{', '}', 'brace');
        this.jqconsole.RegisterMatching('(', ')', 'paran');
        this.jqconsole.RegisterMatching('[', ']', 'bracket');

        isObject = function(obj) {
            return obj === Object(obj);
        };

// Handle a command.
        var handler = _.bind(function(command) {
            if (command) {
                try {
                    var result = window.eval(command);
                } catch (e) {
                    this.jqconsole.Write('ERROR: ' + e.message + '\n');
                }
                try {
                    if(isObject(result)) {
                        result = JSON.stringify(result, function(k, v) {
                            return (k === '$el' || k === 'el' || k === '_events' || k === '_listeners') ? undefined : v;
                        }, 2);
                    }
                } catch (e) {
                    if (e.message === 'Converting circular structure to JSON') {
                        this.jqconsole.Write('ERROR: ' + e.message + '\n');
                        this.jqconsole.Write('Please try the same command in the chrome console.\n');
                    }
                    else {
                        this.jqconsole.Write('ERROR: ' + e.message + '\n');
                    }
                }

                this.jqconsole.Write(result);
                this.jqconsole.Write('\n');
            }
            this.jqconsole.Prompt(true, handler, function(command) {
                // Continue line if can't compile the command.
                try {
                    Function(command);
                } catch (e) {
                    if (/[\[\{\(]$/.test(command)) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
                return false;
            });
        }, this);

// Initiate the first prompt.
        handler();

        model = this.currentView.model;
        view = this.currentView;
        collection = this.currentView.collection;
        options = this.currentView.options;
        clearInterval(this.listener);
        this.previousView = view;
    },

    go: function() {
        this.findViewsAndRegionsInObject(window);

        _.each(this.allViews, function(view) {
            view.$el[0].addEventListener('click', _.bind(function(e) {
                if(e.metaKey && e.shiftKey) {
                    var ownIt = _.bind(this.applySelectedView, this);

                    clearInterval(this.listener);
                    this.listener = setInterval(ownIt, 100);

                    e.preventDefault();
                    this.currentView = view;
                }
            }, this), true);
        }, this);
    }
};

$(function () {
    Openure.go();
});
<commit_msg>close a view by clicking it again<commit_after>Openure = {
    allViews: [],
    currentView: "",
    listener: "",
    trackedViewsIDs: [],
    previousView: null,

    findViewsInRegion: function(region) {
        this.findViewsInView(region.currentView);
    },

    findViewsInView: function(view) {
        if (view.cid && _.lastIndexOf(this.trackedViewsIDs, view.cid) == -1) {
            this.trackedViewsIDs.push(view.cid);
            for(var prop in view) {
                this.findViewsAndRegionsInObject(view[prop]);
            }
            this.allViews.push(view);
        }
    },

    findViewsAndRegionsInObject: function(obj) {
        for(var prop in obj) {
            if (obj[prop] instanceof Backbone.ChildViewContainer) {
                obj[prop].each(function(subview) {
                    this.findViewsInView(subview);
                }, this);
            }
            else if (obj[prop] instanceof Marionette.Region) {
                this.findViewsInRegion(obj[prop]);
            }
            else if (obj[prop] instanceof Marionette.View) {
                this.findViewsInView(obj[prop]);
            }
            else if (obj[prop] instanceof Marionette.Application) {
                this.findViewsAndRegionsInObject(obj[prop]);
            }
        }
    },

    applySelectedView: function() {
        console.log("rock the view - " + this.currentView.cid);

        //Remove the current console when clicking a new one.
        if($('#console').length) {
            this.previousView.el.removeChild($('#console')[0]);
        }

        //For now, close it by clicking the same view again.
        if(this.previousView.cid === this.currentView.cid){
            this.previousView = null;
            return;
        }

        var jqconsole = document.createElement('div');

        var width = this.currentView.$el.css('width');
        width = width.substr(0, width.indexOf('px')); //pull off the px
        var consoleWidth = parseInt(width) - 5;
        jqconsole.style.cssText = 'width:' + consoleWidth + 'px;z-index:99';
        jqconsole.id = "console";

        this.currentView.el.appendChild(jqconsole);

// Creating the console.
        var header = 'Welcome to Openure in JQConsole!\n' +
            'The variable "view" is now in context\n' +
            'here and in the chrome console.\n' +
            'As is model, collection, and options.\n';
        this.jqconsole = $('#console').jqconsole(header, 'JS> ');

// Abort prompt on Ctrl+Z.
        this.jqconsole.RegisterShortcut('Z', function() {
            this.jqconsole.AbortPrompt();
            handler();
        });

// Move to line start Ctrl+A.
        this.jqconsole.RegisterShortcut('A', function() {
            this.jqconsole.MoveToStart();
            handler();
        });

// Move to line end Ctrl+E.
        this.jqconsole.RegisterShortcut('E', function() {
            this.jqconsole.MoveToEnd();
            handler();
        });

        this.jqconsole.RegisterMatching('{', '}', 'brace');
        this.jqconsole.RegisterMatching('(', ')', 'paran');
        this.jqconsole.RegisterMatching('[', ']', 'bracket');

        isObject = function(obj) {
            return obj === Object(obj);
        };

// Handle a command.
        var handler = _.bind(function(command) {
            if (command) {
                try {
                    var result = window.eval(command);
                } catch (e) {
                    this.jqconsole.Write('ERROR: ' + e.message + '\n');
                }
                try {
                    if(isObject(result)) {
                        result = JSON.stringify(result, function(k, v) {
                            return (k === '$el' || k === 'el' || k === '_events' || k === '_listeners') ? undefined : v;
                        }, 2);
                    }
                } catch (e) {
                    if (e.message === 'Converting circular structure to JSON') {
                        this.jqconsole.Write('ERROR: ' + e.message + '\n');
                        this.jqconsole.Write('Please try the same command in the chrome console.\n');
                    }
                    else {
                        this.jqconsole.Write('ERROR: ' + e.message + '\n');
                    }
                }

                this.jqconsole.Write(result);
                this.jqconsole.Write('\n');
            }
            this.jqconsole.Prompt(true, handler, function(command) {
                // Continue line if can't compile the command.
                try {
                    Function(command);
                } catch (e) {
                    if (/[\[\{\(]$/.test(command)) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
                return false;
            });
        }, this);

// Initiate the first prompt.
        handler();

        model = this.currentView.model;
        view = this.currentView;
        collection = this.currentView.collection;
        options = this.currentView.options;
        clearInterval(this.listener);
        this.previousView = view;
    },

    go: function() {
        this.findViewsAndRegionsInObject(window);

        _.each(this.allViews, function(view) {
            view.$el[0].addEventListener('click', _.bind(function(e) {
                if(e.metaKey && e.shiftKey) {
                    var ownIt = _.bind(this.applySelectedView, this);

                    clearInterval(this.listener);
                    this.listener = setInterval(ownIt, 100);

                    e.preventDefault();
                    this.currentView = view;
                }
            }, this), true);
        }, this);
    }
};

$(function () {
    Openure.go();
});
<|endoftext|>


<commit_before>function getTopDomains(historyItems) {
  var typedCounts = {};
  // Get URL data.
  var domains = [];
  for (var i = 0; i < historyItems.length; i++) {
    var h = historyItems[i];
    if (h.url && h.typedCount) {
      if (h.url.slice(0, 5) == 'https')
        continue; // https URLs are probably not junk
      var domain = normalizedDomain(h.url);
      if (domain.indexOf('google.') != -1) // add some other major sites?
        continue;
      domains.push(domain);
      typedCounts[domain] = h.typedCount;
    }
  }
  // Sort by typed count (descending).
  domains.sort(function(a, b) { return typedCounts[b] - typedCounts[a] });
  // Take top N.
  var topUrls = domains.slice(0, 5);
  return topUrls;
} // getTopDomains

function clearUrls() {
  var ul = document.getElementById("topVisited");
  while (ul.childNodes.length > 0)
    ul.removeChild(ul.firstChild);
}

function addUrlField(value) {
  var checkbox = document.createElement('input');
  checkbox.setAttribute('type', 'checkbox');
  checkbox.setAttribute('checked', 'checked');

  var input = document.createElement('input');
  input.setAttribute('type', 'text');
  input.value = value;

  var li = document.createElement('li');
  li.appendChild(checkbox);
  li.appendChild(input);

  var ul = document.getElementById("topVisited");
  var button_li = document.getElementById("add_domain_button").parentNode;
  // Insert field before the "add domain" button.
  ul.insertBefore(li, button_li);
}

function putDomainsOnPage(topUrls) {
  // Put on page.
  for (var i = 0; i < topUrls.length; i++) {
    var domain = normalizedDomain(topUrls[i]);
    addUrlField(domain);
  }

  // Remove placeholder, if any.
  var placeholder = document.getElementById("placeholder");
  if (placeholder)
    document.getElementById("topVisited").removeChild(placeholder);
} // putDomainsOnPage

function loadSavedUrls() {
  putDomainsOnPage(getLocal('junkDomains'));
}

function loadTopUrls() {
  var weekAgo = new Date().getTime() - 1000*3600*24*7;
  chrome.history.search({ text: "", startTime: weekAgo,
                          maxResults: 1000 },
    function(historyItems) {
      var topUrls = getTopDomains(historyItems);
      setLocal('junkDomains', topUrls);
      // Not calling submitConfigChange here to give the chance for the
      // user to clean the domain list.
      putDomainsOnPage(topUrls);
    }
  );
} // loadTopUrls()

function bindControlHandlers() {
  document.getElementById('add_domain_button').onclick = addNewDomain;
  document.getElementById('save_button').onclick = saveSettings;
  document.getElementById('crackbookLink').onclick = function() {
    chrome.tabs.create({url: 'http://crackbook.info'});
  }
}

function showSettings() {
  // Threshold & delay
  document.getElementById("dimmerThreshold").value = getLocal('dimmerThreshold');
  document.getElementById("dimmerDelay").value = getLocal('dimmerDelay');

  // Junk domains.
  if (getLocal('junkDomains').length == 0)
    loadTopUrls();
  else
    loadSavedUrls();

  // Schedule
  document.getElementById("startTime").value = renderTime(getLocal('startTime'));
  document.getElementById("endTime").value = renderTime(getLocal('endTime'));

  var currentWeekdays = getLocal('weekdays');
  for (var i = 0; i < 7; i++) {
    document.getElementById("weekday-" + i).checked = currentWeekdays.indexOf("" + i) != -1;
  }

  // Reporting
  if (getLocal('reporting'))
    document.getElementById("upload_stats").checked = true;
}

function saveSettings() {
  /* Save settings from submitted form. */

  // Junk domains
  var ul = document.getElementById("topVisited");
  junkDomains = [];
  for (var i = 0; i < ul.childNodes.length; i++) {
    if (ul.childNodes[i].nodeName == "LI") {
      var li = ul.childNodes[i];
      var checkbox = li.childNodes[0];
      var input = li.childNodes[1];
      if (checkbox.checked) {
        var domain = normalizedDomain(input.value);
        if (domain.indexOf(".") != -1)
          junkDomains.push(domain);
      }
    }
  }

  // Threshold & delay
  var dimmerThreshold = parseInt(document.getElementById("dimmerThreshold").value);
  if (!dimmerThreshold || dimmerThreshold <= 0)
    dimmerThreshold = getLocal('dimmerThreshold');

  var dimmerDelay = parseInt(document.getElementById("dimmerDelay").value);
  if (!dimmerDelay || dimmerDelay <= 0)
    dimmerDelay = getLocal('dimmerDelay');

  // TODO: better validation
  var startTime = parseTime(document.getElementById("startTime").value);
  var endTime = parseTime(document.getElementById("endTime").value);

  var weekdays = "";
  for (var i = 0; i < 7; i++)
    if (document.getElementById("weekday-" + i).checked)
      weekdays += i;

  var reporting = document.getElementById("upload_stats").checked;

  // Write settings to storage.
  setLocal('reporting', reporting);
  setLocal('dimmerThreshold', dimmerThreshold);
  setLocal('dimmerDelay', dimmerDelay);
  setLocal('junkDomains', junkDomains);
  setLocal('startTime', startTime);
  setLocal('endTime', endTime);
  setLocal('weekdays', weekdays);

  bgPage().submitConfigChange();

  // Show status message.
  document.getElementById('saved_message').style['display'] = 'inline';
} // saveSettings

function addNewDomain() {
  addUrlField('');
}

window.onload = function() {
  bindControlHandlers();
  showSettings();
}
<commit_msg>Factor out TOP_DOMAINS_NUM.<commit_after>var TOP_DOMAINS_NUM = 6;

function getTopDomains(historyItems) {
  var typedCounts = {};
  // Get URL data.
  var domains = [];
  for (var i = 0; i < historyItems.length; i++) {
    var h = historyItems[i];
    if (h.url && h.typedCount) {
      if (h.url.slice(0, 5) == 'https')
        continue; // https URLs are probably not junk
      var domain = normalizedDomain(h.url);
      if (domain.indexOf('google.') != -1) // add some other major sites?
        continue;
      domains.push(domain);
      typedCounts[domain] = h.typedCount;
    }
  }
  // Sort by typed count (descending).
  domains.sort(function(a, b) { return typedCounts[b] - typedCounts[a] });
  // Take top N.
  var topUrls = domains.slice(0, TOP_DOMAINS_NUM);
  return topUrls;
} // getTopDomains

function clearUrls() {
  var ul = document.getElementById("topVisited");
  while (ul.childNodes.length > 0)
    ul.removeChild(ul.firstChild);
}

function addUrlField(value) {
  var checkbox = document.createElement('input');
  checkbox.setAttribute('type', 'checkbox');
  checkbox.setAttribute('checked', 'checked');

  var input = document.createElement('input');
  input.setAttribute('type', 'text');
  input.value = value;

  var li = document.createElement('li');
  li.appendChild(checkbox);
  li.appendChild(input);

  var ul = document.getElementById("topVisited");
  var button_li = document.getElementById("add_domain_button").parentNode;
  // Insert field before the "add domain" button.
  ul.insertBefore(li, button_li);
}

function putDomainsOnPage(topUrls) {
  // Put on page.
  for (var i = 0; i < topUrls.length; i++) {
    var domain = normalizedDomain(topUrls[i]);
    addUrlField(domain);
  }

  // Remove placeholder, if any.
  var placeholder = document.getElementById("placeholder");
  if (placeholder)
    document.getElementById("topVisited").removeChild(placeholder);
} // putDomainsOnPage

function loadSavedUrls() {
  putDomainsOnPage(getLocal('junkDomains'));
}

function loadTopUrls() {
  var weekAgo = new Date().getTime() - 1000*3600*24*7;
  chrome.history.search({ text: "", startTime: weekAgo,
                          maxResults: 1000 },
    function(historyItems) {
      var topUrls = getTopDomains(historyItems);
      setLocal('junkDomains', topUrls);
      // Not calling submitConfigChange here to give the chance for the
      // user to clean the domain list.
      putDomainsOnPage(topUrls);
    }
  );
} // loadTopUrls()

function bindControlHandlers() {
  document.getElementById('add_domain_button').onclick = addNewDomain;
  document.getElementById('save_button').onclick = saveSettings;
  document.getElementById('crackbookLink').onclick = function() {
    chrome.tabs.create({url: 'http://crackbook.info'});
  }
}

function showSettings() {
  // Threshold & delay
  document.getElementById("dimmerThreshold").value = getLocal('dimmerThreshold');
  document.getElementById("dimmerDelay").value = getLocal('dimmerDelay');

  // Junk domains.
  if (getLocal('junkDomains').length == 0)
    loadTopUrls();
  else
    loadSavedUrls();

  // Schedule
  document.getElementById("startTime").value = renderTime(getLocal('startTime'));
  document.getElementById("endTime").value = renderTime(getLocal('endTime'));

  var currentWeekdays = getLocal('weekdays');
  for (var i = 0; i < 7; i++) {
    document.getElementById("weekday-" + i).checked = currentWeekdays.indexOf("" + i) != -1;
  }

  // Reporting
  if (getLocal('reporting'))
    document.getElementById("upload_stats").checked = true;
}

function saveSettings() {
  /* Save settings from submitted form. */

  // Junk domains
  var ul = document.getElementById("topVisited");
  junkDomains = [];
  for (var i = 0; i < ul.childNodes.length; i++) {
    if (ul.childNodes[i].nodeName == "LI") {
      var li = ul.childNodes[i];
      var checkbox = li.childNodes[0];
      var input = li.childNodes[1];
      if (checkbox.checked) {
        var domain = normalizedDomain(input.value);
        if (domain.indexOf(".") != -1)
          junkDomains.push(domain);
      }
    }
  }

  // Threshold & delay
  var dimmerThreshold = parseInt(document.getElementById("dimmerThreshold").value);
  if (!dimmerThreshold || dimmerThreshold <= 0)
    dimmerThreshold = getLocal('dimmerThreshold');

  var dimmerDelay = parseInt(document.getElementById("dimmerDelay").value);
  if (!dimmerDelay || dimmerDelay <= 0)
    dimmerDelay = getLocal('dimmerDelay');

  // TODO: better validation
  var startTime = parseTime(document.getElementById("startTime").value);
  var endTime = parseTime(document.getElementById("endTime").value);

  var weekdays = "";
  for (var i = 0; i < 7; i++)
    if (document.getElementById("weekday-" + i).checked)
      weekdays += i;

  var reporting = document.getElementById("upload_stats").checked;

  // Write settings to storage.
  setLocal('reporting', reporting);
  setLocal('dimmerThreshold', dimmerThreshold);
  setLocal('dimmerDelay', dimmerDelay);
  setLocal('junkDomains', junkDomains);
  setLocal('startTime', startTime);
  setLocal('endTime', endTime);
  setLocal('weekdays', weekdays);

  bgPage().submitConfigChange();

  // Show status message.
  document.getElementById('saved_message').style['display'] = 'inline';
} // saveSettings

function addNewDomain() {
  addUrlField('');
}

window.onload = function() {
  bindControlHandlers();
  showSettings();
}
<|endoftext|>