<commit_before>import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils'
import Vuex from 'vuex'
import cloneDeep from 'lodash.clonedeep'
import TheFooterPlayerTitle from '~/components/TheFooterPlayerTitle'
import pluginApp from '~/plugins/app'
import pluginFontAwesome from '~/plugins/fontawesome'
import storePlayer from '~/store/player'

const localVue = createLocalVue()

localVue.use(Vuex)
localVue.use(pluginApp)
localVue.use(pluginFontAwesome)

const factory = (store = {}) => {
  return mount(TheFooterPlayerTitle, {
    localVue,
    store,
    stubs: {
      NLink: RouterLinkStub
    }
  })
}

const player = cloneDeep(storePlayer)
player.namespaced = true

let fixture, store

beforeEach(() => {
  store = new Vuex.Store({ modules: { player } })

  fixture = {}
  fixture.player = {
    id: 'id1',
    title: 'title1',
    provider: 'provider1',
    type: 'track',
    src: 'src1'
  }
})

test('title route', () => {
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(wrapper.findAllComponents(RouterLinkStub).at(0).props().to)
    .toEqual({ name: 'track', params: { id: 'id1' } })
})

test('title', () => {
  fixture.player.title = 'a'.repeat(50)
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(/^a{40}\.\.\.$/.test(wrapper.findAllComponents(RouterLinkStub).at(0).text()))
    .toBe(true)
})

test('click clear', async () => {
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toBe('title1')

  const button = wrapper.find('button')
  button.trigger('click')
  await wrapper.vm.$nextTick()

  expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toBe('')
})
<commit_msg>Minor fix for vue-test-utils<commit_after>import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils'
import Vuex from 'vuex'
import cloneDeep from 'lodash.clonedeep'
import TheFooterPlayerTitle from '~/components/TheFooterPlayerTitle'
import pluginApp from '~/plugins/app'
import pluginFontAwesome from '~/plugins/fontawesome'
import storePlayer from '~/store/player'

const localVue = createLocalVue()

localVue.use(Vuex)
localVue.use(pluginApp)
localVue.use(pluginFontAwesome)

const factory = (store = {}) => {
  return mount(TheFooterPlayerTitle, {
    localVue,
    store,
    stubs: {
      NLink: RouterLinkStub
    }
  })
}

const player = cloneDeep(storePlayer)
player.namespaced = true

let fixture, store

beforeEach(() => {
  store = new Vuex.Store({ modules: { player } })

  fixture = {}
  fixture.player = {
    id: 'id1',
    title: 'title1',
    provider: 'provider1',
    type: 'track',
    src: 'src1'
  }
})

test('title route', () => {
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(wrapper.findAllComponents(RouterLinkStub).at(0).props().to)
    .toEqual({ name: 'track', params: { id: 'id1' } })
})

test('title', () => {
  fixture.player.title = 'a'.repeat(50)
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(/^a{40}\.\.\.$/.test(wrapper.findAllComponents(RouterLinkStub).at(0).text()))
    .toBe(true)
})

test('click clear', async () => {
  store.commit('player/setItem', fixture.player)
  const wrapper = factory(store)
  expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toBe('title1')

  const button = wrapper.find('button')
  await button.trigger('click')

  expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toBe('')
})
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
      .module('dopplerRelay')
      .controller('DomainManagerCtrl', DomainManagerCtrl);

    DomainManagerCtrl.$inject = [
      '$scope',
      'settings',
      '$q'
    ];

    function DomainManagerCtrl($scope, settings, $q) {
      var vm = this;
      vm.regexDomain = "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\\.)+[a-zA-Z]{2,63}$)";
      vm.activationPromise = activate();

      function activate() {
        return loadUserDomains();
      }

      vm.showNewDomainInput = function(){
        vm.showDomainInput = true;
      };

      vm.addDomain = function(form) {
        vm.submitted = true;
        if (!form.$valid) {
          return;
        }
        settings.addDomain(form.domain.$modelValue)
        .then(function() {
          loadUserDomains();
        });

      }

      function loadUserDomains() {
        return settings.getDomains()
        .then(function(data){
          vm.domains = data.domains;
          data.domains.map(function (ele) {
            ele.status = ele.disabled ? 'disabled_text' : 'default_text';
          });
          vm.domainDefault = data.defaultDomain;
        });
      }
    }
})();
<commit_msg>DR-861 Change to not modify the passed object<commit_after>(function () {
    'use strict';

    angular
      .module('dopplerRelay')
      .controller('DomainManagerCtrl', DomainManagerCtrl);

    DomainManagerCtrl.$inject = [
      '$scope',
      'settings',
      '$q'
    ];

    function DomainManagerCtrl($scope, settings, $q) {
      var vm = this;
      vm.regexDomain = "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\\.)+[a-zA-Z]{2,63}$)";
      vm.activationPromise = activate();

      function activate() {
        return loadUserDomains();
      }

      vm.showNewDomainInput = function(){
        vm.showDomainInput = true;
      };

      vm.addDomain = function(form) {
        vm.submitted = true;
        if (!form.$valid) {
          return;
        }
        settings.addDomain(form.domain.$modelValue)
        .then(function() {
          loadUserDomains();
        });

      }

      function loadUserDomains() {
        return settings.getDomains()
        .then(function(data) {
          vm.domains = data.domains.map(function (ele) {
            return {
              status: ele.disabled ? 'disabled_text' : 'default_text',
              name: ele.name
             };
          });
          vm.domainDefault = data.defaultDomain;
        });
      }
    }
})();
<|endoftext|>


<commit_before>/**
 * 读取元素在有序数组中的位置
 * @param {Array} orderArray
 * @param {string|number} searchItem
 */
var getIndexFromOrderedArray = function (orderArray, searchItem, isLE = (sample, search) => (typeof sample === "object" ? sample.value : sample) <= (typeof search === "object" ? search.value : search)) {
    var count = 0;
    for (var cx = 0, dx = orderArray.length, ci = cx + dx >>> 1; cx < dx; ci = cx + dx >>> 1) {
        var orderItem = orderArray[ci];
        if (isLE(orderItem, searchItem)) {
            cx = ci + 1;
        } else {
            dx = ci;
        }
    }
    return dx - 1;
};<commit_msg>修改读取value的方法<commit_after>var getValue = function (o) {
    return o instanceof Object && "value" in o ? o.value : o
};
var defaultIsLE = (sample, search) => getValue(sample) <= getValue(search);
/**
 * 读取元素在有序数组中的位置
 * @param {Array} orderArray
 * @param {string|number} searchItem
 */
var getIndexFromOrderedArray = function (orderArray, searchItem, isLE = defaultIsLE) {
    var count = 0;
    for (var cx = 0, dx = orderArray.length, ci = cx + dx >>> 1; cx < dx; ci = cx + dx >>> 1) {
        var orderItem = orderArray[ci];
        if (isLE(orderItem, searchItem)) {
            cx = ci + 1;
        } else {
            dx = ci;
        }
    }
    return dx - 1;
};<|endoftext|>


<commit_before>/**
 * Created by marti on 2017-03-25.
 */
angular.module('myApp.myTasks', [])
  .controller('MyTasksController', function ($scope, Model) {

    Model.authorize();

    $scope.boards = Model.getBoards();

  });<commit_msg>Added some TODOs<commit_after>/**
 * Created by marti on 2017-03-25.
 */
angular.module('myApp.myTasks', [])
  .controller('MyTasksController', function ($scope, Model) {
    //TODO: Move this to where it only runs once
    Model.authorize();

    //TODO: Wait for data to load in model
    $scope.boards = Model.getBoards();

  });<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.node_nid', ['ngRoute', 'drupalService'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/node/:nid', {
            templateUrl: 'node_nid/node_nid.html',
            controller: 'NodeNidCtrl'
        });
    }])

    .controller('NodeNidCtrl', function ($scope, $routeParams, Node, User, TaxonomyTerm, Comment) {
        var anonymousUser = {
            name: [
                {
                    value: "Anonymous"
                }
            ]
        };

        $scope.tags = {};
        // Fetch node entity for current nid
        $scope.node = Node.fetch({nid: $routeParams.nid}, function (node) {
            $scope.breadcrumb = [
                {
                    path: '#node',
                    title: 'Home'
                }, {
                    path: '#node/1',
                    title: $scope.node.title[0].value
                }
            ];

            // If the node isn't anonymous then fetch the user entity
            if ($scope.node._internals.uid[0].target_id == 0) {
                $scope.node.user = anonymousUser;
            } else {
                $scope.node.user = User.get({uid: $scope.node.uid[0].target_id})
            }

            // Fetch the entity for every tag in this node.
            $scope.node._internals.field_tags.forEach(function (element, index, array) {
                if ($scope.tags[element.target_id] == undefined) {
                    $scope.tags[element.target_id] = TaxonomyTerm.query({tid: element.target_id});
                }
            });
        });

        // Fetch the comments for this node (Using a special view in Drupal)
        $scope.comments = Comment.query({
            nid: $routeParams.nid
        });

        $scope.postComment = function () {
            // Post new comment to this node. $scope.newComment contains the http payload
            $scope.newComment.entity_type = 'node';
            $scope.newComment.field_name = 'comment';
            $scope.newComment.entity_id = [{"target_id": $routeParams.nid}];
            Comment.post({}, $scope.newComment, function (response) {
                // Comment posted, refresh the comment list
                $scope.comments = Comment.query({nid: $routeParams.nid});
            });
        };

    });
<commit_msg>Fix for empty node.field_tags.<commit_after>'use strict';

angular.module('myApp.node_nid', ['ngRoute', 'drupalService'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/node/:nid', {
            templateUrl: 'node_nid/node_nid.html',
            controller: 'NodeNidCtrl'
        });
    }])

    .controller('NodeNidCtrl', function ($scope, $routeParams, Node, User, TaxonomyTerm, Comment) {
        var anonymousUser = {
            name: [
                {
                    value: "Anonymous"
                }
            ]
        };

        $scope.tags = {};
        // Fetch node entity for current nid
        $scope.node = Node.fetch({nid: $routeParams.nid}, function (node) {
            $scope.breadcrumb = [
                {
                    path: '#node',
                    title: 'Home'
                }, {
                    path: '#node/1',
                    title: $scope.node.title[0].value
                }
            ];

            // If the node isn't anonymous then fetch the user entity
            if ($scope.node._internals.uid[0].target_id == 0) {
                $scope.node.user = anonymousUser;
            } else {
                $scope.node.user = User.get({uid: $scope.node.uid[0].target_id})
            }

            // TODO: DRY alert
            if ($scope.node._internals.field_tags) {
                // Fetch the entity for every tag in this node.
                $scope.node._internals.field_tags.forEach(function (element, index, array) {
                    if ($scope.tags[element.target_id] == undefined) {
                        $scope.tags[element.target_id] = TaxonomyTerm.query({tid: element.target_id});
                    }
                });
            }
        });

        // Fetch the comments for this node (Using a special view in Drupal)
        $scope.comments = Comment.query({
            nid: $routeParams.nid
        });

        $scope.postComment = function () {
            // Post new comment to this node. $scope.newComment contains the http payload
            $scope.newComment.entity_type = 'node';
            $scope.newComment.field_name = 'comment';
            $scope.newComment.entity_id = [{"target_id": $routeParams.nid}];
            Comment.post({}, $scope.newComment, function (response) {
                // Comment posted, refresh the comment list
                $scope.comments = Comment.query({nid: $routeParams.nid});
            });
        };

    });
<|endoftext|>


