<commit_before>import * as R from "ramda"

//

function Identity(value) {this.value = value}
const Ident = x => new Identity(x)
Identity.prototype.map = function (x2y) {return new Identity(x2y(this.value))}
Identity.prototype.of = Ident
Identity.prototype.ap = function (x) {return new Identity(this.value(x.value))}

//

function Constant(value) {this.value = value}
const Const = x => new Constant(x)
const Single = x => Const([x])
Constant.prototype.map = function () {return this}
Constant.prototype.of = Const
Constant.prototype.ap = function (x) {return new Const(R.concat(this.value, x.value))}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const curry2 = fn => function (a, b) {
  switch (arguments.length) {
    case 1:  return b => fn(a, b)
    default: return fn(a, b)
  }
}

const curry3 = fn => function (a, b, c) {
  switch (arguments.length) {
    case 1:  return curry2((b, c) => fn(a, b, c))
    case 2:  return c => fn(a, b, c)
    default: return fn(a, b, c)
  }
}

//

const isArray  = x => x && x.constructor === Array
const isObject = x => x && x.constructor === Object

const unArray  = x =>  isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : []

//

const id = x => x
const snd = (_, c) => c

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const dropped = xs => {
  for (const _ in xs)
    return xs
  return undefined
}

//

const empty = {}

const deleteKey = (k, o) => {
  const r = Object.assign({}, o)
  delete r[k]
  return dropped(r)
}

const setKey = (k, v, o) => {
  const r = Object.assign({}, o)
  r[k] = v
  return r
}

//

const toPartial = transform => x => undefined === x ? x : transform(x)

//

const filtered = toPartial(xs => dropped(xs.filter(x => x !== undefined)))

//

const seemsLens = x => typeof x === "function" && x.length === 1

const lifted = assert("a lens", seemsLens)

const lift = l => {
  switch (typeof l) {
    case "string": return liftProp(l)
    case "number": return liftIndex(l)
    default:       return lifted(l)
  }
}

export const compose = (...ls) =>
  ls.length === 0 ? identity :
  ls.length === 1 ? ls[0] :
  (toCat => R.compose(...ls.map(l => lift(l)(toCat))))

export const removeAll = curry2((lens, data) => {
  warn("`removeAll` is deprecated and will be removed in next major version --- use a different approach.")
  while (get(lens, data) !== undefined)
    data = remove(lens, data)
  return data
})

const setI = (l, x, s) => {
  switch (typeof l) {
    case "string": return setProp(l, x, s)
    case "number": return setIndex(l, x, s)
    default:       return lifted(l)(Ident)(() => Ident(x))(s).value
  }
}
const getI = (l, s) => {
  switch (typeof l) {
    case "string": return getProp(l, s)
    case "number": return getIndex(l, s)
    default:       return lifted(l)(Const)(Const)(s).value
  }
}
const modifyI = (l, x2x, s) => {
  switch (typeof l) {
    case "string": return setProp(l, x2x(getProp(l, s)), s)
    case "number": return setIndex(l, x2x(getIndex(l, s)), s)
    default:       return lifted(l)(Ident)(y => Ident(x2x(y)))(s).value
  }
}
const lensI = (getter, setter) => _c => inner => target =>
  inner(getter(target)).map(focus => setter(focus, target))
const collectI = (l, s) => l(Const)(Single)(s).value

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const collect = curry2((l, s) =>
  warn("`collect` is experimental and might be removed, renamed or changed semantically before next major release") ||
  mkArray(filtered(collectI(lift(l), s))))

export const chain = curry2((x2yL, xL) =>
  compose(xL, choose(xO => xO === undefined ? nothing : x2yL(xO))))

export const just = x => lensI(R.always(x), snd)

export const choose = x2yL => constructor => inner => target =>
  lift(x2yL(target))(constructor)(inner)(target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => R.equals(x, inn) ? out : x
const normalizer = fn => _c => inner => x => inner(fn(x)).map(fn)

export const replace = curry2((inn, out) => _c => inner => x =>
  inner(replacer(inn, out)(x)).map(replacer(out, inn)))

export const defaults = out => _c => inner => x =>
  inner(x === undefined ? out : x).map(replacer(out, undefined))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x === undefined ? v : x)