<commit_before>(function() {
    // preview sizing and scaling
    window.setInterval(function() {
        var preview =  CCJS.main_preview,
            previewBox = preview.getBoundingClientRect(),
            previewParentBox = CCJS.main_previewPane.getBoundingClientRect(),
            previewWidth = preview.getAttribute('data-width'),
            previewHeight = preview.getAttribute('data-height');

        if (previewWidth && previewHeight) {
            var style = [],
                scale = 1,
                scaleX, scaleY;

            if (previewWidth  > previewParentBox.width)
                scaleX = previewParentBox.width / previewWidth;

            if (previewHeight  > previewParentBox.height)
                scaleY = previewParentBox.height / previewHeight;

            if (scaleX) {
                scale = scaleX || 1;
            }

            if (scaleX && scaleY && scaleX > scaleY){
                scale = scaleY || 1;
            }

            style.push('width:'+previewWidth+'px');
            style.push('height:'+previewHeight+'px');
            style.push('min-width:'+previewWidth+'px');
            style.push('min-height:'+previewHeight+'px');

            if (scale < 1) {
                style.push('transform-origin: top left');
                style.push('transform: scale('+scale+')');

            }

            preview.setAttribute('style', style.join(';'));
            preview.setAttribute('width', previewWidth+"px");
            preview.setAttribute('height', previewHeight+"px");
            debugger;

        } else {
            preview.removeAttribute('style');
            preview.removeAttribute('width');
            preview.removeAttribute('height');

        }
    }, 16);

    // normal view
    CCJS.addPlugin({
        title: 'normal',
        action: function(){
            this.main_preview.removeAttribute('data-width');
            this.main_preview.removeAttribute('data-height');
        },
        category: "mobile-simulation"
    });

    // flip between portrait and landscape
    CCJS.addPlugin({
        title: 'flip-view',
        action: function(){
            var previewWidth = this.main_preview.getAttribute('data-width'),
                previewHeight = this.main_preview.getAttribute('data-height');

            if (!previewWidth || !previewHeight)
                return;

            this.main_preview.setAttribute('data-width', previewHeight);
            this.main_preview.setAttribute('data-height', previewWidth);
        },
        category: "mobile-simulation"
    });

    // adding screen sizes
    var screenSizes = [{
        x: 320,
        y: 480
    }];

    for (var i = 0; i < screenSizes.length; i++) {
        var strX = screenSizes[i].x,
            strY = screenSizes[i].y;

        CCJS.addPlugin({
            title: strX + ' X ' + strY,
            action: function(){
                this.main_preview.setAttribute('data-width',strX);
                this.main_preview.setAttribute('data-height',strY);
            },
            category: "mobile-simulation"
        });
    }
})();
<commit_msg>removed debugger<commit_after>(function() {
    // preview sizing and scaling
    window.setInterval(function() {
        var preview =  CCJS.main_preview,
            previewBox = preview.getBoundingClientRect(),
            previewParentBox = CCJS.main_previewPane.getBoundingClientRect(),
            previewWidth = preview.getAttribute('data-width'),
            previewHeight = preview.getAttribute('data-height');

        if (previewWidth && previewHeight) {
            var style = [],
                scale = 1,
                scaleX, scaleY;

            if (previewWidth  > previewParentBox.width)
                scaleX = previewParentBox.width / previewWidth;

            if (previewHeight  > previewParentBox.height)
                scaleY = previewParentBox.height / previewHeight;

            if (scaleX) {
                scale = scaleX || 1;
            }

            if (scaleX && scaleY && scaleX > scaleY){
                scale = scaleY || 1;
            }

            style.push('width:'+previewWidth+'px');
            style.push('height:'+previewHeight+'px');
            style.push('min-width:'+previewWidth+'px');
            style.push('min-height:'+previewHeight+'px');

            if (scale < 1) {
                style.push('transform-origin: top left');
                style.push('transform: scale('+scale+')');

            }

            preview.setAttribute('style', style.join(';'));
            preview.setAttribute('width', previewWidth+"px");
            preview.setAttribute('height', previewHeight+"px");
        } else {
            preview.removeAttribute('style');
            preview.removeAttribute('width');
            preview.removeAttribute('height');
        }
    }, 16);

    // normal view
    CCJS.addPlugin({
        title: 'normal',
        action: function(){
            this.main_preview.removeAttribute('data-width');
            this.main_preview.removeAttribute('data-height');
        },
        category: "mobile-simulation"
    });

    // flip between portrait and landscape
    CCJS.addPlugin({
        title: 'flip-view',
        action: function(){
            var previewWidth = this.main_preview.getAttribute('data-width'),
                previewHeight = this.main_preview.getAttribute('data-height');

            if (!previewWidth || !previewHeight)
                return;

            this.main_preview.setAttribute('data-width', previewHeight);
            this.main_preview.setAttribute('data-height', previewWidth);
        },
        category: "mobile-simulation"
    });

    // adding screen sizes
    var screenSizes = [{
        x: 320,
        y: 480
    }];

    for (var i = 0; i < screenSizes.length; i++) {
        var strX = screenSizes[i].x,
            strY = screenSizes[i].y;

        CCJS.addPlugin({
            title: strX + ' X ' + strY,
            action: function(){
                this.main_preview.setAttribute('data-width',strX);
                this.main_preview.setAttribute('data-height',strY);
            },
            category: "mobile-simulation"
        });
    }
})();
<|endoftext|>


<commit_before>import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron'
import { btc } from 'utils'
import { closeChannelForm } from './channelform'
import { setError } from './error'
import { showNotification } from 'notifications'
// ------------------------------------
// Constants
// ------------------------------------
export const SET_CHANNEL_FORM = 'SET_CHANNEL_FORM'

export const SET_CHANNEL = 'SET_CHANNEL'

export const GET_CHANNELS = 'GET_CHANNELS'
export const RECEIVE_CHANNELS = 'RECEIVE_CHANNELS'

export const OPENING_CHANNEL = 'OPENING_CHANNEL'
export const OPENING_SUCCESSFUL = 'OPENING_SUCCESSFUL'
export const OPENING_FAILURE = 'OPENING_FAILURE'

export const CLOSING_CHANNEL = 'CLOSING_CHANNEL'
export const CLOSING_SUCCESSFUL = 'CLOSING_SUCCESSFUL'
export const CLOSING_FAILURE = 'CLOSING_FAILURE'

export const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'

export const SET_VIEW_TYPE = 'SET_VIEW_TYPE'

export const TOGGLE_PULLDOWN = 'TOGGLE_PULLDOWN'
export const CHANGE_FILTER = 'CHANGE_FILTER'

// ------------------------------------
// Actions
// ------------------------------------
export function setChannelForm(form) {
  return {
    type: SET_CHANNEL_FORM,
    form
  }
}

export function setChannel(channel) {
  return {
    type: SET_CHANNEL,
    channel
  }
}

export function getChannels() {
  return {
    type: GET_CHANNELS
  }
}

export function openingChannel() {
  return {
    type: OPENING_CHANNEL
  }
}

export function closingChannel() {
  return {
    type: CLOSING_CHANNEL
  }
}

export function openingSuccessful() {
  return {
    type: OPENING_SUCCESSFUL
  }
}

export function openingFailure() {
  return {
    type: OPENING_FAILURE
  }
}

export function updateChannelSearchQuery(searchQuery) {
  return {
    type: UPDATE_SEARCH_QUERY,
    searchQuery
  }
}

export function setViewType(viewType) {
  return {
    type: SET_VIEW_TYPE,
    viewType
  }
}

// Send IPC event for peers
export const fetchChannels = () => async (dispatch) => {
  dispatch(getChannels())
  ipcRenderer.send('lnd', { msg: 'channels' })
}

// Receive IPC event for channels
export const receiveChannels = (event, { channels, pendingChannels }) => dispatch => dispatch({ type: RECEIVE_CHANNELS, channels, pendingChannels })

// Send IPC event for opening a channel
export const openChannel = ({ pubkey, local_amt, push_amt }) => (dispatch) => {
  const localamt = btc.btcToSatoshis(local_amt)
  const pushamt = btc.btcToSatoshis(push_amt)

  dispatch(openingChannel())
  ipcRenderer.send('lnd', { msg: 'openChannel', data: { pubkey, localamt, pushamt } })
}

// TODO: Decide how to handle streamed updates for channels
// Receive IPC event for openChannel
export const channelSuccessful = () => (dispatch) => {
  dispatch(fetchChannels())
  dispatch(closeChannelForm())
}

// Receive IPC event for updated channel
export const pushchannelupdated = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for channel end
export const pushchannelend = event => (dispatch) => { // eslint-disable-line
  dispatch(fetchChannels())
}

// Receive IPC event for channel error
export const pushchannelerror = (event, { error }) => (dispatch) => {
  dispatch(openingFailure())
  dispatch(setError(error))
}

// Receive IPC event for channel status
export const pushchannelstatus = event => (dispatch) => { // eslint-disable-line
  dispatch(fetchChannels())
}

// Send IPC event for opening a channel
export const closeChannel = ({ channel_point }) => (dispatch) => {
  dispatch(closingChannel())
  const channelPoint = channel_point.split(':')
  ipcRenderer.send(
    'lnd',
    {
      msg: 'closeChannel',
      data: {
        channel_point: {
          funding_txid: channelPoint[0],
          output_index: channelPoint[1]
        },
        force: true
      }
    }
  )
}

// TODO: Decide how to handle streamed updates for closing channels
// Receive IPC event for closeChannel
export const closeChannelSuccessful = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for updated closing channel
export const pushclosechannelupdated = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel end
export const pushclosechannelend = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel error
export const pushclosechannelerror = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel status
export const pushclosechannelstatus = () => (dispatch) => {
  dispatch(fetchChannels())
}

// IPC event for channel graph data
export const channelGraphData = (event, data) => (dispatch, getState) => {
  const info = getState().info

  console.log('info: ', info)
  console.log('channelGraphData: ', data)
  const { channelGraphData: { channel_updates } } = data

  // if there are any new channel updates
  if (channel_updates.length) {
    // loop through the channel updates
    for(let i = 0; i < channel_updates.length; i++) {
      let channel_update = channel_updates[i]
      let { advertising_node, connecting_node } = channel_update

      // if our node is involved in this update we wanna show a notification
      if(info.data.identity_pubkey === advertising_node || info.data.identity_pubkey === connecting_node) {

        let otherParty = info.data.identity_pubkey === advertising_node ? connecting_node : advertising_node
        let notifBody = `No new friends, just new channels. Your channel with ${otherParty}` // eslint-disable-line
        const notifTitle = 'New channel detected'

        // HTML 5 notification for channel updates involving our node
        showNotification(notifTitle, notifBody)
      }
    }
  }
}

// IPC event for channel graph status
export const channelGraphStatus = (event, data) => (dispatch) => {
  console.log('channelGraphStatus: ', data)
}

export function toggleFilterPulldown() {
  return {
    type: TOGGLE_PULLDOWN
  }
}

export function changeFilter(filter) {
  return {
    type: CHANGE_FILTER,
    filter
  }
}

// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
  [SET_CHANNEL_FORM]: (state, { form }) => (
    { ...state, channelForm: Object.assign({}, state.channelForm, form) }
  ),

  [SET_CHANNEL]: (state, { channel }) => ({ ...state, channel }),

  [GET_CHANNELS]: state => ({ ...state, channelsLoading: true }),
  [RECEIVE_CHANNELS]: (state, { channels, pendingChannels }) => (
    { ...state, channelsLoading: false, channels, pendingChannels }
  ),

  [OPENING_CHANNEL]: state => ({ ...state, openingChannel: true }),
  [OPENING_FAILURE]: state => ({ ...state, openingChannel: false }),

  [CLOSING_CHANNEL]: state => ({ ...state, closingChannel: true }),

  [UPDATE_SEARCH_QUERY]: (state, { searchQuery }) => ({ ...state, searchQuery }),

  [SET_VIEW_TYPE]: (state, { viewType }) => ({ ...state, viewType }),

  [TOGGLE_PULLDOWN]: state => ({ ...state, filterPulldown: !state.filterPulldown }),
  [CHANGE_FILTER]: (state, { filter }) => ({ ...state, filterPulldown: false, filter })
}