export const valueOr = v => _c => inner => x =>
  inner(x === undefined || x === null ? v : x)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) => {
  const oOut = isObject(o) ? o : empty
  return v === undefined ? deleteKey(k, oOut) : setKey(k, v, oOut)
}
const liftProp = k => _c => inner => o =>
  inner(getProp(k, o)).map(v => setProp(k, v, o))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export const findWith = (...ls) => {
  const lls = lift(compose(...ls))
  return compose(find(x => getI(lls, x) !== undefined), lls)
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
const setIndex = (i, x, xs) => {
  if (x === undefined) {
    if (!isArray(xs))
      return undefined
    if (xs.length <= i)
      return dropped(xs)
    const ys = xs.slice(0)
    ys.splice(i, 1)
    return dropped(ys)
  } else {
    if (!isArray(xs))
      return Array(i).concat([x])
    if (xs.length <= i)
      return xs.concat(Array(i - xs.length), [x])
    const ys = xs.slice(0)
    ys[i] = x
    return ys
  }
}
const liftIndex = i => _c => inner => xs =>
  inner(getIndex(i, xs)).map(x => setIndex(i, x, xs))

export const append = lensI(snd, (x, xs) =>
  x === undefined ? unArray(xs) : isArray(xs) ? xs.concat([x]) : [x])

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  dropped(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : empty
      let z
      const set = (k, v) => {
        if (undefined === z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

export const pick = template => lensI(
  c => {
    let r
    for (const k in template) {
      const v = getI(template[k], c)
      if (v !== undefined) {
        if (r === undefined)
          r = {}
        r[k] = v
      }
    }
    return r
  },
  (o = empty, cIn) => {
    let c = cIn
    for (const k in template)
      c = setI(template[k], o[k], c)
    return c
  })

export const identity = _c => inner => inner

export const props = (...ks) => pick(R.zipObj(ks, ks))

const show = (...labels) => x => console.log(...labels, x) || x

export const log = (...labels) =>
  lensI(show(...labels, "get"), show(...labels, "set"))

export const sequence = constructor => inner => target =>
  warn("`sequence` is experimental and might be removed, renamed or changed semantically before next major release") ||
  R.traverse(constructor, inner, mkArray(target))
  .map(filtered)

export const optional =
  compose(lensI(toPartial(x => [x]),
                toPartial(([x]) => x)),
          sequence)

export const fromRamda = l => _c => l
const fantasy = () => {throw new Error("Sorry, `toRamda` is only fantasy!")}
export const toRamda = l => lift(l)(fantasy)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}
      for (let i=0, n=xs.length; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? R.values(o) : undefined)

export default compose
<commit_msg>Minor opt<commit_after>import * as R from "ramda"

//

function Identity(value) {this.value = value}
const Ident = x => new Identity(x)
Identity.prototype.map = function (x2y) {return new Identity(x2y(this.value))}
Identity.prototype.of = Ident
Identity.prototype.ap = function (x) {return new Identity(this.value(x.value))}

//

function Constant(value) {this.value = value}
const Const = x => new Constant(x)
const Single = x => Const([x])
Constant.prototype.map = function () {return this}
Constant.prototype.of = Const
Constant.prototype.ap = function (x) {return new Const(R.concat(this.value, x.value))}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const curry2 = fn => function (a, b) {
  switch (arguments.length) {
    case 1:  return b => fn(a, b)
    default: return fn(a, b)
  }
}

const curry3 = fn => function (a, b, c) {
  switch (arguments.length) {
    case 1:  return curry2((b, c) => fn(a, b, c))
    case 2:  return c => fn(a, b, c)
    default: return fn(a, b, c)
  }
}

//

const isArray  = x => x && x.constructor === Array
const isObject = x => x && x.constructor === Object

const unArray  = x =>  isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : []

//

const id = x => x
const snd = (_, c) => c

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const dropped = xs => {
  for (const _ in xs)
    return xs
  return undefined
}

//

const empty = {}

const deleteKey = (k, o) => {
  const r = Object.assign({}, o)
  delete r[k]
  return dropped(r)
}

const setKey = (k, v, o) => {
  const r = Object.assign({}, o)
  r[k] = v
  return r
}

//

const toPartial = transform => x => undefined === x ? x : transform(x)

//

const filtered = toPartial(xs => dropped(xs.filter(x => x !== undefined)))

//

const seemsLens = x => typeof x === "function" && x.length === 1

const lifted = assert("a lens", seemsLens)

const lift = l => {
  switch (typeof l) {
    case "string": return liftProp(l)
    case "number": return liftIndex(l)
    default:       return lifted(l)
  }
}

export function compose() {
  switch (arguments.length) {
    case 0:  return identity
    case 1:  return arguments[0]
    default: return toCat => x => {
      let i = arguments.length
      let r = lift(arguments[--i])(toCat)(x)
      do {
        r = lift(arguments[--i])(toCat)(r)
      } while (0 < i)
      return r
    }
  }
}

export const removeAll = curry2((lens, data) => {
  warn("`removeAll` is deprecated and will be removed in next major version --- use a different approach.")
  while (get(lens, data) !== undefined)
    data = remove(lens, data)
  return data
})

const setI = (l, x, s) => {
  switch (typeof l) {
    case "string": return setProp(l, x, s)
    case "number": return setIndex(l, x, s)
    default:       return lifted(l)(Ident)(() => Ident(x))(s).value
  }
}
const getI = (l, s) => {
  switch (typeof l) {
    case "string": return getProp(l, s)
    case "number": return getIndex(l, s)
    default:       return lifted(l)(Const)(Const)(s).value
  }
}
const modifyI = (l, x2x, s) => {
  switch (typeof l) {
    case "string": return setProp(l, x2x(getProp(l, s)), s)
    case "number": return setIndex(l, x2x(getIndex(l, s)), s)
    default:       return lifted(l)(Ident)(y => Ident(x2x(y)))(s).value
  }
}
const lensI = (getter, setter) => _c => inner => target =>
  inner(getter(target)).map(focus => setter(focus, target))
const collectI = (l, s) => l(Const)(Single)(s).value

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const collect = curry2((l, s) =>
  warn("`collect` is experimental and might be removed, renamed or changed semantically before next major release") ||
  mkArray(filtered(collectI(lift(l), s))))

export const chain = curry2((x2yL, xL) =>
  compose(xL, choose(xO => xO === undefined ? nothing : x2yL(xO))))

export const just = x => lensI(R.always(x), snd)

export const choose = x2yL => constructor => inner => target =>
  lift(x2yL(target))(constructor)(inner)(target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => R.equals(x, inn) ? out : x
const normalizer = fn => _c => inner => x => inner(fn(x)).map(fn)

export const replace = curry2((inn, out) => _c => inner => x =>
  inner(replacer(inn, out)(x)).map(replacer(out, inn)))

export const defaults = out => _c => inner => x =>
  inner(x === undefined ? out : x).map(replacer(out, undefined))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x === undefined ? v : x)

export const valueOr = v => _c => inner => x =>
  inner(x === undefined || x === null ? v : x)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) => {
  const oOut = isObject(o) ? o : empty
  return v === undefined ? deleteKey(k, oOut) : setKey(k, v, oOut)
}
const liftProp = k => _c => inner => o =>
  inner(getProp(k, o)).map(v => setProp(k, v, o))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export const findWith = (...ls) => {
  const lls = lift(compose(...ls))
  return compose(find(x => getI(lls, x) !== undefined), lls)
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
const setIndex = (i, x, xs) => {
  if (x === undefined) {
    if (!isArray(xs))
      return undefined
    if (xs.length <= i)
      return dropped(xs)
    const ys = xs.slice(0)
    ys.splice(i, 1)
    return dropped(ys)
  } else {
    if (!isArray(xs))
      return Array(i).concat([x])
    if (xs.length <= i)
      return xs.concat(Array(i - xs.length), [x])
    const ys = xs.slice(0)
    ys[i] = x
    return ys
  }
}
const liftIndex = i => _c => inner => xs =>
  inner(getIndex(i, xs)).map(x => setIndex(i, x, xs))

export const append = lensI(snd, (x, xs) =>
  x === undefined ? unArray(xs) : isArray(xs) ? xs.concat([x]) : [x])

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  dropped(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : empty
      let z
      const set = (k, v) => {
        if (undefined === z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

export const pick = template => lensI(
  c => {
    let r
    for (const k in template) {
      const v = getI(template[k], c)
      if (v !== undefined) {
        if (r === undefined)
          r = {}
        r[k] = v
      }
    }
    return r
  },
  (o = empty, cIn) => {
    let c = cIn
    for (const k in template)
      c = setI(template[k], o[k], c)
    return c
  })

export const identity = _c => inner => inner

export const props = (...ks) => pick(R.zipObj(ks, ks))

const show = (...labels) => x => console.log(...labels, x) || x

export const log = (...labels) =>
  lensI(show(...labels, "get"), show(...labels, "set"))

export const sequence = constructor => inner => target =>
  warn("`sequence` is experimental and might be removed, renamed or changed semantically before next major release") ||
  R.traverse(constructor, inner, mkArray(target))
  .map(filtered)

export const optional =
  compose(lensI(toPartial(x => [x]),
                toPartial(([x]) => x)),
          sequence)

export const fromRamda = l => _c => l
const fantasy = () => {throw new Error("Sorry, `toRamda` is only fantasy!")}
export const toRamda = l => lift(l)(fantasy)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}
      for (let i=0, n=xs.length; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? R.values(o) : undefined)

export default compose
<|endoftext|>


<commit_before>import React from 'react';
import {isObject, isArray, cloneDeep} from 'lodash';
import {Map} from immutable;
import Footer from 'Footer';
import HeaderContainer from 'HeaderContainer';
import CellContainer from 'CellContainer';

export default class Sprd extends React.Component {

  static defaultProps = {
    data: null, //data is in format {header1: [value1, value2], header2: [value3, value4]}
    config:{
      showHeaderLetters: true, //show the letters at top A, B, C ... AA, AB
      showRowNumbers: true,
      showFormulaBar: true,
      showFooter: true,
      autoGrow: false, //grow the spreadsheet as the user scrolls
      defaultNumRows: 20, //in case no data is specified
      defaultNumCols: 10 //in case no data is specified
      components: { //override components

      }
    }
  }

  constructor(props){
    super(props);
    if(this.props.data){
      this.parseData();
    } else {
      console.warn('No valid data passed to Sprd');
    }
  }

  //data is reorganized into format {header1: [], header2: [], ...}
  parseData(){
    if(isObject(this.props.data)){
      let data = Map(this.props.data); //avoid modifying the original data
      this.setState({data: data, headers: Object.keys(this.props.data)});
    } else if(this.props.data === null){

    } else {
      console.warn("Unrecognized object passed into Sprd as data");
    }
  }

  static getComponent(name){
    let components = this.props.config.components;
    if(components){
      components[name];
    }
  }

  render(){
    if(!this.props.data) return;
    let HeaderContainer =
    return (

        <HeaderContainer
          headers={headers}
          showFormulaBar={this.props.showFormulaBar}
          showHeaderLetters={this.props.showHeaderLetters}/>
        <CellContainer data={this.state.data}/>

    )
  }
}<commit_msg>store data in an easy to query structure<commit_after>import React from 'react';
import {isObject, isArray, cloneDeep} from 'lodash';
import {Map} from immutable;
import Footer from 'Footer';
import HeaderContainer from 'HeaderContainer';
import CellContainer from 'CellContainer';

export default class Sprd extends React.Component {

  static defaultProps = {
    data: null, //data is in format {header1: [value1, value2], header2: [value3, value4]}
    config:{
      showHeaderLetters: true, //show the letters at top A, B, C ... AA, AB
      firstRowIsHeaders: false,
      showRowNumbers: true,
      showFormulaBar: true,
      showFooter: true,
      autoGrow: false, //grow the spreadsheet as the user scrolls
      defaultNumRows: 20, //in case no data is specified
      defaultNumCols: 10 //in case no data is specified
      components: { //override components

      }
    }
  }

  constructor(props){
    super(props);
    if(this.props.data){
      this.parseData();
    } else {
      console.warn('No valid data passed to Sprd');
    }
    this.state = {
      data: {},
      maxRow: this.props.defaultNumRows,
      maxCol: this.props.defaultNumCols
    };
    this.EMPTY_VALUES = {null: null, undefined: undefined}; //what we consider empty
  }

  parseData(){
    if(isObject(this.props.data)){
      let data = {};
      let headers = Object.keys(this.props.data); //there is no guarantee for header order
      for(let col = 0, row = 0; col < headers.length; col++){
        let headerData = this.props.data[headers[col]];
        if(!data[row]) data[row] = {};

        if(this.EMPTY_VALUES[headerData[row]] === headerData[row])//we don't store empty values
        else data[row][col] = headerData[row];

        if(col == headers.length){
          col = 0;
          row++;
        }
        if(row == headerData.length) break;
      }
      this.setState({data: data, headers: headers});

    } else if(!this.props.data){
      //build an empty spreadsheet
    } else {
      console.warn("Unrecognized object passed into Sprd as data");
    }
  }

  static getComponent(name){
    let components = this.props.config.components;
    if(components){
      components[name];
    }
  }

  render(){
    return (

        <HeaderContainer
          headers={this.state.headers}
          firstRowIsHeaders={this.props.firstRowIsHeaders}
          showFormulaBar={this.props.showFormulaBar}
          showHeaderLetters={this.props.showHeaderLetters}/>
        <CellContainer data={this.state.data}/>

    )
  }
}<|endoftext|>


<commit_before>ConductorSpace.MainView = Backbone.View.extend({

  events: {
    'touchend .color' : 'sendColor',
    'touchend .random' : 'sendRandomColor',
    'change #fader' : 'updateFadeTime',
    'click #toggleSound' : 'toggleSound',
    'click #toggleMotion' : 'toggleMotion',
    'click #toggleStrobe' : 'toggleStrobe',
    'click #toggleAudioLights' : 'toggleAudioLights'
  },

  initialize: function() {
    this.template = this.model.get('templates')['mainView'];
    this.fadeTime = 1500;
  },

  render: function() {
    this.$el.html(this.template());
    return this;
  },

  updateFadeTime: function(e) {
    this.fadeTime = e.target.value;
    var rounded = this.fadeTime / 1000;
    rounded = rounded.toFixed(1);
    $('#fadeTimeText').text('FADE: ' + rounded + ' Seconds');
    this.model.sendNewFadeTime(this.fadeTime);
  },

  sendColor: function(e) {
    var color = e.target.dataset.color;
    this.model.sendColor(color, this.fadeTime);
  },

  sendRandomColor: function(e) {
    var colorOptions = { color: ["#CC0000","#FFFFFF","#00CC00","#0000CC","#B5FC9B","#9BDAFC","#F50FF1","#F5AC0F","#FFE203","#000000", "#AA84E0", "#7A0014"] };
    this.model.randomColor(colorOptions, this.fadeTime);
  },

  toggleSound: function() {
    this.model.toggleSound();
  },

  toggleMotion: function() {
    this.model.toggleMotion();
  },

  toggleStrobe: function() {
    this.model.toggleStrobe();
  },

  toggleAudioLights: function() {
    if (this.model.get('audioLightControl')) {
      $('.audioControlled').removeAttr('disabled');
      $('.audioControlled').css('opacity', '1.0');
    } else {
      $('.audioControlled').prop('disabled', 'disabled');
      $('.audioControlled').css('opacity', '0.7');
      if (this.model.get('strobe')) {
        this.model.toggleStrobe();
      }
    }
    this.model.toggleAudioLights();
  }

});<commit_msg>Click -> touchend in MC events<commit_after>ConductorSpace.MainView = Backbone.View.extend({

  events: {
    'touchend .color' : 'sendColor',
    'touchend .random' : 'sendRandomColor',
    'change #fader' : 'updateFadeTime',
    'touchend #toggleSound' : 'toggleSound',
    'touchend #toggleMotion' : 'toggleMotion',
    'touchend #toggleStrobe' : 'toggleStrobe',
    'touchend #toggleAudioLights' : 'toggleAudioLights'
  },

  initialize: function() {
    this.template = this.model.get('templates')['mainView'];
    this.fadeTime = 1500;
  },

  render: function() {
    this.$el.html(this.template());
    return this;
  },

  updateFadeTime: function(e) {
    this.fadeTime = e.target.value;
    var rounded = this.fadeTime / 1000;
    rounded = rounded.toFixed(1);
    $('#fadeTimeText').text('FADE: ' + rounded + ' Seconds');
    this.model.sendNewFadeTime(this.fadeTime);
  },

  sendColor: function(e) {
    var color = e.target.dataset.color;
    this.model.sendColor(color, this.fadeTime);
  },

  sendRandomColor: function(e) {
    var colorOptions = { color: ["#CC0000","#FFFFFF","#00CC00","#0000CC","#B5FC9B","#9BDAFC","#F50FF1","#F5AC0F","#FFE203","#000000", "#AA84E0", "#7A0014"] };
    this.model.randomColor(colorOptions, this.fadeTime);
  },

  toggleSound: function() {
    this.model.toggleSound();
  },

  toggleMotion: function() {
    this.model.toggleMotion();
  },

  toggleStrobe: function() {
    this.model.toggleStrobe();
  },

  toggleAudioLights: function() {
    if (this.model.get('audioLightControl')) {
      $('.audioControlled').removeAttr('disabled');
      $('.audioControlled').css('opacity', '1.0');
    } else {
      $('.audioControlled').prop('disabled', 'disabled');
      $('.audioControlled').css('opacity', '0.7');
      if (this.model.get('strobe')) {
        this.model.toggleStrobe();
      }
    }
    this.model.toggleAudioLights();
  }

});<|endoftext|>


<commit_before>function patternAdapter(oboeBus, jsonPathCompiler) {

   var predicateEventMap = {
      node:oboeBus(NODE_FOUND)
   ,  path:oboeBus(PATH_FOUND)
   };

   function addUnderlyingListener( fullEventName, predicateEvent, pattern ){

      var compiledJsonPath = jsonPathCompiler( pattern ),
          fullEvent = oboeBus(fullEventName);

      predicateEvent.on( function (ascent) {

         var maybeMatchingMapping = compiledJsonPath(ascent);

         /* Possible values for maybeMatchingMapping are now:

          false:
          we did not match

          an object/array/string/number/null:
          we matched and have the node that matched.
          Because nulls are valid json values this can be null.

          undefined:
          we matched but don't have the matching node yet.
          ie, we know there is an upcoming node that matches but we
          can't say anything else about it.
          */
         if (maybeMatchingMapping !== false) {

            fullEvent.emit(nodeOf(maybeMatchingMapping), ascent);
         }
      }, fullEventName);

      oboeBus('removeListener').on( function(removedEventName){

         // if the match even listener is later removed, clean up by removing
         // the underlying listener if nothing else is using that pattern:

         if( removedEventName == fullEventName ) {

            if( !oboeBus(removedEventName).listeners(  )) {
               predicateEvent.un( fullEventName );
            }
         }
      });
   }

   oboeBus('newListener').on( function(fullEventName){

      var match = /(node|path):(.*)/.exec(fullEventName),
          predicateEvent = match && predicateEventMap[match[1]];

      if( predicateEvent && !predicateEvent.hasListener( fullEventName) ) {

         addUnderlyingListener(
            fullEventName,
            predicateEvent,
            match[2]
         );
      }
   })

}<commit_msg>minor refactoring<commit_after>function patternAdapter(oboeBus, jsonPathCompiler) {

   var predicateEventMap = {
      node:oboeBus(NODE_FOUND)
   ,  path:oboeBus(PATH_FOUND)
   };

   function addUnderlyingListener( fullEventName, predicateEvent, compiledJsonPath ){

      var fullEvent = oboeBus(fullEventName);

      predicateEvent.on( function (ascent) {

         var maybeMatchingMapping = compiledJsonPath(ascent);

         /* Possible values for maybeMatchingMapping are now:

          false:
          we did not match

          an object/array/string/number/null:
          we matched and have the node that matched.
          Because nulls are valid json values this can be null.

          undefined:
          we matched but don't have the matching node yet.
          ie, we know there is an upcoming node that matches but we
          can't say anything else about it.
          */
         if (maybeMatchingMapping !== false) {

            fullEvent.emit(nodeOf(maybeMatchingMapping), ascent);
         }
      }, fullEventName);

      oboeBus('removeListener').on( function(removedEventName){

         // if the match even listener is later removed, clean up by removing
         // the underlying listener if nothing else is using that pattern:

         if( removedEventName == fullEventName ) {

            if( !oboeBus(removedEventName).listeners(  )) {
               predicateEvent.un( fullEventName );
            }
         }
      });
   }

   oboeBus('newListener').on( function(fullEventName){

      var match = /(node|path):(.*)/.exec(fullEventName);

      if( match ) {
         var predicateEvent = predicateEventMap[match[1]];

         if( !predicateEvent.hasListener( fullEventName) ) {

            addUnderlyingListener(
               fullEventName,
               predicateEvent,
               jsonPathCompiler( match[2] )
            );
         }
      }
   })

}<|endoftext|>


<commit_before>'use strict';

angular.module('gameofdronesApp')
    .controller('roundGameController', ['$scope','$http','Todos', 'Util', function($scope, $http, Todos, Util) {

        $scope.gameDrones = {};
        $scope.round = {};

        var setRound = function(player){
            $scope.round.numberPlayer = Util.getNumberPlayer();
            $scope.round.namePlayer = Util.getNamePlayer();
            $scope.round.limitMovements = Util.getLimitMovements();
            $scope.round.moveType = Util.getMoveType();
            $scope.round.numberRound = Util.getNumberRound();
        };

        Util.setMoveType($scope.gameDrones.selectMove);

        var initRound = function(){
            if(!Util.getStarting()){
                Todos.get().success(function(dataPlayer) {

                    dataPlayer.forEach(function (player) {
                        if(player.number == 1){
                            Util.setNumberPlayer(player.number);
                            Util.setNamePlayer(player.name);
                            Util.setLimitMovements(3);
                            Util.setNumberRound(1);
                        }
                    });

                });

                setRound();
            }else{
                setRound(Util);
            }

            $scope.loading = false;
        }

        initRound();

}]);
<commit_msg>Added new validations<commit_after>'use strict';

angular.module('gameofdronesApp')
    .controller('roundGameController', ['$scope','$http','Todos', 'Util', function($scope, $http, Todos, Util) {

        $scope.gameDrones = {};
        $scope.round = {};

        var setRound = function(player){
            $scope.round.numberPlayer = Util.getNumberPlayer();
            $scope.round.namePlayer = Util.getNamePlayer();
            $scope.round.limitMovements = Util.getLimitMovements();
            $scope.round.moveType = Util.getMoveType();
            $scope.round.numberRound = Util.getNumberRound();
        };

        Util.setMoveType($scope.gameDrones.selectMove);

        var initRound = function(){
            if(!Util.getStarting()){
                Todos.get().success(function(dataPlayer) {

                    dataPlayer.forEach(function (player) {
                        if(player.number == 1){
                            Util.setNumberPlayer(player.number);
                            Util.setNamePlayer(player.name);
                            Util.setLimitMovements(3);
                            Util.setNumberRound(1);
                            Util.setStarting(true);
                            setRound(Util);
                        }
                    });
                });
            }else{
                setRound(Util);
            }

            $scope.loading = false;
        }

        initRound();

}]);
<|endoftext|>


<commit_before>/*global angular, $*/
(function () {
    'use strict';
    angular.module('core').directive('ngSlideView', ['resolutions', '$rootScope', 'SlideSetup', 'resizeSenzor', '$timeout',
        function (resolutions, $rootScope, SlideSetup, resizeSenzor, $timeout) {
            var indicator = "<svg style='width:0px;height:0px;opacity:0.8;position: absolute;margin-left:0px;margin-top:0px;display:none;z-index:1000; transform: translate(-50%,-50%)'><circle cx='50%' cy='50%' r='46%' stroke='red' fill='red' fill-opacity='0.0' stroke-width='4%'></circle></svg>";

            var template = '

';
            template += "
";
            template += "

";
            template += "
LOADING...
";
            template += "
";
            template += '

';
            return {
                scope: {
                    slideWidth: "=",
                    slideHeight: "=",
                    referenceSlide: "=",
                    isPlaying: "=",
                    emitSlideLoadedEvent: "="
                },
                template: template,
                link: function (scope, element, attrs) {
                    var templateLoaded = false;
                    scope.loadedScripts = [];
                    scope.slideLoaded = false;
                    scope.indicatorVisible = false;
                    scope.indicatorSize = 0;
                    scope.slideReady = false;
                    var appliedScale = 1;
                    var getSizeMeasurementContainer = function () {
                        var container = $("#measurementContainer");
                        if (container.length) {
                            return container;
                        }
                        return $("body").append(measurementContainer);
                    }

                    var zoomContentToElement = function () {
                        var elementToScale = element.find(".toBeScaled");
                        var parent = elementToScale.parent();

                        if (elementToScale.width()==0 || elementToScale.height() == 0)  {
                            return;
                        }

                        var sx = parent.width() / elementToScale.width();
                        var sy = parent.height() / elementToScale.height();
                        var scale = Math.min(sx, sy);

                        elementToScale.css("transform", "scale(" + scale + ") translate(-50%, -50%)");
                    }

                    var scaleElementToResolution = function () {
                        if (scope.emitSlideLoadedEvent === true) {
                            scope.$emit("slideLoadedInSlideView");
                        }
                        if (!scope.referenceSlide) {
                            return;
                        }
                        scope.resolution = scope.referenceSlide.resolution || resolutions[0];
                        scope.zoomPercent = scope.referenceSlide.zoomPercent || 100;
                        scope.indicatorSize = Math.max(scope.resolution.width, scope.resolution.height) * 10 / 100;

                        var sx = element.parent().width() / scope.resolution.width;
                        var sy = element.parent().height() / scope.resolution.height;
                        var appliedScale = Math.min(sx, sy);

                        element.find(".slideshow-placeholder").css("transform", "scale(" + appliedScale + ") translate(-50%, -50%)");
                        zoomContentToElement();
                        scope.slideReady = true;
                    };

                    var lastTimeout;
                    var update = function () {
                        window.clearTimeout(lastTimeout);
                        if (scope.slideConfiguration && scope.slideConfiguration.onUpdate) {
                            scope.slideConfiguration.onUpdate(function () {
                                lastTimeout = window.setTimeout(scaleElementToResolution, 10);
                            }, element.find(".ng-slide-view").children().first());
                            return;
                        }

                        lastTimeout = window.setTimeout(scaleElementToResolution, 10);
                    };

                    var contentResizeSenzorDestroy = resizeSenzor(element.find(".toBeScaled")[0], update);
                    var parentResizeSenzorDestroy = resizeSenzor(element.find(".slide-content-container")[0], update);

                    scope.onSlideClicked = function (event) {
                        var pageX = 0;
                        var pageY = 0;
                        if (event.originalEvent.touches && event.originalEvent.touches.length > 0) {
                            pageX = event.originalEvent.touches[0].pageX;
                            pageY = event.originalEvent.touches[0].pageY;
                        } else {
                            pageX = event.originalEvent.pageX;
                            pageY = event.originalEvent.pageY;
                        }
                        var target = $(event.currentTarget);

                        var x = pageX - target.offset().left;
                        var y = pageY - target.offset().top;

                        var percentX = x * 100 / (scope.resolution.width * appliedScale);
                        var percentY = y * 100 / (scope.resolution.height * appliedScale);

                        $rootScope.$broadcast("slideShowClicked", {percentX : percentX, percentY : percentY});
                    };

                    scope.$watch("referenceSlide", function (newValue, oldValue) {
                        SlideSetup.setup(scope, element);
                    });
                    scope.$watch("referenceSlide.resolution", function (newValue, oldValue) {
                        if (!scope.isPlaying) {
                            update();
                        }
                    });
                    scope.$watch("referenceSlide.zoomPercent", function (newValue, oldValue) {
                        if (!scope.isPlaying) {
                            update();
                        }
                    });

                    scope.$on("getSlideContentPart", function (event, contentPartName, callback) {
                        if (!scope.referenceSlide) {
                            return;
                        }
                        var content = scope.referenceSlide.content || {};
                        callback(content[contentPartName]);
                    });
                    scope.$on("getTemplatePath", function (event, callback) {
                        callback(scope.referencePath);
                    });

                    scope.$on("displayIndicator", function (event, position) {
                        window.setTimeout(function () {
                            var indicatorElement = $(indicator);
                            indicatorElement.css({
                                "margin-left" : ((scope.resolution.width * position.percentX) / 100) + "px",
                                "margin-top" : ((scope.resolution.height * position.percentY) / 100) + "px",
                                "display" : "block"
                            });
                            element.find('.slideshow-placeholder').append(indicatorElement);
                            indicatorElement.animate({width: scope.indicatorSize + "px", height: scope.indicatorSize + "px"}, 1000, "easeInOutElastic", function () {
                                window.setTimeout(function () {
                                    indicatorElement.animate({width: "0px", height: "0px"}, 3000, "easeInOutElastic", function () {
                                        indicatorElement.remove();
                                    });
                                }, 2000);

                            });
                        }, 10);
                    });

                    scope.$on("scriptLoaded", function (event, scriptUrl) {
                        scope.loadedScripts.push(scriptUrl);
                    });

                    scope.$on("scriptCached", function (event, scriptUrl) {
                        if (scope.loadedScripts.indexOf(scriptUrl) == -1) {
                            scope.loadedScripts.push(scriptUrl);
                        }
                    });

                    scope.$on("$destroy", function () {
                        contentResizeSenzorDestroy();
                        parentResizeSenzorDestroy();
                    });

                    scope.templateLoaded = function () {
                        if (!scope.referenceSlide) {
                            // no slide was specified, for exampel empty slideshow edit page
                            return;
                        }
                        templateLoaded = true;
                        scope.slideLoaded = true;
                        SlideSetup.loadScripts(scope, element).then(function () {
                            if (scope.referenceSlide.setupFinishedPromise) {
                                scope.referenceSlide.setupFinishedPromise.resolve();
                            }
                           $timeout(update,20);
                        });
                    };
                }
            };
        }
                                                    ]);
}());
<commit_msg>Add position relative to slide preview container.<commit_after>/*global angular, $*/
(function () {
    'use strict';
    angular.module('core').directive('ngSlideView', ['resolutions', '$rootScope', 'SlideSetup', 'resizeSenzor', '$timeout',
        function (resolutions, $rootScope, SlideSetup, resizeSenzor, $timeout) {
            var indicator = "<svg style='width:0px;height:0px;opacity:0.8;position: absolute;margin-left:0px;margin-top:0px;display:none;z-index:1000; transform: translate(-50%,-50%)'><circle cx='50%' cy='50%' r='46%' stroke='red' fill='red' fill-opacity='0.0' stroke-width='4%'></circle></svg>";

            var template = '

';
            template += "
";
            template += "

";
            template += "
LOADING...
";
            template += "
";
            template += '

';
            return {
                scope: {
                    slideWidth: "=",
                    slideHeight: "=",
                    referenceSlide: "=",
                    isPlaying: "=",
                    emitSlideLoadedEvent: "="
                },
                template: template,
                link: function (scope, element, attrs) {
                    var templateLoaded = false;
                    scope.loadedScripts = [];
                    scope.slideLoaded = false;
                    scope.indicatorVisible = false;
                    scope.indicatorSize = 0;
                    scope.slideReady = false;
                    var appliedScale = 1;
                    var getSizeMeasurementContainer = function () {
                        var container = $("#measurementContainer");
                        if (container.length) {
                            return container;
                        }
                        return $("body").append(measurementContainer);
                    }

                    var zoomContentToElement = function () {
                        var elementToScale = element.find(".toBeScaled");
                        var parent = elementToScale.parent();

                        if (elementToScale.width()==0 || elementToScale.height() == 0)  {
                            return;
                        }

                        var sx = parent.width() / elementToScale.width();
                        var sy = parent.height() / elementToScale.height();
                        var scale = Math.min(sx, sy);

                        elementToScale.css("transform", "scale(" + scale + ") translate(-50%, -50%)");
                    }

                    var scaleElementToResolution = function () {
                        if (scope.emitSlideLoadedEvent === true) {
                            scope.$emit("slideLoadedInSlideView");
                        }
                        if (!scope.referenceSlide) {
                            return;
                        }
                        scope.resolution = scope.referenceSlide.resolution || resolutions[0];
                        scope.zoomPercent = scope.referenceSlide.zoomPercent || 100;
                        scope.indicatorSize = Math.max(scope.resolution.width, scope.resolution.height) * 10 / 100;

                        var sx = element.parent().width() / scope.resolution.width;
                        var sy = element.parent().height() / scope.resolution.height;
                        var appliedScale = Math.min(sx, sy);

                        element.find(".slideshow-placeholder").css("transform", "scale(" + appliedScale + ") translate(-50%, -50%)");
                        zoomContentToElement();
                        scope.slideReady = true;
                    };

                    var lastTimeout;
                    var update = function () {
                        window.clearTimeout(lastTimeout);
                        if (scope.slideConfiguration && scope.slideConfiguration.onUpdate) {
                            scope.slideConfiguration.onUpdate(function () {
                                lastTimeout = window.setTimeout(scaleElementToResolution, 10);
                            }, element.find(".ng-slide-view").children().first());
                            return;
                        }

                        lastTimeout = window.setTimeout(scaleElementToResolution, 10);
                    };

                    var contentResizeSenzorDestroy = resizeSenzor(element.find(".toBeScaled")[0], update);
                    var parentResizeSenzorDestroy = resizeSenzor(element.find(".slide-content-container")[0], update);

                    scope.onSlideClicked = function (event) {
                        var pageX = 0;
                        var pageY = 0;
                        if (event.originalEvent.touches && event.originalEvent.touches.length > 0) {
                            pageX = event.originalEvent.touches[0].pageX;
                            pageY = event.originalEvent.touches[0].pageY;
                        } else {
                            pageX = event.originalEvent.pageX;
                            pageY = event.originalEvent.pageY;
                        }
                        var target = $(event.currentTarget);

                        var x = pageX - target.offset().left;
                        var y = pageY - target.offset().top;

                        var percentX = x * 100 / (scope.resolution.width * appliedScale);
                        var percentY = y * 100 / (scope.resolution.height * appliedScale);

                        $rootScope.$broadcast("slideShowClicked", {percentX : percentX, percentY : percentY});
                    };

                    scope.$watch("referenceSlide", function (newValue, oldValue) {
                        SlideSetup.setup(scope, element);
                    });
                    scope.$watch("referenceSlide.resolution", function (newValue, oldValue) {
                        if (!scope.isPlaying) {
                            update();
                        }
                    });
                    scope.$watch("referenceSlide.zoomPercent", function (newValue, oldValue) {
                        if (!scope.isPlaying) {
                            update();
                        }
                    });

                    scope.$on("getSlideContentPart", function (event, contentPartName, callback) {
                        if (!scope.referenceSlide) {
                            return;
                        }
                        var content = scope.referenceSlide.content || {};
                        callback(content[contentPartName]);
                    });
                    scope.$on("getTemplatePath", function (event, callback) {
                        callback(scope.referencePath);
                    });

                    scope.$on("displayIndicator", function (event, position) {
                        window.setTimeout(function () {
                            var indicatorElement = $(indicator);
                            indicatorElement.css({
                                "margin-left" : ((scope.resolution.width * position.percentX) / 100) + "px",
                                "margin-top" : ((scope.resolution.height * position.percentY) / 100) + "px",
                                "display" : "block"
                            });
                            element.find('.slideshow-placeholder').append(indicatorElement);
                            indicatorElement.animate({width: scope.indicatorSize + "px", height: scope.indicatorSize + "px"}, 1000, "easeInOutElastic", function () {
                                window.setTimeout(function () {
                                    indicatorElement.animate({width: "0px", height: "0px"}, 3000, "easeInOutElastic", function () {
                                        indicatorElement.remove();
                                    });
                                }, 2000);

                            });
                        }, 10);
                    });

                    scope.$on("scriptLoaded", function (event, scriptUrl) {
                        scope.loadedScripts.push(scriptUrl);
                    });

                    scope.$on("scriptCached", function (event, scriptUrl) {
                        if (scope.loadedScripts.indexOf(scriptUrl) == -1) {
                            scope.loadedScripts.push(scriptUrl);
                        }
                    });

                    scope.$on("$destroy", function () {
                        contentResizeSenzorDestroy();
                        parentResizeSenzorDestroy();
                    });

                    scope.templateLoaded = function () {
                        if (!scope.referenceSlide) {
                            // no slide was specified, for exampel empty slideshow edit page
                            return;
                        }
                        templateLoaded = true;
                        scope.slideLoaded = true;
                        SlideSetup.loadScripts(scope, element).then(function () {
                            if (scope.referenceSlide.setupFinishedPromise) {
                                scope.referenceSlide.setupFinishedPromise.resolve();
                            }
                           $timeout(update,20);
                        });
                    };
                }
            };
        }
                                                    ]);
}());
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import idgen from './idgen';
import cx from 'classnames';

import Row from './Row';
import Col from './Col';

class Tabs extends Component {
  constructor(props) {
    super(props);
    this.scope = `${idgen()}`;
  }
  componentDidMount() {
    const { tabOptions = {} } = this.props;

    if (typeof $ !== 'undefined') {
      $(this._tabsEl).tabs(tabOptions);
    }
  }

  _onSelect(idx, e) {
    const { onChange } = this.props;

    if (onChange) onChange(idx, e);
  }

  componentDidUpdate() {
    const { tabOptions = {} } = this.props;

    if (typeof $ !== 'undefined') {
      $(this._tabsEl).tabs(tabOptions);
    }
  }

  componentWillUnmount() {
    if (typeof $ !== 'undefined') {
      console.log('destroy');
      $(this._tabsEl).tabs('destroy');
    }
  }

  render() {
    const { children, className, defaultValue } = this.props;
    return (
      <Row>
        <Col s={12}>

 (this._tabsEl = el)}>
            {React.Children.map(children, (child, id) => {
              const idx = `${this.scope}${id}`;
              const {
                active,
                className,
                disabled,
                tabWidth,
                title
              } = child.props;

              const classes = {
                [`s${tabWidth}`]: tabWidth,
                tab: true,
                disabled,
                col: true
              };

              return (

                  <a
                    href={`#tab_${idx}`}
                    className={active || defaultValue === idx ? 'active' : ''}
                    {...(disabled
                      ? {}
                      : { onClick: this._onSelect.bind(this, idx) })}
                  >
                    {title}

              );
            })}

        </Col>
        {React.Children.map(children, (child, id) => {
          const idx = `${this.scope}${id}`;
          return (
            <Col
              id={`tab_${idx}`}
              s={12}
              key={`tab${idx}`}
              style={{
                display:
                  child.props.active || defaultValue === idx ? 'block' : 'none'
              }}
            >
              {child.props.children}
            </Col>
          );
        })}
      </Row>
    );
  }
}

Tabs.propTypes = {
  children: PropTypes.node.isRequired,
  className: PropTypes.string,
  defaultValue: PropTypes.string,
  onChange: PropTypes.func,
  /*
   * More info
   * http://materializecss.com/tabs.html
   */
  tabOptions: PropTypes.shape({
    /*
     * Transition duration in milliseconds.
     * @default 300
     */
    duration: PropTypes.number,
    /*
     * Callback for when a new tab content is showns.
     * @default null
     */
    onShow: PropTypes.func,
    /*
     * Set to true to enable swipeable tabs. This also uses the responsiveThreshold option.
     * @default false
     */
    swipeable: PropTypes.bool,
    /*
     * The maximum width of the screen, in pixels, where the swipeable functionality initializes.
     * @default Infinity
     */
    responsiveThreshold: PropTypes.number
  })
};

export default Tabs;
<commit_msg>Removed console.log and unneeded check<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import idgen from './idgen';
import cx from 'classnames';

import Row from './Row';
import Col from './Col';

class Tabs extends Component {
  constructor(props) {
    super(props);
    this.scope = `${idgen()}`;
  }
  componentDidMount() {
    const { tabOptions = {} } = this.props;

    if (typeof $ !== 'undefined') {
      $(this._tabsEl).tabs(tabOptions);
    }
  }

  _onSelect(idx, e) {
    const { onChange } = this.props;

    if (onChange) onChange(idx, e);
  }

  componentDidUpdate() {
    const { tabOptions = {} } = this.props;

    if (typeof $ !== 'undefined') {
      $(this._tabsEl).tabs(tabOptions);
    }
  }

  componentWillUnmount() {
    $(this._tabsEl).tabs('destroy');
  }

  render() {
    const { children, className, defaultValue } = this.props;
    return (
      <Row>
        <Col s={12}>

 (this._tabsEl = el)}>
            {React.Children.map(children, (child, id) => {
              const idx = `${this.scope}${id}`;
              const {
                active,
                className,
                disabled,
                tabWidth,
                title
              } = child.props;

              const classes = {
                [`s${tabWidth}`]: tabWidth,
                tab: true,
                disabled,
                col: true
              };

              return (

                  <a
                    href={`#tab_${idx}`}
                    className={active || defaultValue === idx ? 'active' : ''}
                    {...(disabled
                      ? {}
                      : { onClick: this._onSelect.bind(this, idx) })}
                  >
                    {title}

              );
            })}

        </Col>
        {React.Children.map(children, (child, id) => {
          const idx = `${this.scope}${id}`;
          return (
            <Col
              id={`tab_${idx}`}
              s={12}
              key={`tab${idx}`}
              style={{
                display:
                  child.props.active || defaultValue === idx ? 'block' : 'none'
              }}
            >
              {child.props.children}
            </Col>
          );
        })}
      </Row>
    );
  }
}

Tabs.propTypes = {
  children: PropTypes.node.isRequired,
  className: PropTypes.string,
  defaultValue: PropTypes.string,
  onChange: PropTypes.func,
  /*
   * More info
   * http://materializecss.com/tabs.html
   */
  tabOptions: PropTypes.shape({
    /*
     * Transition duration in milliseconds.
     * @default 300
     */
    duration: PropTypes.number,
    /*
     * Callback for when a new tab content is showns.
     * @default null
     */
    onShow: PropTypes.func,
    /*
     * Set to true to enable swipeable tabs. This also uses the responsiveThreshold option.
     * @default false
     */
    swipeable: PropTypes.bool,
    /*
     * The maximum width of the screen, in pixels, where the swipeable functionality initializes.
     * @default Infinity
     */
    responsiveThreshold: PropTypes.number
  })
};

export default Tabs;
<|endoftext|>


<commit_before>import { app, BrowserWindow, Menu, shell } from 'electron';
import { IPC_DISPATCH_ACTION, IPC_MIDDLEWARE_READY } from './shared/messages'
import { tapAssertDone } from './app/actions'

let menu;
let template;
let mainWindow = null;
let rendererEndpoint

ipcMain.on(IPC_MIDDLEWARE_READY, (event, arg) => {
  rendererEndpoint = event.sender
  // POC that should dispatch some tap assertion objects
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: true,
    id: '1',
    diag: null
  }))
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: false,
    id: '2',
    diag: null
  }))
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: true,
    id: '3',
    diag: null
  }))
})

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')(); // eslint-disable-line global-require
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

const installExtensions = async () => {
  if (process.env.NODE_ENV === 'development') {
    const installer = require('electron-devtools-installer'); // eslint-disable-line global-require

    const extensions = [
      'REACT_DEVELOPER_TOOLS',
      'REDUX_DEVTOOLS'
    ];
    const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
    for (const name of extensions) {
      try {
        await installer.default(installer[name], forceDownload);
      } catch (e) {} // eslint-disable-line
    }
  }
};

app.on('ready', async () => {
  await installExtensions();

  mainWindow = new BrowserWindow({
    show: false,
    width: 1024,
    height: 728
  });

  mainWindow.loadURL(`file://${__dirname}/app/app.html`);

  mainWindow.webContents.on('did-finish-load', () => {
    mainWindow.show();
    mainWindow.focus();
  });

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools();
    mainWindow.webContents.on('context-menu', (e, props) => {
      const { x, y } = props;

      Menu.buildFromTemplate([{
        label: 'Inspect element',
        click() {
          mainWindow.inspectElement(x, y);
        }
      }]).popup(mainWindow);
    });
  }

  if (process.platform === 'darwin') {
    template = [{
      label: 'Electron',
      submenu: [{
        label: 'About ElectronReact',
        selector: 'orderFrontStandardAboutPanel:'
      }, {
        type: 'separator'
      }, {
        label: 'Services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        label: 'Hide ElectronReact',
        accelerator: 'Command+H',
        selector: 'hide:'
      }, {
        label: 'Hide Others',
        accelerator: 'Command+Shift+H',
        selector: 'hideOtherApplications:'
      }, {
        label: 'Show All',
        selector: 'unhideAllApplications:'
      }, {
        type: 'separator'
      }, {
        label: 'Quit',
        accelerator: 'Command+Q',
        click() {
          app.quit();
        }
      }]
    }, {
      label: 'Edit',
      submenu: [{
        label: 'Undo',
        accelerator: 'Command+Z',
        selector: 'undo:'
      }, {
        label: 'Redo',
        accelerator: 'Shift+Command+Z',
        selector: 'redo:'
      }, {
        type: 'separator'
      }, {
        label: 'Cut',
        accelerator: 'Command+X',
        selector: 'cut:'
      }, {
        label: 'Copy',
        accelerator: 'Command+C',
        selector: 'copy:'
      }, {
        label: 'Paste',
        accelerator: 'Command+V',
        selector: 'paste:'
      }, {
        label: 'Select All',
        accelerator: 'Command+A',
        selector: 'selectAll:'
      }]
    }, {
      label: 'View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: 'Reload',
        accelerator: 'Command+R',
        click() {
          mainWindow.webContents.reload();
        }
      }, {
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }, {
        label: 'Toggle Developer Tools',
        accelerator: 'Alt+Command+I',
        click() {
          mainWindow.toggleDevTools();
        }
      }] : [{
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }]
    }, {
      label: 'Window',
      submenu: [{
        label: 'Minimize',
        accelerator: 'Command+M',
        selector: 'performMiniaturize:'
      }, {
        label: 'Close',
        accelerator: 'Command+W',
        selector: 'performClose:'
      }, {
        type: 'separator'
      }, {
        label: 'Bring All to Front',
        selector: 'arrangeInFront:'
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click() {
          shell.openExternal('http://electron.atom.io');
        }
      }, {
        label: 'Documentation',
        click() {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
        }
      }, {
        label: 'Community Discussions',
        click() {
          shell.openExternal('https://discuss.atom.io/c/electron');
        }
      }, {
        label: 'Search Issues',
        click() {
          shell.openExternal('https://github.com/atom/electron/issues');
        }
      }]
    }];

    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
  } else {
    template = [{
      label: '&File',
      submenu: [{
        label: '&Open',
        accelerator: 'Ctrl+O'
      }, {
        label: '&Close',
        accelerator: 'Ctrl+W',
        click() {
          mainWindow.close();
        }
      }]
    }, {
      label: '&View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: '&Reload',
        accelerator: 'Ctrl+R',
        click() {
          mainWindow.webContents.reload();
        }
      }, {
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }, {
        label: 'Toggle &Developer Tools',
        accelerator: 'Alt+Ctrl+I',
        click() {
          mainWindow.toggleDevTools();
        }
      }] : [{
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click() {
          mainWindow.setFullScreen(!mainWindow.isFullScreen());
        }
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click() {
          shell.openExternal('http://electron.atom.io');
        }
      }, {
        label: 'Documentation',
        click() {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
        }
      }, {
        label: 'Community Discussions',
        click() {
          shell.openExternal('https://discuss.atom.io/c/electron');
        }
      }, {
        label: 'Search Issues',
        click() {
          shell.openExternal('https://github.com/atom/electron/issues');
        }
      }]
    }];
    menu = Menu.buildFromTemplate(template);
    mainWindow.setMenu(menu);
  }
});
<commit_msg>Linting :)<commit_after>import { app, BrowserWindow, Menu, shell, ipcMain } from 'electron'
import { IPC_DISPATCH_ACTION, IPC_MIDDLEWARE_READY } from './shared/messages'
import { tapAssertDone } from './app/actions'