const channelsSelectors = {}
const channelSelector = state => state.channels.channel
const channelsSelector = state => state.channels.channels
const pendingOpenChannelsSelector = state => state.channels.pendingChannels.pending_open_channels
const pendingClosedChannelsSelector = state => state.channels.pendingChannels.pending_closing_channels
const pendingForceClosedChannelsSelector = state => state.channels.pendingChannels.pending_force_closing_channels
const channelSearchQuerySelector = state => state.channels.searchQuery
const filtersSelector = state => state.channels.filters
const filterSelector = state => state.channels.filter

channelsSelectors.channelModalOpen = createSelector(
  channelSelector,
  channel => (!!channel)
)

const activeChannels = createSelector(
  channelsSelector,
  openChannels => openChannels.filter(channel => channel.active)
)

const closingPendingChannels = createSelector(
  pendingClosedChannelsSelector,
  pendingForceClosedChannelsSelector,
  (pendingClosedChannels, pendingForcedClosedChannels) => [...pendingClosedChannels, ...pendingForcedClosedChannels]
)

const allChannels = createSelector(
  channelsSelector,
  pendingOpenChannelsSelector,
  pendingClosedChannelsSelector,
  pendingForceClosedChannelsSelector,
  channelSearchQuerySelector,
  (channels, pendingOpenChannels, pendingClosedChannels, pendingForcedClosedChannels, searchQuery) => {
    const filteredChannels = channels.filter(channel => channel.remote_pubkey.includes(searchQuery) || channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingOpenChannels = pendingOpenChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingClosedChannels = pendingClosedChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingForcedClosedChannels = pendingForcedClosedChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line

    return [...filteredChannels, ...filteredPendingOpenChannels, ...filteredPendingClosedChannels, ...filteredPendingForcedClosedChannels]
  }
)

channelsSelectors.activeChanIds = createSelector(
  channelsSelector,
  channels => channels.map(channel => channel.chan_id)
)

channelsSelectors.nonActiveFilters = createSelector(
  filtersSelector,
  filterSelector,
  (filters, filter) => filters.filter(f => f.key !== filter.key)
)

export const currentChannels = createSelector(
  allChannels,
  activeChannels,
  channelsSelector,
  pendingOpenChannelsSelector,
  closingPendingChannels,
  filterSelector,
  channelSearchQuerySelector,
  (allChannelsArr, activeChannelsArr, openChannels, pendingOpenChannels, pendingClosedChannels, filter, searchQuery) => {
    // Helper function to deliver correct channel array based on filter
    const filteredArray = (filterKey) => {
      switch (filterKey) {
        case 'ALL_CHANNELS':
          return allChannelsArr
        case 'ACTIVE_CHANNELS':
          return activeChannelsArr
        case 'OPEN_CHANNELS':
          return openChannels
        case 'OPEN_PENDING_CHANNELS':
          return pendingOpenChannels
        case 'CLOSING_PENDING_CHANNELS':
          return pendingClosedChannels
        default:
          return []
      }
    }

    const channelArray = filteredArray(filter.key)

    return channelArray.filter(channel => (Object.prototype.hasOwnProperty.call(channel, 'channel') ?
      channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)
      :
      channel.remote_pubkey.includes(searchQuery) || channel.channel_point.includes(searchQuery)))
  }
)

export { channelsSelectors }

// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
  channelsLoading: false,
  channels: [],
  pendingChannels: {
    total_limbo_balance: '',
    pending_open_channels: [],
    pending_closing_channels: [],
    pending_force_closing_channels: []
  },
  channel: null,
  channelForm: {
    isOpen: false,
    node_key: '',
    local_amt: '',
    push_amt: ''
  },
  openingChannel: false,
  closingChannel: false,
  searchQuery: '',
  viewType: 0,

  filterPulldown: false,
  filter: { key: 'ALL_CHANNELS', name: 'All Channels' },
  filters: [
    { key: 'ALL_CHANNELS', name: 'All Channels' },
    { key: 'ACTIVE_CHANNELS', name: 'Active Channels' },
    { key: 'OPEN_CHANNELS', name: 'Open Channels' },
    { key: 'OPEN_PENDING_CHANNELS', name: 'Open Pending Channels' },
    { key: 'CLOSING_PENDING_CHANNELS', name: 'Closing Pending Channels' }
  ]
}

export default function channelsReducer(state = initialState, action) {
  const handler = ACTION_HANDLERS[action.type]

  return handler ? handler(state, action) : state
}
<commit_msg>feature(fetchNetwork + fetchChannels): fetchNetwork on new network update and fetchChannels on new channel that has to do with the current node<commit_after>import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron'
import { btc } from 'utils'
import { fetchDescribeNetwork } from './network'
import { closeChannelForm } from './channelform'
import { setError } from './error'
import { showNotification } from 'notifications'
// ------------------------------------
// Constants
// ------------------------------------
export const SET_CHANNEL_FORM = 'SET_CHANNEL_FORM'

export const SET_CHANNEL = 'SET_CHANNEL'

export const GET_CHANNELS = 'GET_CHANNELS'
export const RECEIVE_CHANNELS = 'RECEIVE_CHANNELS'

export const OPENING_CHANNEL = 'OPENING_CHANNEL'
export const OPENING_SUCCESSFUL = 'OPENING_SUCCESSFUL'
export const OPENING_FAILURE = 'OPENING_FAILURE'

export const CLOSING_CHANNEL = 'CLOSING_CHANNEL'
export const CLOSING_SUCCESSFUL = 'CLOSING_SUCCESSFUL'
export const CLOSING_FAILURE = 'CLOSING_FAILURE'

export const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'

export const SET_VIEW_TYPE = 'SET_VIEW_TYPE'

export const TOGGLE_PULLDOWN = 'TOGGLE_PULLDOWN'
export const CHANGE_FILTER = 'CHANGE_FILTER'

// ------------------------------------
// Actions
// ------------------------------------
export function setChannelForm(form) {
  return {
    type: SET_CHANNEL_FORM,
    form
  }
}

export function setChannel(channel) {
  return {
    type: SET_CHANNEL,
    channel
  }
}

export function getChannels() {
  return {
    type: GET_CHANNELS
  }
}

export function openingChannel() {
  return {
    type: OPENING_CHANNEL
  }
}

export function closingChannel() {
  return {
    type: CLOSING_CHANNEL
  }
}

export function openingSuccessful() {
  return {
    type: OPENING_SUCCESSFUL
  }
}

export function openingFailure() {
  return {
    type: OPENING_FAILURE
  }
}

export function updateChannelSearchQuery(searchQuery) {
  return {
    type: UPDATE_SEARCH_QUERY,
    searchQuery
  }
}

export function setViewType(viewType) {
  return {
    type: SET_VIEW_TYPE,
    viewType
  }
}

// Send IPC event for peers
export const fetchChannels = () => async (dispatch) => {
  dispatch(getChannels())
  ipcRenderer.send('lnd', { msg: 'channels' })
}

// Receive IPC event for channels
export const receiveChannels = (event, { channels, pendingChannels }) => dispatch => dispatch({ type: RECEIVE_CHANNELS, channels, pendingChannels })

// Send IPC event for opening a channel
export const openChannel = ({ pubkey, local_amt, push_amt }) => (dispatch) => {
  const localamt = btc.btcToSatoshis(local_amt)
  const pushamt = btc.btcToSatoshis(push_amt)

  dispatch(openingChannel())
  ipcRenderer.send('lnd', { msg: 'openChannel', data: { pubkey, localamt, pushamt } })
}

// TODO: Decide how to handle streamed updates for channels
// Receive IPC event for openChannel
export const channelSuccessful = () => (dispatch) => {
  dispatch(fetchChannels())
  dispatch(closeChannelForm())
}

// Receive IPC event for updated channel
export const pushchannelupdated = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for channel end
export const pushchannelend = event => (dispatch) => { // eslint-disable-line
  dispatch(fetchChannels())
}

// Receive IPC event for channel error
export const pushchannelerror = (event, { error }) => (dispatch) => {
  dispatch(openingFailure())
  dispatch(setError(error))
}

// Receive IPC event for channel status
export const pushchannelstatus = event => (dispatch) => { // eslint-disable-line
  dispatch(fetchChannels())
}

// Send IPC event for opening a channel
export const closeChannel = ({ channel_point }) => (dispatch) => {
  dispatch(closingChannel())
  const channelPoint = channel_point.split(':')
  ipcRenderer.send(
    'lnd',
    {
      msg: 'closeChannel',
      data: {
        channel_point: {
          funding_txid: channelPoint[0],
          output_index: channelPoint[1]
        },
        force: true
      }
    }
  )
}

// TODO: Decide how to handle streamed updates for closing channels
// Receive IPC event for closeChannel
export const closeChannelSuccessful = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for updated closing channel
export const pushclosechannelupdated = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel end
export const pushclosechannelend = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel error
export const pushclosechannelerror = () => (dispatch) => {
  dispatch(fetchChannels())
}

// Receive IPC event for closing channel status
export const pushclosechannelstatus = () => (dispatch) => {
  dispatch(fetchChannels())
}

// IPC event for channel graph data
export const channelGraphData = (event, data) => (dispatch, getState) => {
  const info = getState().info
  const { channelGraphData: { channel_updates } } = data

  // if there are any new channel updates
  if (channel_updates.length) {
    // The network has updated, so fetch a new result
    dispatch(fetchDescribeNetwork())

    // loop through the channel updates
    for(let i = 0; i < channel_updates.length; i++) {
      let channel_update = channel_updates[i]
      let { advertising_node, connecting_node } = channel_update

      // if our node is involved in this update we wanna show a notification
      if(info.data.identity_pubkey === advertising_node || info.data.identity_pubkey === connecting_node) {
        // this channel has to do with the user, lets fetch a new channel list for them
        // TODO: full fetch is probably not necessary
        dispatch(fetchChannels())

        // Construct the notification
        let otherParty = info.data.identity_pubkey === advertising_node ? connecting_node : advertising_node
        let notifBody = `No new friends, just new channels. Your channel with ${otherParty}` // eslint-disable-line
        const notifTitle = 'New channel detected'

        // HTML 5 notification for channel updates involving our node
        showNotification(notifTitle, notifBody)
      }
    }
  }
}

// IPC event for channel graph status
export const channelGraphStatus = (event, data) => (dispatch) => {
  console.log('channelGraphStatus: ', data)
}

export function toggleFilterPulldown() {
  return {
    type: TOGGLE_PULLDOWN
  }
}

export function changeFilter(filter) {
  return {
    type: CHANGE_FILTER,
    filter
  }
}

// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
  [SET_CHANNEL_FORM]: (state, { form }) => (
    { ...state, channelForm: Object.assign({}, state.channelForm, form) }
  ),

  [SET_CHANNEL]: (state, { channel }) => ({ ...state, channel }),

  [GET_CHANNELS]: state => ({ ...state, channelsLoading: true }),
  [RECEIVE_CHANNELS]: (state, { channels, pendingChannels }) => (
    { ...state, channelsLoading: false, channels, pendingChannels }
  ),

  [OPENING_CHANNEL]: state => ({ ...state, openingChannel: true }),
  [OPENING_FAILURE]: state => ({ ...state, openingChannel: false }),

  [CLOSING_CHANNEL]: state => ({ ...state, closingChannel: true }),

  [UPDATE_SEARCH_QUERY]: (state, { searchQuery }) => ({ ...state, searchQuery }),

  [SET_VIEW_TYPE]: (state, { viewType }) => ({ ...state, viewType }),

  [TOGGLE_PULLDOWN]: state => ({ ...state, filterPulldown: !state.filterPulldown }),
  [CHANGE_FILTER]: (state, { filter }) => ({ ...state, filterPulldown: false, filter })
}