let rendererEndpoint
let menu
let template
let mainWindow = null

ipcMain.on(IPC_MIDDLEWARE_READY, (event, arg) => {
  rendererEndpoint = event.sender
  // POC that should dispatch some tap assertion objects
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: true,
    id: '1',
    diag: null
  }))
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: false,
    id: '2',
    diag: null
  }))
  rendererEndpoint.send(IPC_DISPATCH_ACTION, tapAssertDone({
    ok: true,
    id: '3',
    diag: null
  }))
})

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')() // eslint-disable-line global-require
}

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

const installExtensions = async () => {
  if (process.env.NODE_ENV === 'development') {
    const installer = require('electron-devtools-installer') // eslint-disable-line global-require

    const extensions = [
      'REACT_DEVELOPER_TOOLS',
      'REDUX_DEVTOOLS'
    ]

    const forceDownload = !!process.env.UPGRADE_EXTENSIONS

    for (const name of extensions) {
      try {
        await installer.default(installer[name], forceDownload)
      } catch (e) {} // eslint-disable-line
    }
  }
}

app.on('ready', async () => {
  await installExtensions()

  mainWindow = new BrowserWindow({
    show: false,
    width: 1024,
    height: 728
  })

  mainWindow.loadURL(`file://${__dirname}/app/app.html`)

  mainWindow.webContents.on('did-finish-load', () => {
    mainWindow.show()
    mainWindow.focus()
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools()
    mainWindow.webContents.on('context-menu', (e, props) => {
      const { x, y } = props

      Menu.buildFromTemplate([{
        label: 'Inspect element',
        click () {
          mainWindow.inspectElement(x, y)
        }
      }]).popup(mainWindow)
    })
  }

  if (process.platform === 'darwin') {
    template = [{
      label: 'Electron',
      submenu: [{
        label: 'About ElectronReact',
        selector: 'orderFrontStandardAboutPanel:'
      }, {
        type: 'separator'
      }, {
        label: 'Services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        label: 'Hide ElectronReact',
        accelerator: 'Command+H',
        selector: 'hide:'
      }, {
        label: 'Hide Others',
        accelerator: 'Command+Shift+H',
        selector: 'hideOtherApplications:'
      }, {
        label: 'Show All',
        selector: 'unhideAllApplications:'
      }, {
        type: 'separator'
      }, {
        label: 'Quit',
        accelerator: 'Command+Q',
        click () {
          app.quit()
        }
      }]
    }, {
      label: 'Edit',
      submenu: [{
        label: 'Undo',
        accelerator: 'Command+Z',
        selector: 'undo:'
      }, {
        label: 'Redo',
        accelerator: 'Shift+Command+Z',
        selector: 'redo:'
      }, {
        type: 'separator'
      }, {
        label: 'Cut',
        accelerator: 'Command+X',
        selector: 'cut:'
      }, {
        label: 'Copy',
        accelerator: 'Command+C',
        selector: 'copy:'
      }, {
        label: 'Paste',
        accelerator: 'Command+V',
        selector: 'paste:'
      }, {
        label: 'Select All',
        accelerator: 'Command+A',
        selector: 'selectAll:'
      }]
    }, {
      label: 'View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: 'Reload',
        accelerator: 'Command+R',
        click () {
          mainWindow.webContents.reload()
        }
      }, {
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click () {
          mainWindow.setFullScreen(!mainWindow.isFullScreen())
        }
      }, {
        label: 'Toggle Developer Tools',
        accelerator: 'Alt+Command+I',
        click () {
          mainWindow.toggleDevTools()
        }
      }] : [{
        label: 'Toggle Full Screen',
        accelerator: 'Ctrl+Command+F',
        click () {
          mainWindow.setFullScreen(!mainWindow.isFullScreen())
        }
      }]
    }, {
      label: 'Window',
      submenu: [{
        label: 'Minimize',
        accelerator: 'Command+M',
        selector: 'performMiniaturize:'
      }, {
        label: 'Close',
        accelerator: 'Command+W',
        selector: 'performClose:'
      }, {
        type: 'separator'
      }, {
        label: 'Bring All to Front',
        selector: 'arrangeInFront:'
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click () {
          shell.openExternal('http://electron.atom.io')
        }
      }, {
        label: 'Documentation',
        click () {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme')
        }
      }, {
        label: 'Community Discussions',
        click () {
          shell.openExternal('https://discuss.atom.io/c/electron')
        }
      }, {
        label: 'Search Issues',
        click () {
          shell.openExternal('https://github.com/atom/electron/issues')
        }
      }]
    }]

    menu = Menu.buildFromTemplate(template)
    Menu.setApplicationMenu(menu)
  } else {
    template = [{
      label: '&File',
      submenu: [{
        label: '&Open',
        accelerator: 'Ctrl+O'
      }, {
        label: '&Close',
        accelerator: 'Ctrl+W',
        click () {
          mainWindow.close()
        }
      }]
    }, {
      label: '&View',
      submenu: (process.env.NODE_ENV === 'development') ? [{
        label: '&Reload',
        accelerator: 'Ctrl+R',
        click () {
          mainWindow.webContents.reload()
        }
      }, {
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click () {
          mainWindow.setFullScreen(!mainWindow.isFullScreen())
        }
      }, {
        label: 'Toggle &Developer Tools',
        accelerator: 'Alt+Ctrl+I',
        click () {
          mainWindow.toggleDevTools()
        }
      }] : [{
        label: 'Toggle &Full Screen',
        accelerator: 'F11',
        click () {
          mainWindow.setFullScreen(!mainWindow.isFullScreen())
        }
      }]
    }, {
      label: 'Help',
      submenu: [{
        label: 'Learn More',
        click () {
          shell.openExternal('http://electron.atom.io')
        }
      }, {
        label: 'Documentation',
        click () {
          shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme')
        }
      }, {
        label: 'Community Discussions',
        click () {
          shell.openExternal('https://discuss.atom.io/c/electron')
        }
      }, {
        label: 'Search Issues',
        click () {
          shell.openExternal('https://github.com/atom/electron/issues')
        }
      }]
    }]
    menu = Menu.buildFromTemplate(template)
    mainWindow.setMenu(menu)
  }
})
<|endoftext|>


<commit_before>import os from 'os'
import path from 'path'
import {app, autoUpdater, BrowserWindow, Menu, shell, ipcMain, dialog, Tray} from 'electron';
import {moveToApplications} from 'electron-lets-move';
import pkg from './package.json'
import Storage from 'electron-json-storage'
import windowStateKeeper from 'electron-window-state'

/*
* Basics
*/
let menu;
let mainWindow = null;
let settingsWindow = null;

if (process.env.NODE_ENV === 'development') {
    require('electron-debug')();
}

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});

/*
* autoUpdater
*/
let firstRun = true
const platform = os.platform() + '_' + os.arch(); // darwin_x64
const updateURL = `https://download.getcaption.co/update/${platform}/${pkg.version}`;

autoUpdater.on('checking-for-update', () => {
    console.log('Checking for updates...');
});

autoUpdater.on('update-not-available', () => {
    if (!firstRun) {
        const options = {
            type: 'info',
            buttons: ['OK'],
            title: 'Caption',
            message: `Caption is up to date`,
            detail: `It looks like you're already rocking the latest version!`
        }
        dialog.showMessageBox(options)
    }
    firstRun = false;
    console.log(`You've got the latest version.`)
})

autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) => {
    const options = {
        type: 'info',
        buttons: ['Restart', 'Later'],
        title: "Caption",
        message: `The new version has been downloaded. Please restart the application to apply the updates.`,
        detail: releaseName + "\n\n" + releaseNotes
    }
    const index = dialog.showMessageBox(options)

    if (index === 1) {
        return;
    }

    quitAndUpdate();
    firstRun = false;
});