const channelsSelectors = {}
const channelSelector = state => state.channels.channel
const channelsSelector = state => state.channels.channels
const pendingOpenChannelsSelector = state => state.channels.pendingChannels.pending_open_channels
const pendingClosedChannelsSelector = state => state.channels.pendingChannels.pending_closing_channels
const pendingForceClosedChannelsSelector = state => state.channels.pendingChannels.pending_force_closing_channels
const channelSearchQuerySelector = state => state.channels.searchQuery
const filtersSelector = state => state.channels.filters
const filterSelector = state => state.channels.filter

channelsSelectors.channelModalOpen = createSelector(
  channelSelector,
  channel => (!!channel)
)

const activeChannels = createSelector(
  channelsSelector,
  openChannels => openChannels.filter(channel => channel.active)
)

const closingPendingChannels = createSelector(
  pendingClosedChannelsSelector,
  pendingForceClosedChannelsSelector,
  (pendingClosedChannels, pendingForcedClosedChannels) => [...pendingClosedChannels, ...pendingForcedClosedChannels]
)

const allChannels = createSelector(
  channelsSelector,
  pendingOpenChannelsSelector,
  pendingClosedChannelsSelector,
  pendingForceClosedChannelsSelector,
  channelSearchQuerySelector,
  (channels, pendingOpenChannels, pendingClosedChannels, pendingForcedClosedChannels, searchQuery) => {
    const filteredChannels = channels.filter(channel => channel.remote_pubkey.includes(searchQuery) || channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingOpenChannels = pendingOpenChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingClosedChannels = pendingClosedChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line
    const filteredPendingForcedClosedChannels = pendingForcedClosedChannels.filter(channel => channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)) // eslint-disable-line

    return [...filteredChannels, ...filteredPendingOpenChannels, ...filteredPendingClosedChannels, ...filteredPendingForcedClosedChannels]
  }
)

channelsSelectors.activeChanIds = createSelector(
  channelsSelector,
  channels => channels.map(channel => channel.chan_id)
)

channelsSelectors.nonActiveFilters = createSelector(
  filtersSelector,
  filterSelector,
  (filters, filter) => filters.filter(f => f.key !== filter.key)
)

export const currentChannels = createSelector(
  allChannels,
  activeChannels,
  channelsSelector,
  pendingOpenChannelsSelector,
  closingPendingChannels,
  filterSelector,
  channelSearchQuerySelector,
  (allChannelsArr, activeChannelsArr, openChannels, pendingOpenChannels, pendingClosedChannels, filter, searchQuery) => {
    // Helper function to deliver correct channel array based on filter
    const filteredArray = (filterKey) => {
      switch (filterKey) {
        case 'ALL_CHANNELS':
          return allChannelsArr
        case 'ACTIVE_CHANNELS':
          return activeChannelsArr
        case 'OPEN_CHANNELS':
          return openChannels
        case 'OPEN_PENDING_CHANNELS':
          return pendingOpenChannels
        case 'CLOSING_PENDING_CHANNELS':
          return pendingClosedChannels
        default:
          return []
      }
    }

    const channelArray = filteredArray(filter.key)

    return channelArray.filter(channel => (Object.prototype.hasOwnProperty.call(channel, 'channel') ?
      channel.channel.remote_node_pub.includes(searchQuery) || channel.channel.channel_point.includes(searchQuery)
      :
      channel.remote_pubkey.includes(searchQuery) || channel.channel_point.includes(searchQuery)))
  }
)

export { channelsSelectors }

// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
  channelsLoading: false,
  channels: [],
  pendingChannels: {
    total_limbo_balance: '',
    pending_open_channels: [],
    pending_closing_channels: [],
    pending_force_closing_channels: []
  },
  channel: null,
  channelForm: {
    isOpen: false,
    node_key: '',
    local_amt: '',
    push_amt: ''
  },
  openingChannel: false,
  closingChannel: false,
  searchQuery: '',
  viewType: 0,

  filterPulldown: false,
  filter: { key: 'ALL_CHANNELS', name: 'All Channels' },
  filters: [
    { key: 'ALL_CHANNELS', name: 'All Channels' },
    { key: 'ACTIVE_CHANNELS', name: 'Active Channels' },
    { key: 'OPEN_CHANNELS', name: 'Open Channels' },
    { key: 'OPEN_PENDING_CHANNELS', name: 'Open Pending Channels' },
    { key: 'CLOSING_PENDING_CHANNELS', name: 'Closing Pending Channels' }
  ]
}