autoUpdater.on('error', (error) => {
    console.log(error)
    firstRun = false;
});

autoUpdater.on('update-available', () => {
    console.log('update available')
    firstRun = false;

    // setInterval(() => {
    //     console.log(autoUpdater.status);
    // }, 5000);

});

try {
    autoUpdater.setFeedURL(updateURL)
    autoUpdater.checkForUpdates()
}
catch (error) {
    console.log(error)
}

/*
* Extentions
*/
const installExtensions = async () => {
    if (process.env.NODE_ENV === 'development') {
        // eslint-disable-line global-require
        const installer = require('electron-devtools-installer');

        const extensions = [
            'REACT_DEVELOPER_TOOLS',
            'REDUX_DEVTOOLS'
        ];
        const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
        for (const name of extensions) {
            try {
                await installer.default(installer[name], forceDownload);
            } catch (e) {} // eslint-disable-line
        }
    }
};

/*
* Create Main Window
*/
const createMainWindow = () => {
    let mainWindowState = windowStateKeeper({
        defaultWidth: 360,
        defaultHeight: 440
    });

    let transparent = true
    let backgroundColor = 'none'
    const osVersion = os.release().split('.').join('')

    if (osVersion < 1400) {
        transparent = false
        backgroundColor = '#474748'
    }

    // Create the windows
    mainWindow = new BrowserWindow({
        width: mainWindowState.width,
        height: mainWindowState.height,
        x: mainWindowState.x,
        y: mainWindowState.y,
        show: false,
        minWidth: 300,
        minHeight: 300,
        vibrancy: 'dark',
        transparent: transparent,
        titleBarStyle: 'hidden-inset',
        backgroundColor: backgroundColor
    });

    // Manage window state
    mainWindowState.manage(mainWindow);

    // Set URL
    mainWindow.loadURL(`file://${__dirname}/app/app.html`);

    // Events
    mainWindow.webContents.on('did-finish-load', () => {
        mainWindow.show();
        mainWindow.focus();
    });

    mainWindow.on('closed', () => {
        mainWindow = null;
        app.quit();
    });
}

app.on('ready', async () => {

    // if (process.env.NODE_ENV !== 'development') {
        /*
        * Let's Move
        */
        Storage.get('do-not-move', async (doNotMove) => {

            console.log(doNotMove)

            if (!doNotMove) {
                try {
                    const moved = await moveToApplications();

                    if (!moved) {
                        // the user asked not to move the app, it's up to the parent application
                        // to store this information and not hassle them again.
                        Storage.set('do-not-move', true);
                    }
                    else {
                        Storage.set('do-not-move', false);
                    }

                } catch (error) {
                    // log error, something went wrong whilst moving the app.
                    console.log(error);
                }
            }
        });
    // }

    await installExtensions();

    /*
    * MainWindow
    */
    createMainWindow();

    /*
    * IPC's
    */
    ipcMain.on('close-main', () => {
        mainWindow.close();
        app.quit();
    });

    ipcMain.on('lang-changed', () => {
        mainWindow.webContents.send('change-language')
    })

    /*
    * Downloads
    */
    mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
        item.on('updated', (event, state) => {
            if (state === 'interrupted') {
                console.log('Download is interrupted but can be resumed')
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    console.log('Download is paused')
                } else {
                    console.log(`Received bytes: ${item.getReceivedBytes()}`)
                }
            }
        })

        item.once('done', (event, state) => {
            if (state === 'completed') {
                console.log('Download successfully')
            } else {
                console.log(`Download failed: ${state}`)
            }
        })
    });

    /*
    * Development
    */
    if (process.env.NODE_ENV === 'development') {
        mainWindow.openDevTools();
        mainWindow.webContents.on('context-menu', (e, props) => {
            const { x, y } = props;

            Menu.buildFromTemplate([{
                label: 'Inspect element',
                click() {
                    mainWindow.inspectElement(x, y);
                }
            }]).popup(mainWindow);
        });
    }

    /*
    * Menu
    */
    const template = [{
        label: 'Caption',
        submenu: [{
            label: 'About Caption',
            selector: 'orderFrontStandardAboutPanel:'
        }, {
            label: 'Check for Updates...',
            click() {
                autoUpdater.checkForUpdates();
            }
        }, {
            type: 'separator'
        }, {
            label: 'Services',
            submenu: []
        }, {
            type: 'separator'
        }, {
            label: 'Hide Caption',
            accelerator: 'Command+H',
            selector: 'hide:'
        }, {
            label: 'Hide Others',
            accelerator: 'Command+Shift+H',
            selector: 'hideOtherApplications:'
        }, {
            label: 'Show All',
            selector: 'unhideAllApplications:'
        }, {
            type: 'separator'
        }, {
            label: 'Quit',
            accelerator: 'Command+Q',
            click() {
                app.quit();
            }
        }]
    }, {
        label: 'Edit',
        submenu: [{
            label: 'Undo',
            accelerator: 'Command+Z',
            selector: 'undo:'
        }, {
            label: 'Redo',
            accelerator: 'Shift+Command+Z',
            selector: 'redo:'
        }, {
            type: 'separator'
        }, {
            label: 'Cut',
            accelerator: 'Command+X',
            selector: 'cut:'
        }, {
            label: 'Copy',
            accelerator: 'Command+C',
            selector: 'copy:'
        }, {
            label: 'Paste',
            accelerator: 'Command+V',
            selector: 'paste:'
        }, {
            label: 'Select All',
            accelerator: 'Command+A',
            selector: 'selectAll:'
        }]
    }, {
        label: 'View',
        submenu: (process.env.NODE_ENV === 'development') ? [{
            label: 'Reload',
            accelerator: 'Command+R',
            click() {
                mainWindow.webContents.reload();
            }
        }, {
            label: 'Toggle Full Screen',
            accelerator: 'Ctrl+Command+F',
            click() {
                mainWindow.setFullScreen(!mainWindow.isFullScreen());
            }
        }] : [{
            label: 'Toggle Full Screen',
            accelerator: 'Ctrl+Command+F',
            click() {
                mainWindow.setFullScreen(!mainWindow.isFullScreen());
            }
        }]
    }, {
        label: 'Window',
        submenu: [{
            label: 'Minimize',
            accelerator: 'Command+M',
            selector: 'performMiniaturize:'
        }, {
            label: 'Close',
            accelerator: 'Command+W',
            click() {
                app.quit();
            }
        }, {
            type: 'separator'
        }, {
            label: 'Bring All to Front',
            selector: 'arrangeInFront:'
        }]
    }, {
        label: 'Help',
        submenu: [{
            label: 'Learn More',
            click() {
                shell.openExternal('http://electron.atom.io');
            }
        }, {
            label: 'Documentation',
            click() {
                shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
            }
        }, {
            label: 'Community Discussions',
            click() {
                shell.openExternal('https://discuss.atom.io/c/electron');
            }
        }, {
            label: 'Search Issues',
            click() {
                shell.openExternal('https://github.com/atom/electron/issues');
            }
        }]
    }];

    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

});
<commit_msg>Fixed #21<commit_after>import os from 'os'
import path from 'path'
import { app, autoUpdater, BrowserWindow, Menu, shell, ipcMain, dialog, Tray } from 'electron';
import { moveToApplications } from 'electron-lets-move';
import pkg from './package.json'
import Storage from 'electron-json-storage'
import windowStateKeeper from 'electron-window-state'