export default function channelsReducer(state = initialState, action) {
  const handler = ACTION_HANDLERS[action.type]

  return handler ? handler(state, action) : state
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var passport = require('passport');

var Provincia = require('../models/ProvinciaSchema');

router.get('/', function(req, res, next) {
  Provincia.find(function(err, provincias) {
    if (!err) {
      res.json(provincias);
    } else {
      return next(err);
    }
  });
});

module.exports = router;
<commit_msg>Improve provincias route<commit_after>var express = require('express');
var router = express.Router();
var passport = require('passport');

var Provincia = require('../models/ProvinciaSchema');

router.get('/', function(req, res, next) {
  Provincia.find(function(err, provincias) {
    if (!err) {
      if (provincias) {
        res.json(provincias);
      } else {
        return res.status(500).json({message:'No hay provincias'});
      }
    } else {
      return res.status(500).json({message:'Intente de nuevo'});
    }
  });
});

module.exports = router;
<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react';
import {
  Image,
  LayoutAnimation,
  PixelRatio,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import MapView from 'react-native-maps';

import ListTitle from '../../components/ListTitle';
import Navbar from '../../components/Navbar';
import Scene from '../../components/Scene';

import { list as organiserList } from '../../data/organisers';
import theme from '../../theme';
import { attemptToOpenUrl } from '../../utils';

import CodeOfConduct from './components/CodeOfConduct';
import Organiser from './components/Organiser';

// Santa Clara, California
const mapRegion = {
  latitude: 37.354108,
  longitude: -121.955246,
  latitudeDelta: 0.01,
  longitudeDelta: 0.01,
};

export default class Info extends Component {
  props: {
    navigator: Object,
    organisers: typeof organiserList,
  };

  state = {
    modalIsOpen: false,
  };

  static defaultProps = {
    organisers: organiserList,
  };

  componentDidMount() {
    setTimeout(this.refs.marker.showCallout, 1000);
  }

  toggleModal = () => {
    LayoutAnimation.easeInEaseOut();
    this.setState({ modalIsOpen: !this.state.modalIsOpen });
  };

  openMap() {
    const url = `http://maps.apple.com/?ll=${mapRegion.latitude},${mapRegion.longitude}`;

    attemptToOpenUrl(url);
  }
  openThinkmill() {
    const url = 'https://www.thinkmill.com.au';

    attemptToOpenUrl(url);
  }

  openRepository() {
    const url = 'https://github.com/Thinkmill/react-conf-2017';
    attemptToOpenUrl(url);
  }

  render() {
    const { navigator, organisers } = this.props;
    const { modalIsOpen } = this.state;

    return (
      <Scene>
        <Navbar
          title="Event Info"
          leftButtonIconName="ios-arrow-back"
          leftButtonOnPress={navigator.popToTop}
        />
        <ScrollView>
          <MapView initialRegion={mapRegion} style={styles.map}>
            <MapView.Marker
              coordinate={mapRegion}
              title="Santa Clara Marriott"
              description="2700 Mission College Blvd, Santa Clara, CA 95054"
              ref="marker"
            />
          </MapView>

          <View style={{ flex: 1 }}>
            <View style={styles.hero}>
              <Text style={styles.heroText}>
                The conference will be taking place on February 22nd and 23rd, with talks from 10am to 6pm each day. Plan to hang out with us each evening for plenty of socializing over food and drink.
              </Text>
              <Text style={styles.heroText}>
                Proceeds from all ticket sales are being donated to Code2040.
              </Text>
              <TouchableOpacity onPress={this.toggleModal} activeOpacity={0.75}>
                <Text style={styles.heroLink}>
                  Code of Conduct
                </Text>
              </TouchableOpacity>
            </View>

            <ListTitle text="Organizers" />
            {organisers.map((organiser, idx) => {
              const onPress = () => {};

              return (
                <Organiser
                  avatar={organiser.avatar}
                  key={idx}
                  onPress={onPress}
                  name={organiser.name}
                  summary={organiser.summary}
                />
              );
            })}

            <View style={styles.madeby}>
              <TouchableOpacity
                onPress={this.openThinkmill}
                activeOpacity={0.75}
                style={styles.madebyLink}
              >
                <Image
                  source={require('./images/thinkmill-logo.png')}
                  style={{ width: 80, height: 80 }}
                />
                {/* <Text style={[styles.madebyText, styles.madebyTitle]}>Made by Thinkmill</Text> */}
              </TouchableOpacity>
              <Text style={styles.madebyText}>
                This app made with love in Sydney, Australia and open sourced by Thinkmill
              </Text>
              <TouchableOpacity
                onPress={this.openRepository}
                activeOpacity={0.75}
              >
                <Text style={styles.heroLink}>
                  View Source Code
                </Text>
              </TouchableOpacity>
            </View>
          </View>
        </ScrollView>

        {!!modalIsOpen && <CodeOfConduct onClose={this.toggleModal} />}
      </Scene>
    );
  }
}

const styles = StyleSheet.create({
  map: {
    flex: 1,
    height: 200,
    maxHeight: 200,
  },
  // hero
  hero: {
    alignItems: 'center',
    backgroundColor: 'white',
    borderBottomColor: theme.color.gray20,
    borderBottomWidth: 1 / PixelRatio.get(),
    borderTopColor: theme.color.gray30,
    borderTopWidth: 1 / PixelRatio.get(),
    paddingHorizontal: theme.fontSize.default,
  },
  heroText: {
    paddingTop: theme.fontSize.xlarge,
    fontSize: theme.fontSize.default,
    fontWeight: '300',
    lineHeight: theme.fontSize.large,
    textAlign: 'center',
  },
  heroLink: {
    color: theme.color.blue,
    fontSize: theme.fontSize.default,
    fontWeight: '500',
    padding: theme.fontSize.large,
  },

  // made by thinkmill
  madeby: {
    alignItems: 'center',
    paddingHorizontal: theme.fontSize.default,
    paddingVertical: theme.fontSize.xlarge,
  },
  madebyLink: {
    alignItems: 'center',
  },
  madebyText: {
    fontSize: theme.fontSize.default,
    fontWeight: '300',
    lineHeight: theme.fontSize.large,
    marginTop: theme.fontSize.default,
    textAlign: 'center',
  },
  madebyTitle: {
    fontWeight: '500',
  },
});
<commit_msg>Updating conference details.<commit_after>// @flow
import React, { Component } from 'react';
import {
  Image,
  LayoutAnimation,
  PixelRatio,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import MapView from 'react-native-maps';

import ListTitle from '../../components/ListTitle';
import Navbar from '../../components/Navbar';
import Scene from '../../components/Scene';

import { list as organiserList } from '../../data/organisers';
import theme from '../../theme';
import { attemptToOpenUrl } from '../../utils';

import CodeOfConduct from './components/CodeOfConduct';
import Organiser from './components/Organiser';

// Santa Clara, California
const mapRegion = {
  latitude: 37.354108,
  longitude: -121.955246,
  latitudeDelta: 0.01,
  longitudeDelta: 0.01,
};

export default class Info extends Component {
  props: {
    navigator: Object,
    organisers: typeof organiserList,
  };

  state = {
    modalIsOpen: false,
  };

  static defaultProps = {
    organisers: organiserList,
  };

  componentDidMount() {
    setTimeout(this.refs.marker.showCallout, 1000);
  }

  toggleModal = () => {
    LayoutAnimation.easeInEaseOut();
    this.setState({ modalIsOpen: !this.state.modalIsOpen });
  };

  openMap() {
    const url = `http://maps.apple.com/?ll=${mapRegion.latitude},${mapRegion.longitude}`;

    attemptToOpenUrl(url);
  }
  openThinkmill() {
    const url = 'https://www.thinkmill.com.au';

    attemptToOpenUrl(url);
  }

  openRepository() {
    const url = 'https://github.com/Thinkmill/react-conf-2017';
    attemptToOpenUrl(url);
  }

  render() {
    const { navigator, organisers } = this.props;
    const { modalIsOpen } = this.state;

    return (
      <Scene>
        <Navbar
          title="Event Info"
          leftButtonIconName="ios-arrow-back"
          leftButtonOnPress={navigator.popToTop}
        />
        <ScrollView>
          <MapView initialRegion={mapRegion} style={styles.map}>
            <MapView.Marker
              coordinate={mapRegion}
              title="Santa Clara Marriott"
              description="2700 Mission College Blvd, Santa Clara, CA 95054"
              ref="marker"
            />
          </MapView>

          <View style={{ flex: 1 }}>
            <View style={styles.hero}>
              <Text style={styles.heroText}>
                The conference will be taking place on March 13th and 14th, with talks from 10am to 6pm each day. Plan to hang out with us each evening for plenty of socializing over food and drink.
              </Text>
              <Text style={styles.heroText}>
                Proceeds from all ticket sales are being donated to Code2040.
              </Text>
              <TouchableOpacity onPress={this.toggleModal} activeOpacity={0.75}>
                <Text style={styles.heroLink}>
                  Code of Conduct
                </Text>
              </TouchableOpacity>
            </View>

            <ListTitle text="Organizers" />
            {organisers.map((organiser, idx) => {
              const onPress = () => {};

              return (
                <Organiser
                  avatar={organiser.avatar}
                  key={idx}
                  onPress={onPress}
                  name={organiser.name}
                  summary={organiser.summary}
                />
              );
            })}

            <View style={styles.madeby}>
              <TouchableOpacity
                onPress={this.openThinkmill}
                activeOpacity={0.75}
                style={styles.madebyLink}
              >
                <Image
                  source={require('./images/thinkmill-logo.png')}
                  style={{ width: 80, height: 80 }}
                />
                {/* <Text style={[styles.madebyText, styles.madebyTitle]}>Made by Thinkmill</Text> */}
              </TouchableOpacity>
              <Text style={styles.madebyText}>
                This app made with love in Sydney, Australia and open sourced by Thinkmill
              </Text>
              <TouchableOpacity
                onPress={this.openRepository}
                activeOpacity={0.75}
              >
                <Text style={styles.heroLink}>
                  View Source Code
                </Text>
              </TouchableOpacity>
            </View>
          </View>
        </ScrollView>

        {!!modalIsOpen && <CodeOfConduct onClose={this.toggleModal} />}
      </Scene>
    );
  }
}

const styles = StyleSheet.create({
  map: {
    flex: 1,
    height: 200,
    maxHeight: 200,
  },
  // hero
  hero: {
    alignItems: 'center',
    backgroundColor: 'white',
    borderBottomColor: theme.color.gray20,
    borderBottomWidth: 1 / PixelRatio.get(),
    borderTopColor: theme.color.gray30,
    borderTopWidth: 1 / PixelRatio.get(),
    paddingHorizontal: theme.fontSize.default,
  },
  heroText: {
    paddingTop: theme.fontSize.xlarge,
    fontSize: theme.fontSize.default,
    fontWeight: '300',
    lineHeight: theme.fontSize.large,
    textAlign: 'center',
  },
  heroLink: {
    color: theme.color.blue,
    fontSize: theme.fontSize.default,
    fontWeight: '500',
    padding: theme.fontSize.large,
  },

  // made by thinkmill
  madeby: {
    alignItems: 'center',
    paddingHorizontal: theme.fontSize.default,
    paddingVertical: theme.fontSize.xlarge,
  },
  madebyLink: {
    alignItems: 'center',
  },
  madebyText: {
    fontSize: theme.fontSize.default,
    fontWeight: '300',
    lineHeight: theme.fontSize.large,
    marginTop: theme.fontSize.default,
    textAlign: 'center',
  },
  madebyTitle: {
    fontWeight: '500',
  },
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { ActionSheetIOS, Animated, Dimensions, Easing } from 'react-native';
import moment from 'moment';

import { TIME_FORMAT } from '../../constants';
import Navbar from '../../components/Navbar';
import Scene from '../../components/Scene';

import theme from '../../theme';
import { bindMethods } from '../../utils';
import { getNextTalkFromId, getPrevTalkFromId } from '../../data/talks';

import Hint from './components/Hint';
import Speaker from './components/Speaker';
import TalkPane from './components/Pane';

export default class Talk extends Component {
	constructor (props) {
		super(props);

		bindMethods.call(this, [
			'handleScroll',
			'share',
			'toggleSpeakerModal',
		]);

		this.sceneHeight = Dimensions.get('window').height;
		this.sceneWidth = Dimensions.get('window').width;

		this.state = {
			animValue: new Animated.Value(0),
			modalIsOpen: false,
			nextTalk: props.nextTalk,
			prevTalk: props.prevTalk,
			showIntro: props.introduceUI,
			talk: props.talk,
		};
	}

	handleLayout ({ height }) {
		const availableHeight = this.sceneHeight - (height);

		this.talkpane.refs.summary.measure((left, top, width, height) => {
			if (availableHeight > height) {
				this.talkpane.refs.summary.setNativeProps({ style: { minHeight: availableHeight - theme.nextup.height } });
			}
		});

	}
	handleScroll ({ nativeEvent }) {
		const contentHeight = nativeEvent.contentSize.height;
		const viewHeight = nativeEvent.layoutMeasurement.height;
		const scrollY = nativeEvent.contentOffset.y;
		const heightOffset = contentHeight > viewHeight
			? contentHeight - viewHeight
			: 0;
		const { nextTalkPreview, prevTalkPreview, scrollview } = this.talkpane.refs;
		const { nextTalk, prevTalk } = this.state;

		if (scrollY > 0 && nextTalkPreview) {
			const opacity = Math.min((scrollY - (heightOffset + 20)) / 100, 1);
			nextTalkPreview.setNativeProps({ style: { opacity } });
		} else if (prevTalkPreview) {
			const opacity = Math.min(Math.abs(scrollY + 20) / 100, 1);
			prevTalkPreview.setNativeProps({ style: { opacity } });
		}

		const jumpToNext = nextTalk && (scrollY > (heightOffset + 110));
		const jumpToPrev = prevTalk && (scrollY < -110);

		if (jumpToNext) {
			scrollview.setNativeProps({
				scrollEnabled: false,
				bounces: false,
			});
			this.renderNextTalk();
		} else if (jumpToPrev) {
			scrollview.setNativeProps({
				bounces: false,
				scrollEnabled: false,
			});
			this.renderPrevTalk();
		}
	}
	renderNextTalk () {
		const talk = this.state.nextTalk;
		const nextTalk = this.state.nextTalk
			? getNextTalkFromId(this.state.nextTalk.id)
			: null;
		const prevTalk = this.state.talk;

		this.setTalks({ nextTalk, prevTalk, talk }, 'next');
	}
	renderPrevTalk () {
		const talk = this.state.prevTalk;
		const nextTalk = this.state.talk;
		const prevTalk = this.state.prevTalk
			? getPrevTalkFromId(this.state.prevTalk.id)
			: null;

		this.setTalks({ nextTalk, prevTalk, talk }, 'prev');
	}
	setTalks (newState, transitionDirection) {
		this.setState({
			incomingTalk: newState.talk,
			transitionDirection,
		}, () => {
			Animated.spring(this.state.animValue, {
				toValue: 1,
				friction: 7,
				tension: 30,
			}).start(() => {
				this.setState(Object.assign(newState, { incomingTalk: null }), () => {
					this.state.animValue.setValue(0);
					this.talkpane.refs.scrollview.setNativeProps({
						bounces: true,
						scrollEnabled: true,
					});
					this.talkpane.refs.scrollview.scrollTo({ y: 0, animated: false });
				});
			});
		});
	}
	share () {
		const { talk } = this.state;
		const speakerHandle = talk.speaker.twitter
			? ('@' + talk.speaker.twitter)
			: talk.speaker.name;

		ActionSheetIOS.showShareActionSheetWithOptions({
			message: `Enjoying ${speakerHandle}'s talk "${talk.title}" #ReactConf2017`,
		},
		(error) => alert(error),
		(success, method) => {
			const result = success ? `Shared via ${method}` : 'Share cancelled';

			console.log(result);
		});
	}
	toggleSpeakerModal (modalIsOpen) {
		this.setState({ modalIsOpen });
	}
	render () {
		const { navigator } = this.props;
		const {
			animValue,
			modalIsOpen,
			nextTalk,
			incomingTalk,
			prevTalk,
			showIntro,
			talk,
		} = this.state;

		const headerTitle = moment(talk.time.start).format(TIME_FORMAT);
		const availableHeight = this.sceneHeight - theme.navbar.height;

		const incomingFrom = this.state.transitionDirection === 'next'
			? this.sceneHeight
			: -this.sceneHeight;
		const outgoingTo = this.state.transitionDirection === 'next'
			? -this.sceneHeight
			: this.sceneHeight;

		const transitionStyles = {
			height: availableHeight,
			position: 'absolute',
			top: theme.navbar.height,
			width: this.sceneWidth,
		};
		const incomingTransitionStyles = {
			transform: [{
				translateY: animValue.interpolate({
					inputRange: [0, 1],
					outputRange: [incomingFrom, 0],
				}),
			}],
		};
		const outgoingTransitionStyles = {
			transform: [{
				translateY: animValue.interpolate({
					inputRange: [0, 1],
					outputRange: [0, outgoingTo],
				}),
			}],
		};

		// navbar must be rendered after the talk panes for visibility
		const navbar = (
			<Navbar
				title={headerTitle}
				leftButtonIconName="ios-arrow-back"
				leftButtonOnPress={navigator.popToTop}
				rightButtonText="Share"
				rightButtonOnPress={this.share}
			/>
		);

		return (
			<Scene>
				<Animated.View style={[transitionStyles, outgoingTransitionStyles]}>
					<TalkPane
						nextTalk={nextTalk}
						onHeroLayout={({ nativeEvent: { layout } }) => this.handleLayout(layout)}
						onScroll={this.handleScroll}
						prevTalk={prevTalk}
						ref={r => (this.talkpane = r)}
						showSpeakerModal={() => this.toggleSpeakerModal(true)}
						visibleTalk={talk}
					/>
				</Animated.View>
				{!!incomingTalk && (
					<Animated.View style={[transitionStyles, incomingTransitionStyles]} pointerEvents="none">
						<TalkPane
							visibleTalk={incomingTalk}
							ref={r => (this.transitionpane = r)}
						/>
					</Animated.View>
				)}

				{showIntro && (
					<Hint
						onClose={() => this.setState({ showIntro: false })}
					/>
				)}

				{modalIsOpen && (
					<Speaker
						avatar={talk.speaker.avatar}
						github={talk.speaker.github}
						name={talk.speaker.name}
						onClose={() => this.toggleSpeakerModal(false)}
						summary={talk.speaker.summary}
						twitter={talk.speaker.twitter}
					/>
				)}
				{navbar}
			</Scene>
		);
	}
};

Talk.propTypes = {
	navigator: PropTypes.object.isRequired,
	talk: PropTypes.object.isRequired,
};
Talk.defaultProps = {
	talk: {
		id: 'max-stoiber',
		summary: 'What if we took the best of JavaScript and the best of CSS, and combined them together to create the ultimate styling solution for React? Glen Maddern (CSS Modules co-creator) and I sat down and starting thinking about this. Let\'s talk about what we thought about and why we arrived where we did – 💅 styled-components.',
		title: 'The Road to Styled Components',
		speaker: {
			avatar: 'https://www.gravatar.com/avatar/48619fc17b3ab68472aebd56c0106278?s=128',
			github: 'mxstbr',
			name: 'Max Stoiber',
			twitter: 'mxstbr',
			summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi a finibus ligula, sed congue eros. Proin nunc nunc, facilisis sit amet tempor et, finibus eu turpis.',
		},
		time: {
			start: new Date('2017-02-26T22:30:00.000Z'),
			end: new Date('2017-02-26T23:30:00.000Z'),
		},
	},
};
<commit_msg>fix linter warning<commit_after>import React, { Component, PropTypes } from 'react';
import { ActionSheetIOS, Animated, Dimensions } from 'react-native';
import moment from 'moment';

import { TIME_FORMAT } from '../../constants';
import Navbar from '../../components/Navbar';
import Scene from '../../components/Scene';

import theme from '../../theme';
import { bindMethods } from '../../utils';
import { getNextTalkFromId, getPrevTalkFromId } from '../../data/talks';

import Hint from './components/Hint';
import Speaker from './components/Speaker';
import TalkPane from './components/Pane';

export default class Talk extends Component {
	constructor (props) {
		super(props);

		bindMethods.call(this, [
			'handleScroll',
			'share',
			'toggleSpeakerModal',
		]);

		this.sceneHeight = Dimensions.get('window').height;
		this.sceneWidth = Dimensions.get('window').width;

		this.state = {
			animValue: new Animated.Value(0),
			modalIsOpen: false,
			nextTalk: props.nextTalk,
			prevTalk: props.prevTalk,
			showIntro: props.introduceUI,
			talk: props.talk,
		};
	}

	handleLayout ({ height }) {
		const availableHeight = this.sceneHeight - (height);

		this.talkpane.refs.summary.measure((left, top, width, height) => {
			if (availableHeight > height) {
				this.talkpane.refs.summary.setNativeProps({ style: { minHeight: availableHeight - theme.nextup.height } });
			}
		});

	}
	handleScroll ({ nativeEvent }) {
		const contentHeight = nativeEvent.contentSize.height;
		const viewHeight = nativeEvent.layoutMeasurement.height;
		const scrollY = nativeEvent.contentOffset.y;
		const heightOffset = contentHeight > viewHeight
			? contentHeight - viewHeight
			: 0;
		const { nextTalkPreview, prevTalkPreview, scrollview } = this.talkpane.refs;
		const { nextTalk, prevTalk } = this.state;

		if (scrollY > 0 && nextTalkPreview) {
			const opacity = Math.min((scrollY - (heightOffset + 20)) / 100, 1);
			nextTalkPreview.setNativeProps({ style: { opacity } });
		} else if (prevTalkPreview) {
			const opacity = Math.min(Math.abs(scrollY + 20) / 100, 1);
			prevTalkPreview.setNativeProps({ style: { opacity } });
		}

		const jumpToNext = nextTalk && (scrollY > (heightOffset + 110));
		const jumpToPrev = prevTalk && (scrollY < -110);

		if (jumpToNext) {
			scrollview.setNativeProps({
				scrollEnabled: false,
				bounces: false,
			});
			this.renderNextTalk();
		} else if (jumpToPrev) {
			scrollview.setNativeProps({
				bounces: false,
				scrollEnabled: false,
			});
			this.renderPrevTalk();
		}
	}
	renderNextTalk () {
		const talk = this.state.nextTalk;
		const nextTalk = this.state.nextTalk
			? getNextTalkFromId(this.state.nextTalk.id)
			: null;
		const prevTalk = this.state.talk;

		this.setTalks({ nextTalk, prevTalk, talk }, 'next');
	}
	renderPrevTalk () {
		const talk = this.state.prevTalk;
		const nextTalk = this.state.talk;
		const prevTalk = this.state.prevTalk
			? getPrevTalkFromId(this.state.prevTalk.id)
			: null;

		this.setTalks({ nextTalk, prevTalk, talk }, 'prev');
	}
	setTalks (newState, transitionDirection) {
		this.setState({
			incomingTalk: newState.talk,
			transitionDirection,
		}, () => {
			Animated.spring(this.state.animValue, {
				toValue: 1,
				friction: 7,
				tension: 30,
			}).start(() => {
				this.setState(Object.assign(newState, { incomingTalk: null }), () => {
					this.state.animValue.setValue(0);
					this.talkpane.refs.scrollview.setNativeProps({
						bounces: true,
						scrollEnabled: true,
					});
					this.talkpane.refs.scrollview.scrollTo({ y: 0, animated: false });
				});
			});
		});
	}
	share () {
		const { talk } = this.state;
		const speakerHandle = talk.speaker.twitter
			? ('@' + talk.speaker.twitter)
			: talk.speaker.name;

		ActionSheetIOS.showShareActionSheetWithOptions({
			message: `Enjoying ${speakerHandle}'s talk "${talk.title}" #ReactConf2017`,
		},
		(error) => alert(error),
		(success, method) => {
			const result = success ? `Shared via ${method}` : 'Share cancelled';

			console.log(result);
		});
	}
	toggleSpeakerModal (modalIsOpen) {
		this.setState({ modalIsOpen });
	}
	render () {
		const { navigator } = this.props;
		const {
			animValue,
			modalIsOpen,
			nextTalk,
			incomingTalk,
			prevTalk,
			showIntro,
			talk,
		} = this.state;

		const headerTitle = moment(talk.time.start).format(TIME_FORMAT);
		const availableHeight = this.sceneHeight - theme.navbar.height;

		const incomingFrom = this.state.transitionDirection === 'next'
			? this.sceneHeight
			: -this.sceneHeight;
		const outgoingTo = this.state.transitionDirection === 'next'
			? -this.sceneHeight
			: this.sceneHeight;

		const transitionStyles = {
			height: availableHeight,
			position: 'absolute',
			top: theme.navbar.height,
			width: this.sceneWidth,
		};
		const incomingTransitionStyles = {
			transform: [{
				translateY: animValue.interpolate({
					inputRange: [0, 1],
					outputRange: [incomingFrom, 0],
				}),
			}],
		};
		const outgoingTransitionStyles = {
			transform: [{
				translateY: animValue.interpolate({
					inputRange: [0, 1],
					outputRange: [0, outgoingTo],
				}),
			}],
		};

		// navbar must be rendered after the talk panes for visibility
		const navbar = (
			<Navbar
				title={headerTitle}
				leftButtonIconName="ios-arrow-back"
				leftButtonOnPress={navigator.popToTop}
				rightButtonText="Share"
				rightButtonOnPress={this.share}
			/>
		);

		return (
			<Scene>
				<Animated.View style={[transitionStyles, outgoingTransitionStyles]}>
					<TalkPane
						nextTalk={nextTalk}
						onHeroLayout={({ nativeEvent: { layout } }) => this.handleLayout(layout)}
						onScroll={this.handleScroll}
						prevTalk={prevTalk}
						ref={r => (this.talkpane = r)}
						showSpeakerModal={() => this.toggleSpeakerModal(true)}
						visibleTalk={talk}
					/>
				</Animated.View>
				{!!incomingTalk && (
					<Animated.View style={[transitionStyles, incomingTransitionStyles]} pointerEvents="none">
						<TalkPane
							visibleTalk={incomingTalk}
							ref={r => (this.transitionpane = r)}
						/>
					</Animated.View>
				)}

				{showIntro && (
					<Hint
						onClose={() => this.setState({ showIntro: false })}
					/>
				)}

				{modalIsOpen && (
					<Speaker
						avatar={talk.speaker.avatar}
						github={talk.speaker.github}
						name={talk.speaker.name}
						onClose={() => this.toggleSpeakerModal(false)}
						summary={talk.speaker.summary}
						twitter={talk.speaker.twitter}
					/>
				)}
				{navbar}
			</Scene>
		);
	}
};

Talk.propTypes = {
	navigator: PropTypes.object.isRequired,
	talk: PropTypes.object.isRequired,
};
Talk.defaultProps = {
	talk: {
		id: 'max-stoiber',
		summary: 'What if we took the best of JavaScript and the best of CSS, and combined them together to create the ultimate styling solution for React? Glen Maddern (CSS Modules co-creator) and I sat down and starting thinking about this. Let\'s talk about what we thought about and why we arrived where we did – 💅 styled-components.',
		title: 'The Road to Styled Components',
		speaker: {
			avatar: 'https://www.gravatar.com/avatar/48619fc17b3ab68472aebd56c0106278?s=128',
			github: 'mxstbr',
			name: 'Max Stoiber',
			twitter: 'mxstbr',
			summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi a finibus ligula, sed congue eros. Proin nunc nunc, facilisis sit amet tempor et, finibus eu turpis.',
		},
		time: {
			start: new Date('2017-02-26T22:30:00.000Z'),
			end: new Date('2017-02-26T23:30:00.000Z'),
		},
	},
};
<|endoftext|>


<commit_before>app.controller('startController', function ($rootScope, $scope, timeService, SettingService, NotificationsService) {
    $scope.time = {
        value: "00:00"
    };

    /**
     * 初始化倒计时时间
     * @param type 当前的状态
     */
    var init = function (type) {
        SettingService.read(function (result) {
            $scope.time.value = result[0][type] + ":00";
            $scope.$apply();
        });
    };
    init($rootScope.status.type);

    var notifyCallback = function (id, buttonIndex) {
        if (buttonIndex === 0) {
            $scope.start($rootScope.status.type);
        }

        chrome.notifications.clear(id);
    };
    chrome.notifications.onButtonClicked.addListener(notifyCallback);

    /**
     * 开启计时程序
     * @param type 当前的状态
     */
    $scope.start = function (type) {
        // 计时器图标状态
        $rootScope.status.underway = !$rootScope.status.underway;

        var _fn = timeService.start(type);

        $scope.timer = setInterval(function () {
            var count = _fn();
            if (count == -1) {
                clearInterval($scope.timer);
                end(type);
            } else {
                $scope.time.value = timeService.timeFormat(count);
                $scope.$apply();
            }
        }, 1000);
    };

    /**
     * 用户终止计时
     */
    $scope.stop = function (type) {
        $rootScope.status.underway = !$rootScope.status.underway;
        clearInterval($scope.timer);
        init(type);
    };

    // intervalCount， longRestTime， shortRestTime， workTime
    var end = function (type) {
        $rootScope.status.underway = !$rootScope.status.underway;

        if (type === "workTime") {
            // 工作时间转过来的， 次数加一
            $rootScope.status.workCount += 1;

            if ($rootScope.status.workCount != $rootScope.settingInfo.intervalCount) { // 未到长休息时间
                $rootScope.status.type = "shortRestTime"; // 转入短休息
            } else {
                $rootScope.status.type = "longRestTime";  // 转入长休息
            }
            // 显示休息通知
            NotificationsService.sendNotifications('work2rest');
        } else {
            // 统计休息次数
            if ($rootScope.status.type === 'shortRestTime') {
                $rootScope.status.shortRestCount += 1;
            } else {
                $rootScope.status.longRestCount += 1;
            }

            $rootScope.status.type = "workTime";

            // 显示工作通知
            NotificationsService.sendNotifications('rest2work');
        }
        init($rootScope.status.type);
    };

})
    .controller('listController', function ($rootScope, $scope, uiService, TodoService, StatusService) {
        // 保持高度自适应
        uiService.setHeight();

        $scope.todoList = {
            undo: [],
            does: []
        };

        $scope.status = {
            isShow: true
        };

        $scope.getTodoList = function () {
            TodoService.read(function (result) {
                var today = Date.now();

                $scope.todoList.undo = result.filter(function (val) {
                    return !val.completed;
                });
                $scope.todoList.does = result.filter(function (val) {
                    // 只保存距现在24小时之前的内容
                    return val.completed && ((today - val.id) / (24 * 60 * 60 * 1000) < 1);
                });
                $scope.$apply();
            });
        };
        $scope.getTodoList();

        $scope.addItem = function ($event) {
            var keycode = $event.keyCode;
            // enter code 13
            if (keycode === 13) {
                TodoService.create($scope.title, $scope.getTodoList);
                $scope.title = "";
            }
        };

        $scope.completeItem = function ($event, type) {
            var target = $event.target,
                id = target.parentNode.id,
                update = null;

            // type === 1 => completed  0 => uncompleted
            if (type === 1) {
                update = {
                    completed: type,
                    workCount: $rootScope.status.workCount,
                    shortRestCount: $rootScope.status.shortRestCount,
                    longRestCount: $rootScope.status.longRestCount
                };
                StatusService.resetCount();
            } else {
                update = {
                    completed: type,
                    workCount: 0,
                    shortRestCount: 0,
                    longRestCount: 0
                }
            }

            TodoService.update(id, update, $scope.getTodoList);
        };

        $scope.deleteItem = function ($event) {
            var target = $event.target,
                id = target.parentNode.id;

            TodoService.remove(id, $scope.getTodoList);
        };

        $scope.toggle = function () {
            $scope.status.isShow = !$scope.status.isShow;
            console.log($scope.status.isShow);
        }
    })
    .controller('historyController', function ($scope, uiService, TodoService) {
        uiService.setHeight();

        $scope.history = [];

        $scope.getHistory = function () {
            TodoService.read(function (result) {
                var today = Date.now();

                $scope.history = result.filter(function (val) {
                    // 只保存距现在24小时之前的内容
                    return val.completed && ((today - val.id) / (24 * 60 * 60 * 1000) >= 1);
                });
                $scope.$apply();
            });
        };
        $scope.getHistory();

    })
    .controller('settingController', function ($rootScope, $scope, uiService, SettingService) {
        uiService.setHeight();

        $scope.changeValue = function (type) {
            var updateVal = {};
            updateVal[type] = $rootScope.settingInfo[type];

            SettingService.update("key", updateVal, function () {
            });
        }
    });<commit_msg>merage<commit_after>app.controller('startController', function ($rootScope, $scope, timeService, SettingService, NotificationsService) {
    $scope.time = {
        value: "00:00"
    };

    /**
     * 初始化倒计时时间
     * @param type 当前的状态
     */
    var init = function (type) {
        SettingService.read(function (result) {
            $scope.time.value = result[0][type] + ":00";
            $scope.$apply();
        });
    };
    init($rootScope.status.type);

    var notifyCallback = function (id, buttonIndex) {
        if (buttonIndex === 0) {
            $scope.start($rootScope.status.type);
        }

        chrome.notifications.clear(id);
    };
    chrome.notifications.onButtonClicked.addListener(notifyCallback);

    /**
     * 开启计时程序
     * @param type 当前的状态
     */
    $scope.start = function (type) {
        // 计时器图标状态
        $rootScope.status.underway = !$rootScope.status.underway;

        var _fn = timeService.start(type);

        $scope.timer = setInterval(function () {
            var count = _fn();
            if (count == -1) {
                clearInterval($scope.timer);
                end(type);
            } else {
                $scope.time.value = timeService.timeFormat(count);
                $scope.$apply();
            }
        }, 1000);
    };

    /**
     * 用户终止计时
     */
    $scope.stop = function (type) {
        $rootScope.status.underway = !$rootScope.status.underway;
        clearInterval($scope.timer);
        init(type);
    };

    // intervalCount， longRestTime， shortRestTime， workTime
    var end = function (type) {
        $rootScope.status.underway = !$rootScope.status.underway;

        if (type === "workTime") {
            // 工作时间转过来的， 次数加一
            $rootScope.status.workCount += 1;

            if ($rootScope.status.workCount != $rootScope.settingInfo.intervalCount) { // 未到长休息时间
                $rootScope.status.type = "shortRestTime"; // 转入短休息
            } else {
                $rootScope.status.type = "longRestTime";  // 转入长休息
            }
            // 显示休息通知
            NotificationsService.sendNotifications('work2rest');
        } else {
            // 统计休息次数
            if ($rootScope.status.type === 'shortRestTime') {
                $rootScope.status.shortRestCount += 1;
            } else {
                $rootScope.status.longRestCount += 1;
            }

            $rootScope.status.type = "workTime";

            // 显示工作通知
            NotificationsService.sendNotifications('rest2work');
        }
        init($rootScope.status.type);
    };

})
    .controller('listController', function ($rootScope, $scope, uiService, TodoService, StatusService) {
        // 保持高度自适应
        uiService.setHeight();

        $scope.todoList = {
            undo: [],
            does: []
        };

        $scope.status = {
            isShow: true
        };

        $scope.getTodoList = function () {
            TodoService.read(function (result) {
                var today = Date.now();

                $scope.todoList.undo = result.filter(function (val) {
                    return !val.completed;
                });
                $scope.todoList.does = result.filter(function (val) {
                    // 只保存距现在24小时之前的内容
                    return val.completed && ((today - val.id) / (24 * 60 * 60 * 1000) < 1);
                });
                $scope.$apply();
            });
        };
        $scope.getTodoList();

        $scope.addItem = function ($event) {
            var keycode = $event.keyCode;
            // enter code 13
            if (keycode === 13) {
                TodoService.create($scope.title, $scope.getTodoList);
                $scope.title = "";
            }
        };

        $scope.completeItem = function ($event, type) {
            var target = $event.target,
                id = target.parentNode.id,
                update = null;

            // type === 1 => completed  0 => uncompleted
            if (type === 1) {
                update = {
                    completed: type,
                    workCount: $rootScope.status.workCount,
                    shortRestCount: $rootScope.status.shortRestCount,
                    longRestCount: $rootScope.status.longRestCount
                };
                StatusService.resetCount();
            } else {
                update = {
                    completed: type,
                    workCount: 0,
                    shortRestCount: 0,
                    longRestCount: 0
                }
            }

            TodoService.update(id, update, $scope.getTodoList);
        };

        $scope.deleteItem = function ($event) {
            var target = $event.target,
                id = target.parentNode.id;

            TodoService.remove(id, $scope.getTodoList);
        };

        $scope.toggle = function () {
            $scope.status.isShow = !$scope.status.isShow;
            console.log($scope.status.isShow);
        }
    })
    .controller('historyController', function ($scope, uiService, TodoService) {
        uiService.setHeight();
        $scope.history = [];

        $scope.getHistory = function () {
            TodoService.read(function (result) {
                var today = Date.now();

                $scope.history = result.filter(function (val) {
                    // 只保存距现在24小时之前的内容
                    return val.completed && ((today - val.id) / (24 * 60 * 60 * 1000) >= 1);
                });
                $scope.$apply();
            });
        };
        $scope.getHistory();
    })
    .controller('settingController', function ($rootScope, $scope, uiService, SettingService) {
        uiService.setHeight();

        $scope.changeValue = function (type) {
            var updateVal = {};
            updateVal[type] = $rootScope.settingInfo[type];

            SettingService.update("key", updateVal, function () {
            });
        }
    });<|endoftext|>


<commit_before>var cctvCollection = require('../collections/cctvCollection.js'),
    cctvModel = require('../models/cctvModel.js'),
    cctvTemplate = require('../templates/map.html');

L.Icon.Default.imagePath = 'images';

module.exports = Backbone.View.extend({
    template: _.template(cctvTemplate),
    collection: new cctvCollection(),
    cam: new cctvModel(),
    map: {},
    addCamMarker: {},
    initialize: function(options) {
        this.vent = options.vent;
        _.bindAll(this, 'closeInfo','drawCam', 'toggleOverlay', 'hideOverlay', 'showOverlay', 'setView', 'createMarker', 'removeMarker');

        this.vent.on('toggle:overlay', this.toggleOverlay);
        this.vent.on('hide:overlay', this.hideOverlay);
        this.vent.on('show:overlay', this.showOverlay);
        this.vent.on('retrieveMapPosition', this.retrieveMapPosition);
        this.vent.on('map:setView', this.setView);
        this.vent.on('map:createMarker', this.createMarker);
        this.vent.on('map:removeMarker', this.removeMarker);

        this.collection.on('add', this.drawCam);

        $(document).on('click', '.caminfo .close-btn', this.closeInfo)

        this.render();
    },
    closeInfo: function(){
        $('#details').css({ bottom : '-1000px' });
    },
    render: function() {

        this.$el.html(this.template());

        this.initMap();
        this.collection.fetch();

        return this;
    },

    setView: function(params) {
        this.map.setView(params.latlng, params.zoom);
    },

    createMarker: function(params) {

        // handle marker without geolocated user
        if (params.latlng === -1) {
            params.latlng = this.map.getCenter();
            this.vent.trigger('addcam:updateMarker', {
                latlng: params.latlng
            })
        }

        this.map.setView(params.latlng, config.map.detailZoom);

        this.addCamMarker = new L.Marker(params.latlng, {
            draggable: true
        });

        this.addCamMarker.on('drag', _.bind(function(e) {
            this.vent.trigger('addcam:updateMarker', {
                latlng: this.addCamMarker._latlng
            })
        }, this));

        this.addCamMarker.addTo(this.map);

    },
    removeMarker: function() {
        if (typeof this.addCamMarker._latlng !== 'undefined') {
            this.map.removeLayer(this.addCamMarker);
        }
    },
    initMap: function() {
        this.map = new L.Map('map', {
            center: config.map.center,
            zoom: config.map.initZoom,
            zoomControl: false
        });
        var tileLayer = new L.TileLayer(config.map.tilesURL, {
            attribution: config.map.label
        }).addTo(this.map);

        // new OSMBuildings(this.map).loadData();
    },

    drawCam: function(model) {
        var latlng = model.get('location');
        if (latlng[0] && latlng[1]) {

            var circle = L.circle(latlng, 15, {
                fill: true,
                stroke: false,
                fillColor: 'rgb(231,76,60)',
                fillOpacity: .5
            });

            circle.on('click', function(){
                latlng[0] -= 0.005;
                this.map.setView(latlng, this.map.getZoom());

                this.vent.trigger('route:caminfo', '!/info/' + model.get('id'))
            }.bind(this));

            circle.addTo(this.map);

        }
    },
    hideOverlay: function() {
        $('.map-overlay').removeClass('active');
    },
    showOverlay: function() {
        $('.map-overlay').addClass('active');
    },
    toggleOverlay: function() {
        $('.map-overlay').toggleClass('active');
    }
});<commit_msg>changed map<commit_after>var cctvCollection = require('../collections/cctvCollection.js'),
    cctvModel = require('../models/cctvModel.js'),
    cctvTemplate = require('../templates/map.html');

L.Icon.Default.imagePath = 'images';

module.exports = Backbone.View.extend({
    template: _.template(cctvTemplate),
    collection: new cctvCollection(),
    cam: new cctvModel(),
    map: {},
    addCamMarker: {},
    initialize: function(options) {
        this.vent = options.vent;
        _.bindAll(this, 'closeInfo','drawCam', 'toggleOverlay', 'hideOverlay', 'showOverlay', 'setView', 'createMarker', 'removeMarker');

        this.vent.on('toggle:overlay', this.toggleOverlay);
        this.vent.on('hide:overlay', this.hideOverlay);
        this.vent.on('show:overlay', this.showOverlay);
        this.vent.on('retrieveMapPosition', this.retrieveMapPosition);
        this.vent.on('map:setView', this.setView);
        this.vent.on('map:createMarker', this.createMarker);
        this.vent.on('map:removeMarker', this.removeMarker);

        this.collection.on('add', this.drawCam);

        $(document).on('click', '.caminfo .close-btn', this.closeInfo)

        this.render();
    },
    closeInfo: function(){
        $('#details').css({ bottom : '-1000px' });
    },
    render: function() {

        this.$el.html(this.template());

        this.initMap();
        this.collection.fetch();

        return this;
    },

    setView: function(params) {
        this.map.setView(params.latlng, params.zoom);
    },

    createMarker: function(params) {

        // handle marker without geolocated user
        if (params.latlng === -1) {
            params.latlng = this.map.getCenter();
            this.vent.trigger('addcam:updateMarker', {
                latlng: params.latlng
            })
        }

        this.map.setView(params.latlng, config.map.detailZoom);

        this.addCamMarker = new L.Marker(params.latlng, {
            draggable: true
        });

        this.addCamMarker.on('drag', _.bind(function(e) {
            this.vent.trigger('addcam:updateMarker', {
                latlng: this.addCamMarker._latlng
            })
        }, this));

        this.addCamMarker.addTo(this.map);

    },
    removeMarker: function() {
        if (typeof this.addCamMarker._latlng !== 'undefined') {
            this.map.removeLayer(this.addCamMarker);
        }
    },
    initMap: function() {
        this.map = new L.Map('map', {
            center: config.map.center,
            zoom: config.map.initZoom,
            zoomControl: false,
            minZoom: 6
        });
        var tileLayer = new L.TileLayer(config.map.tilesURL, {
            attribution: config.map.label
        }).addTo(this.map);

        // new OSMBuildings(this.map).loadData();
    },

    drawCam: function(model) {
        var latlng = model.get('location');
        if (latlng[0] && latlng[1]) {

            var circle = L.circle(latlng, 15, {
                fill: true,
                stroke: false,
                fillColor: 'rgb(231,76,60)',
                fillOpacity: .5
            });

            circle.on('click', function(){
                latlng[0] -= 0.005;
                this.map.setView(latlng, this.map.getZoom());

                this.vent.trigger('route:caminfo', '!/info/' + model.get('id'))
            }.bind(this));

            circle.addTo(this.map);

        }
    },
    hideOverlay: function() {
        $('.map-overlay').removeClass('active');
    },
    showOverlay: function() {
        $('.map-overlay').addClass('active');
    },
    toggleOverlay: function() {
        $('.map-overlay').toggleClass('active');
    }
});<|endoftext|>


<commit_before>var gpio = require("gpio");
var moment = require("moment");

// pin 38 GPIO 20 - for trigger
let trig = gpio.export(38, {
   direction: "out",
   interval: 10,
   ready: function() {
   }
});

// pin 37 GPIO 26 - for echo
let echo = gpio.export(37, {
   direction: "in",
   interval: 50,
   ready: function() {
   }
});

var getDistance = function() {

  // resetting trigger
  trig.set(0);
  console.log("initial trig value (0): " + trig.value); // should be 0

  responsiveVoice.speak(" ");
  var monitor = true;
  var timestamp = moment().add(30, 's');

  // set up recursive loop
  function monitorWithTimeout() {

    console.log("monitoring");
    var pulseStart = moment().millisecond();

    // trigger on, then off then  monitor on change
    trig.set(function() {

      console.log("1 trig value (1): " + trig.value) // should be 1
      setTimeout(function() {

        trig.set(0, function() {
           console.log("2 trig value (0): " + trig.value) // should be 0

           console.log("echo value: " + echo.value)
           echo.on("change", function(val) {

             console.log("on change")

           });
        });

      }, 15);

    });

    setTimeout(function () {

      console.log("")
      // echo.removeAllListeners('change');
      if (moment().isBefore(timestamp) && monitor) {
        monitorWithTimeout();
      };

    }, 2000);
  }

  monitorWithTimeout();
};

module.exports = {
  getDistance : getDistance
};
<commit_msg>updated proximity file to simple example<commit_after>import gpio from 'gpio';
import moment from 'moment';

// pin 38 GPIO 20 - for trigger
const trig = gpio.export(38, {
  direction: 'out'
});

// pin 37 GPIO 26 - for echo
const echo = gpio.export(37, {
  direction: 'in'
});

function getDistance() {
  // resetting trigger
  trig.set(0);
  setTimeout(500);
  console.log("initial trig value (0): " + trig.value); // should be 0
  responsiveVoice.speak('');
  const timestamp = moment().add(30, 's');
  let start = 0;
  let end = 0;

  while (moment().isBefore(timestamp)) {
    trig.set();
    setTimeout(10);
    trig.set(0);

    while (echo.value === 0) {
      start = moment();
      console.log('Echo is 0');
    }

    while (echo.value === 1) {
      end = moment();
      console.log('Echo is 1');
    }
  }
  console.log('Start time = ' + start + ' End Time = ' + end);
  // set up recursive loop
  // function monitorWithTimeout() {

  //   console.log("monitoring");
  //   var pulseStart = moment().millisecond();

  //   // trigger on, then off then  monitor on change
  //   trig.set(function() {

  //     console.log("1 trig value (1): " + trig.value) // should be 1
  //     setTimeout(function() {

  //       trig.set(0, function() {
  //          console.log("2 trig value (0): " + trig.value) // should be 0

  //          console.log("echo value: " + echo.value)
  //          echo.on("change", function(val) {

  //            console.log("on change")

  //          });
  //       });

  //     }, 15);

  //   });

  //   setTimeout(function () {

  //     console.log("")
  //     // echo.removeAllListeners('change');
  //     if (moment().isBefore(timestamp) && monitor) {
  //       monitorWithTimeout();
  //     };

  //   }, 2000);
  // }

  // monitorWithTimeout();
}

module.exports = {
  getDistance
};
<|endoftext|>


<commit_before>(function () {
    'use strict';

    var serviceID = 'gamesAPI';
	var ns = 'hearthboard.' + serviceID;

	angular.module('hearthboard').factory(serviceID, ['$http', 'userAPI', gamesAPI]);
	function gamesAPI($http, userAPI){

		function submitConstructedMatch(match){
			/*
				required: ownClass, opponentClass, coin, result
				- Controller can autofill ownClass on deck selection, and specify defaults for all values
			*/
			var userID = userAPI.getUserID();
			var sessionID = userAPI.getSessionID();
			console.log('submitting constructed match with userID: ' + userID + ' sessionID: ' + sessionID + ' ownClass: ' + match.ownClass + ' opponentClass: ' + match.opponentClass);
			return $http({
				url: 'http://apsis.me/Hearthboard/lib/Constructed/Constructed_cc.php',
				method: 'POST',
				data: {
					action: 'submitConstructedMatch',
					userID: userID,
					sessionID: sessionID,
					ownClass: match.ownClass,
					deckID: (match.deckID ? match.deckID : ''),
					opponentClass: match.opponentClass,
					coin: match.coin,
					result: match.result,
					comments: (match.comments ? match.comments : ''),
					seasonID: (match.seasonID ? match.seasonID : 0)
				}
			}).then(
				function(response){
					console.log('server response: ' + JSON.stringify(response.data));
					if(response.data['newSessionID']){
						userAPI.setSessionID(response.data['newSessionID']);
						if(response.data['responseCode'] == 'success'){
							//do something? or handle in calling controller
						}
					}
					return response;
				}
			).catch(
				function(response) {
					console.log('status: ' + response.status + ' data: ' + JSON.stringify(response.data));
					return response;
				}
			);
		};

		//returns the current user's constructed match history for the specified season
		//	if seasonID is 0, returns all matches
		function getConstructedMatches(seasonID){
			var userID = userAPI.getUserID();
			var sessionID = userAPI.getSessionID();
			console.log('getting constructed matches for userID: ' + userID  + ' seasonID: ' + seasonID + ' sessionID: ' + sessionID);
			return $http({
				url: 'http://apsis.me/Hearthboard/lib/Constructed/Constructed_cc.php',
				method: 'POST',
				data: {
					action: 'getConstructedMatches',
					userID: userID,
					sessionID: sessionID,
					seasonID: seasonID
				}
			}).then(
				function(response){
					console.log('server response: ' + JSON.stringify(response.data));
					if(response.data['newSessionID']){
						userAPI.setSessionID(response.data['newSessionID']);
						if(response.data['responseCode'] == 'success'){
							//do something? or handle in calling controller
						}
					}
					return response;
				}
			).catch(
				function(response) {
					console.log('status: ' + response.status + ' data: ' + JSON.stringify(response.data));
					return response;
				}
			);
		};

		return{
			submitConstructedMatch: submitConstructedMatch,
			getConstructedMatches: getConstructedMatches
		}
	};
})();<commit_msg>null check<commit_after>(function () {
    'use strict';

    var serviceID = 'gamesAPI';
	var ns = 'hearthboard.' + serviceID;

	angular.module('hearthboard').factory(serviceID, ['$http', 'userAPI', gamesAPI]);
	function gamesAPI($http, userAPI){

		function submitConstructedMatch(match){
			/*
				required: ownClass, opponentClass, coin, result
				- Controller can autofill ownClass on deck selection, and specify defaults for all values
			*/
			var userID = userAPI.getUserID();
			var sessionID = userAPI.getSessionID();
			console.log('submitting constructed match with userID: ' + userID + ' sessionID: ' + sessionID + ' ownClass: ' + match.ownClass + ' opponentClass: ' + match.opponentClass);
			return $http({
				url: 'http://apsis.me/Hearthboard/lib/Constructed/Constructed_cc.php',
				method: 'POST',
				data: {
					action: 'submitConstructedMatch',
					userID: userID,
					sessionID: sessionID,
					ownClass: match.ownClass,
					deckID: (match.deckID ? match.deckID : ''),
					opponentClass: match.opponentClass,
					coin: match.coin,
					result: match.result,
					comments: (match.comments ? match.comments : ''),
					seasonID: (match.seasonID ? match.seasonID : 0)
				}
			}).then(
				function(response){
					console.log('server response: ' + JSON.stringify(response.data));
					if(response.data['newSessionID']){
						userAPI.setSessionID(response.data['newSessionID']);
						if(response.data['responseCode'] == 'success'){
							//do something? or handle in calling controller
						}
					}
					return response;
				}
			).catch(
				function(response) {
					console.log('status: ' + response.status + ' data: ' + JSON.stringify(response.data));
					return response;
				}
			);
		};

		//returns the current user's constructed match history for the specified season
		//	if seasonID is 0, returns all matches
		function getConstructedMatches(seasonID){
			var userID = userAPI.getUserID();
			var sessionID = userAPI.getSessionID();
			console.log('getting constructed matches for userID: ' + userID  + ' seasonID: ' + seasonID + ' sessionID: ' + sessionID);
			return $http({
				url: 'http://apsis.me/Hearthboard/lib/Constructed/Constructed_cc.php',
				method: 'POST',
				data: {
					action: 'getConstructedMatches',
					userID: userID,
					sessionID: sessionID,
					seasonID: (seasonID ? seasonID : 0)
				}
			}).then(
				function(response){
					console.log('server response: ' + JSON.stringify(response.data));
					if(response.data['newSessionID']){
						userAPI.setSessionID(response.data['newSessionID']);
						if(response.data['responseCode'] == 'success'){
							//do something? or handle in calling controller
						}
					}
					return response;
				}
			).catch(
				function(response) {
					console.log('status: ' + response.status + ' data: ' + JSON.stringify(response.data));
					return response;
				}
			);
		};

		return{
			submitConstructedMatch: submitConstructedMatch,
			getConstructedMatches: getConstructedMatches
		}
	};
})();<|endoftext|>