/*
* Basics
*/
let menu;
let mainWindow = null;
let settingsWindow = null;

if (process.env.NODE_ENV === 'development') {
    require('electron-debug')();
}

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});

/*
* autoUpdater
*/
let firstRun = true
const platform = os.platform() + '_' + os.arch(); // darwin_x64
const updateURL = `https://download.getcaption.co/update/${platform}/${pkg.version}`;

autoUpdater.on('checking-for-update', () => {
    console.log('Checking for updates...');
});

autoUpdater.on('update-not-available', () => {
    if (!firstRun) {
        const options = {
            type: 'info',
            buttons: ['OK'],
            title: 'Caption',
            message: `Caption is up to date`,
            detail: `It looks like you're already rocking the latest version!`
        }
        dialog.showMessageBox(options)
    }
    firstRun = false;
    console.log(`You've got the latest version.`)
})

autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) => {
    const options = {
        type: 'info',
        buttons: ['Restart', 'Later'],
        title: "Caption",
        message: `The new version has been downloaded. Please restart the application to apply the updates.`,
        detail: releaseName + "\n\n" + releaseNotes
    }
    const index = dialog.showMessageBox(options)

    if (index === 1) {
        return;
    }

    quitAndUpdate();
    firstRun = false;
});

autoUpdater.on('error', (error) => {
    console.log(error)
    firstRun = false;
});

autoUpdater.on('update-available', () => {
    console.log('update available')
    firstRun = false;

    // setInterval(() => {
    //     console.log(autoUpdater.status);
    // }, 5000);

});

try {
    autoUpdater.setFeedURL(updateURL)
    autoUpdater.checkForUpdates()
}
catch (error) {
    console.log(error)
}

/*
* Extentions
*/
const installExtensions = async () => {
    if (process.env.NODE_ENV === 'development') {
        // eslint-disable-line global-require
        const installer = require('electron-devtools-installer');

        const extensions = [
            'REACT_DEVELOPER_TOOLS',
            'REDUX_DEVTOOLS'
        ];
        const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
        for (const name of extensions) {
            try {
                await installer.default(installer[name], forceDownload);
            } catch (e) { } // eslint-disable-line
        }
    }
};

/*
* Create Main Window
*/
const createMainWindow = () => {
    let mainWindowState = windowStateKeeper({
        defaultWidth: 360,
        defaultHeight: 440
    });

    let transparent = true
    let backgroundColor = 'none'
    const osVersion = os.release().split('.').join('')

    if (osVersion < 1400) {
        transparent = false
        backgroundColor = '#474748'
    }

    // Create the windows
    mainWindow = new BrowserWindow({
        width: mainWindowState.width,
        height: mainWindowState.height,
        x: mainWindowState.x,
        y: mainWindowState.y,
        show: false,
        minWidth: 300,
        minHeight: 300,
        vibrancy: 'dark',
        transparent: transparent,
        titleBarStyle: 'hidden-inset',
        backgroundColor: backgroundColor
    });

    // Manage window state
    mainWindowState.manage(mainWindow);

    // Set URL
    mainWindow.loadURL(`file://${__dirname}/app/app.html`);

    // Events
    mainWindow.webContents.on('did-finish-load', () => {
        mainWindow.show();
        mainWindow.focus();
    });

    mainWindow.on('closed', () => {
        mainWindow = null;
        app.quit();
    });
}

app.on('ready', async () => {

    // if (process.env.NODE_ENV !== 'development') {
    /*
    * Let's Move
    */

    Storage.has('moveApp', async (error, value) => {
        if (!value) {
            try {
                const moved = await moveToApplications();
                if (!moved) {
                    Storage.set('moveApp', false);
                }
            }
            catch (error) {
                console.log(error);
            }
        }
        else {
            Storage.get('moveApp', async (error, value) => {
                if (value) {
                    try {
                        const moved = await moveToApplications();
                    }
                    catch (error) {
                        console.log(error);
                    }
                }
                else {
                    console.log('user choosed to not move the app!');
                }
            })
        }
    })
    // }

    await installExtensions();

    /*
    * MainWindow
    */
    createMainWindow();

    /*
    * IPC's
    */
    ipcMain.on('close-main', () => {
        mainWindow.close();
        app.quit();
    });

    ipcMain.on('lang-changed', () => {
        mainWindow.webContents.send('change-language')
    })

    /*
    * Downloads
    */
    mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
        item.on('updated', (event, state) => {
            if (state === 'interrupted') {
                console.log('Download is interrupted but can be resumed')
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    console.log('Download is paused')
                } else {
                    console.log(`Received bytes: ${item.getReceivedBytes()}`)
                }
            }
        })

        item.once('done', (event, state) => {
            if (state === 'completed') {
                console.log('Download successfully')
            } else {
                console.log(`Download failed: ${state}`)
            }
        })
    });

    /*
    * Development
    */
    if (process.env.NODE_ENV === 'development') {
        mainWindow.openDevTools();
        mainWindow.webContents.on('context-menu', (e, props) => {
            const { x, y } = props;

            Menu.buildFromTemplate([{
                label: 'Inspect element',
                click() {
                    mainWindow.inspectElement(x, y);
                }
            }]).popup(mainWindow);
        });
    }

    /*
    * Menu
    */
    const template = [{
        label: 'Caption',
        submenu: [{
            label: 'About Caption',
            selector: 'orderFrontStandardAboutPanel:'
        }, {
            label: 'Check for Updates...',
            click() {
                autoUpdater.checkForUpdates();
            }
        }, {
            type: 'separator'
        }, {
            label: 'Services',
            submenu: []
        }, {
            type: 'separator'
        }, {
            label: 'Hide Caption',
            accelerator: 'Command+H',
            selector: 'hide:'
        }, {
            label: 'Hide Others',
            accelerator: 'Command+Shift+H',
            selector: 'hideOtherApplications:'
        }, {
            label: 'Show All',
            selector: 'unhideAllApplications:'
        }, {
            type: 'separator'
        }, {
            label: 'Quit',
            accelerator: 'Command+Q',
            click() {
                app.quit();
            }
        }]
    }, {
        label: 'Edit',
        submenu: [{
            label: 'Undo',
            accelerator: 'Command+Z',
            selector: 'undo:'
        }, {
            label: 'Redo',
            accelerator: 'Shift+Command+Z',
            selector: 'redo:'
        }, {
            type: 'separator'
        }, {
            label: 'Cut',
            accelerator: 'Command+X',
            selector: 'cut:'
        }, {
            label: 'Copy',
            accelerator: 'Command+C',
            selector: 'copy:'
        }, {
            label: 'Paste',
            accelerator: 'Command+V',
            selector: 'paste:'
        }, {
            label: 'Select All',
            accelerator: 'Command+A',
            selector: 'selectAll:'
        }]
    }, {
        label: 'View',
        submenu: (process.env.NODE_ENV === 'development') ? [{
            label: 'Reload',
            accelerator: 'Command+R',
            click() {
                mainWindow.webContents.reload();
            }
        }, {
            label: 'Toggle Full Screen',
            accelerator: 'Ctrl+Command+F',
            click() {
                mainWindow.setFullScreen(!mainWindow.isFullScreen());
            }
        }] : [{
            label: 'Toggle Full Screen',
            accelerator: 'Ctrl+Command+F',
            click() {
                mainWindow.setFullScreen(!mainWindow.isFullScreen());
            }
        }]
    }, {
        label: 'Window',
        submenu: [{
            label: 'Minimize',
            accelerator: 'Command+M',
            selector: 'performMiniaturize:'
        }, {
            label: 'Close',
            accelerator: 'Command+W',
            click() {
                app.quit();
            }
        }, {
            type: 'separator'
        }, {
            label: 'Bring All to Front',
            selector: 'arrangeInFront:'
        }]
    }, {
        label: 'Help',
        submenu: [{
            label: 'Learn More',
            click() {
                shell.openExternal('http://electron.atom.io');
            }
        }, {
            label: 'Documentation',
            click() {
                shell.openExternal('https://github.com/atom/electron/tree/master/docs#readme');
            }
        }, {
            label: 'Community Discussions',
            click() {
                shell.openExternal('https://discuss.atom.io/c/electron');
            }
        }, {
            label: 'Search Issues',
            click() {
                shell.openExternal('https://github.com/atom/electron/issues');
            }
        }]
    }];

    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

});
<|endoftext|>