<commit_before>const $ = require('jquery');
const React = require('react');
const ReactDOM = require('react-dom');
const _ = require('lodash');

const common = require('../common/common.js');
const spdata = require('../common/sp-data.js');
const constants = require('../common/constants.js');
const ga = require('../common/ga.js');
const DashboardHistoryButton = require('../components/DashboardHistoryButton.jsx');
const AggregateHistory = require('../components/AggregateHistory.jsx');
const AggregateKeywords = require('../components/AggregateKeywords.jsx');
const AmsCampaignRow = require('../components/AmsCampaignRow.jsx');
const AmsCampaignTitleCell = require('../components/AmsCampaignTitleCell.jsx');
const KdpTab = require('../components/KdpTab.jsx');
const tabber = require('../components/tabber.js');

const twoWeeks = 15 * constants.timespan.day;
const startTimestamp = Date.now() - twoWeeks;
const charts = [
    { column: 6, columnTitle: 'Impressions', label: "Impressions / day", metric: [constants.metric.impressions] },
    { column: 7, columnTitle: 'Clicks', label: "Clicks / day", metric: [constants.metric.clicks] },
    { column: 8, columnTitle: 'CPC', label: "Avg CPC", metric: [constants.metric.avgCpc] },
    { column: 9, columnTitle: 'Spend', label: "Spend / day", metric: [constants.metric.spend] },
    { column: 10, columnTitle: 'Sales', label: "Sales ($) / day", metric: [constants.metric.salesValue, constants.metric.knpeValue, constants.metric.knpeTotalValue] },
    { column: 11, columnTitle: 'ACoS', label: "ACOS", metric: [constants.metric.acos, constants.metric.knpeAcos] },
];

spdata.startSession();
spdata.amsPageInit();

window.setInterval(ga.mcatch(() => {
    let wrapper = $('#campaignTable_wrapper');
    if (!wrapper.length) {
        wrapper = $('.page-container div').first().children().last();
    }

    addTabs(wrapper);
    addTotalsRow(wrapper);
    addChartButtons(wrapper);
}), 100);

function addTabs(wrapper) {
    if (wrapper.hasClass('a-tab-container'))
        return;
    tabber(wrapper, { label: 'Dashboard', active: true });

    tabber(wrapper, {
        label: 'Aggregate History',
        activate: activateAggregateHistoryTab,
    });

    tabber(wrapper, {
        label: 'Aggregate Keywords',
        activate: activateAggregateKeywordTab,
    });

    tabber(wrapper, {
        label: "KDP Integration",
        activate: activateKdpTab,
    });
}

function addTotalsRow(wrapper) {
    if (!wrapper.length || wrapper.find('#machete-totals').length)
        return;

    const head = wrapper.find('#campaignTable thead');
    if (head.length) { // original UI
        const body = $('

');
        head.after(body);

        const totalRow = React.createElement(AmsCampaignRow, {
            label: "Yesterday's Totals",
            lastDay: {},
            syncPromise: spdata.startSession(),
        });
        ReactDOM.render(totalRow, body[0]);

        spdata.getCampaignSummaries().then(summaries => {
            const activeCampaigns = summaries.filter(x => spdata.isRunning(x));
            const lastDay = common.sumCampaignSnapshots(activeCampaigns.map(x => x.latestData));
            lastDay.budget = activeCampaigns.reduce((sum, x) => sum + x.budget, 0);

            const totalRow = React.createElement(AmsCampaignRow, {
                label: "Yesterday's Totals",
                lastDay,
                syncPromise: spdata.startSession(),
            });
            ReactDOM.render(totalRow, body[0]);
        });
    }

    else {
        const topRows = $('[role=rowgroup]').first();
        const totalCell = topRows.children().last();
        totalCell.attr('id', 'machete-totals');

        const ourCell = React.createElement(AmsCampaignTitleCell, {
            title: '',
            syncPromise: spdata.startSession(),
        });
        ReactDOM.unmountComponentAtNode(totalCell[0]);
        ReactDOM.render(ourCell, totalCell[0]);
    }
}

function campaignSelectOptions(campaigns) {
    let options = [
        { value: campaigns, label: 'All Campaigns' },
        { value: campaigns.filter(c => spdata.isRunning(c)), label: 'All Active Campaigns' }
    ].concat(...campaigns.filter(c => c.name).map(c => ({ value: [c], label: 'Campaign: ' + c.name })));

    for (const asin of _.uniq(campaigns.map(c => c.asin).filter(a => a && a != 'null'))) {
        options.push({ value: campaigns.filter(c => c.asin == asin), label: 'Campaigns for ASIN: ' + asin });
    }
    return options;
}

function activateAggregateHistoryTab(container) {
    let aggContent = React.createElement(AggregateHistory, {
        campaignPromise: ga.mpromise(async function() {
            const allowed = await spdata.getAllowedCampaignSummaries();
            return campaignSelectOptions(allowed);
        }),
        loadDataPromise: ga.mcatch(summaries => {
            const campaignIds = _.uniq(summaries.map(x => x.campaignId));
            return spdata.getAggregateCampaignHistory(spdata.getEntityId(), campaignIds);
        }),
    });
    ReactDOM.render(aggContent, container[0]);
}

function activateAggregateKeywordTab(container) {
    let aggContent = React.createElement(AggregateKeywords, {
        campaignPromise: ga.mpromise(async function() {
            const allowed = await spdata.getAllowedCampaignSummaries();
            return campaignSelectOptions(allowed);
        }),
        loadDataPromise: summaries => ga.mpromise(async function() {
            const adGroupIds = _.uniq(summaries.map(x => x.adGroupId).filter(x => x && x != 'null'));
            const kwData = await spdata.getAggregateKeywordData(spdata.getEntityId(), adGroupIds);
            const aggKws = common.aggregateKeywords(kwData);
            return aggKws;
        }),
        updateStatus: ga.mcatch((ids, enabled, callback) => {
            const idList = _.uniq(ids.reduce((array, item) => array.concat(...item), []));
            spdata.updateKeywordStatus(idList, enabled).then(callback);
        }),
        updateBid: ga.mcatch((ids, bid, callback) => {
            const idList = _.uniq(ids.reduce((array, item) => array.concat(...item), []));
            spdata.updateKeywordBid(idList, bid).then(callback);
        }),
    });
    ReactDOM.render(aggContent, container[0]);
}

function activateKdpTab(container) {
    let kdpContent = React.createElement(KdpTab, {});
    ReactDOM.render(kdpContent, container[0]);
}

function addChartButtons(wrapper) {
    for (let { row, campaignCell } of findCampaignRows(wrapper)) {
        if ($(row).find(`.${DashboardHistoryButton.chartClass}`).length)
            continue;

        let link = $(campaignCell).find('a')[0];
        if (!link)
            continue;

        let href = link.href;
        let campaignId = spdata.getCampaignId(href);

        const renderButtons = ga.mcatch((allowed, anonymous, summary) => {
            for (let chart of charts) {
                const target = findTargetInRow(row, chart);
                if (target)
                    addChartButtonToCell({ summary, allowed, anonymous, target, chart });
            }
        });
        renderButtons(false, true, {});

        ga.mpromise(Promise.all([spdata.getCampaignAllowed(spdata.getEntityId(), campaignId), common.getUser(), spdata.getCampaignSummaries()]))
        .then(results => {
            const [allowed, user, summaries] = results;
            const summary = summaries.find(x => x.campaignId == campaignId) || {};
            renderButtons(allowed, user.isAnon, summary);
        });
    }
}

let columns = null;
function findCampaignRows(wrapper) {
    let tableRows = $('#campaignTable tbody tr');
    if (tableRows.length)
        return Array.from(tableRows).map(x => ({ row: x, campaignCell: $(x).find('td')[1] }));

    const rowGroups = wrapper.find('[role=rowgroup]');
    columns = Array.from($(rowGroups[1]).find('span')).filter(x => x.innerText);
    const cells = $(rowGroups[3]).children('div').children('div');
    const campaignCells = $(rowGroups[2]).children('div');

    const rows = Array.from(common.pageArray(cells, columns.length));
    return rows.map((x, index) => ({ row: x, campaignCell: campaignCells[(index * 3) + 2] }));
}

function findTargetInRow(row, chart) {
    if (columns && columns.length) {
        const columnTitles = columns.map(x => x.innerText);
        const cell = row[columnTitles.indexOf(chart.columnTitle)];
        return $(cell).children()[0];
    }
    return $(row).children()[chart.column];
}

function addChartButtonToCell({ summary, allowed, anonymous, target, chart }) {
    const dataPromiseFactory = () => ga.mpromise(async function() {
        const data = summary.campaignId ? await spdata.getCampaignHistory(spdata.getEntityId(), summary.campaignId) : [];
        const deltas = common.chunkSeries(data, 'day').filter(x => x.timestamp > startTimestamp);

        const knpe = spdata.calculateKnpIncome(deltas, summary.kdp);
        const campaignData = common.parallelizeSeries(knpe);
        return chart.metric.map(metric => common.formatParallelData(campaignData, metric));
    });

    let container = $(target).find('.machete-dash-container');
    if (!container.length) {
        container = $('');
        $(target).append(container);
    }

    let btn = React.createElement(DashboardHistoryButton, {
        allowed,
        anonymous,
        metric: chart.metric[0],
        title: chart.label,
        dataPromiseFactory,
        latestData: summary.latestData,
    });
    ReactDOM.render(btn, container[0]);
}
<commit_msg>at least pass the campaignId in face summaries<commit_after>const $ = require('jquery');
const React = require('react');
const ReactDOM = require('react-dom');
const _ = require('lodash');

const common = require('../common/common.js');
const spdata = require('../common/sp-data.js');
const constants = require('../common/constants.js');
const ga = require('../common/ga.js');
const DashboardHistoryButton = require('../components/DashboardHistoryButton.jsx');
const AggregateHistory = require('../components/AggregateHistory.jsx');
const AggregateKeywords = require('../components/AggregateKeywords.jsx');
const AmsCampaignRow = require('../components/AmsCampaignRow.jsx');
const AmsCampaignTitleCell = require('../components/AmsCampaignTitleCell.jsx');
const KdpTab = require('../components/KdpTab.jsx');
const tabber = require('../components/tabber.js');

const twoWeeks = 15 * constants.timespan.day;
const startTimestamp = Date.now() - twoWeeks;
const charts = [
    { column: 6, columnTitle: 'Impressions', label: "Impressions / day", metric: [constants.metric.impressions] },
    { column: 7, columnTitle: 'Clicks', label: "Clicks / day", metric: [constants.metric.clicks] },
    { column: 8, columnTitle: 'CPC', label: "Avg CPC", metric: [constants.metric.avgCpc] },
    { column: 9, columnTitle: 'Spend', label: "Spend / day", metric: [constants.metric.spend] },
    { column: 10, columnTitle: 'Sales', label: "Sales ($) / day", metric: [constants.metric.salesValue, constants.metric.knpeValue, constants.metric.knpeTotalValue] },
    { column: 11, columnTitle: 'ACoS', label: "ACOS", metric: [constants.metric.acos, constants.metric.knpeAcos] },
];

spdata.startSession();
spdata.amsPageInit();

window.setInterval(ga.mcatch(() => {
    let wrapper = $('#campaignTable_wrapper');
    if (!wrapper.length) {
        wrapper = $('.page-container div').first().children().last();
    }

    addTabs(wrapper);
    addTotalsRow(wrapper);
    addChartButtons(wrapper);
}), 100);

function addTabs(wrapper) {
    if (wrapper.hasClass('a-tab-container'))
        return;
    tabber(wrapper, { label: 'Dashboard', active: true });

    tabber(wrapper, {
        label: 'Aggregate History',
        activate: activateAggregateHistoryTab,
    });

    tabber(wrapper, {
        label: 'Aggregate Keywords',
        activate: activateAggregateKeywordTab,
    });

    tabber(wrapper, {
        label: "KDP Integration",
        activate: activateKdpTab,
    });
}

function addTotalsRow(wrapper) {
    if (!wrapper.length || wrapper.find('#machete-totals').length)
        return;

    const head = wrapper.find('#campaignTable thead');
    if (head.length) { // original UI
        const body = $('

');
        head.after(body);

        const totalRow = React.createElement(AmsCampaignRow, {
            label: "Yesterday's Totals",
            lastDay: {},
            syncPromise: spdata.startSession(),
        });
        ReactDOM.render(totalRow, body[0]);

        spdata.getCampaignSummaries().then(summaries => {
            const activeCampaigns = summaries.filter(x => spdata.isRunning(x));
            const lastDay = common.sumCampaignSnapshots(activeCampaigns.map(x => x.latestData));
            lastDay.budget = activeCampaigns.reduce((sum, x) => sum + x.budget, 0);

            const totalRow = React.createElement(AmsCampaignRow, {
                label: "Yesterday's Totals",
                lastDay,
                syncPromise: spdata.startSession(),
            });
            ReactDOM.render(totalRow, body[0]);
        });
    }

    else {
        const topRows = $('[role=rowgroup]').first();
        const totalCell = topRows.children().last();
        totalCell.attr('id', 'machete-totals');

        const ourCell = React.createElement(AmsCampaignTitleCell, {
            title: '',
            syncPromise: spdata.startSession(),
        });
        ReactDOM.unmountComponentAtNode(totalCell[0]);
        ReactDOM.render(ourCell, totalCell[0]);
    }
}

function campaignSelectOptions(campaigns) {
    let options = [
        { value: campaigns, label: 'All Campaigns' },
        { value: campaigns.filter(c => spdata.isRunning(c)), label: 'All Active Campaigns' }
    ].concat(...campaigns.filter(c => c.name).map(c => ({ value: [c], label: 'Campaign: ' + c.name })));

    for (const asin of _.uniq(campaigns.map(c => c.asin).filter(a => a && a != 'null'))) {
        options.push({ value: campaigns.filter(c => c.asin == asin), label: 'Campaigns for ASIN: ' + asin });
    }
    return options;
}

function activateAggregateHistoryTab(container) {
    let aggContent = React.createElement(AggregateHistory, {
        campaignPromise: ga.mpromise(async function() {
            const allowed = await spdata.getAllowedCampaignSummaries();
            return campaignSelectOptions(allowed);
        }),
        loadDataPromise: ga.mcatch(summaries => {
            const campaignIds = _.uniq(summaries.map(x => x.campaignId));
            return spdata.getAggregateCampaignHistory(spdata.getEntityId(), campaignIds);
        }),
    });
    ReactDOM.render(aggContent, container[0]);
}

function activateAggregateKeywordTab(container) {
    let aggContent = React.createElement(AggregateKeywords, {
        campaignPromise: ga.mpromise(async function() {
            const allowed = await spdata.getAllowedCampaignSummaries();
            return campaignSelectOptions(allowed);
        }),
        loadDataPromise: summaries => ga.mpromise(async function() {
            const adGroupIds = _.uniq(summaries.map(x => x.adGroupId).filter(x => x && x != 'null'));
            const kwData = await spdata.getAggregateKeywordData(spdata.getEntityId(), adGroupIds);
            const aggKws = common.aggregateKeywords(kwData);
            return aggKws;
        }),
        updateStatus: ga.mcatch((ids, enabled, callback) => {
            const idList = _.uniq(ids.reduce((array, item) => array.concat(...item), []));
            spdata.updateKeywordStatus(idList, enabled).then(callback);
        }),
        updateBid: ga.mcatch((ids, bid, callback) => {
            const idList = _.uniq(ids.reduce((array, item) => array.concat(...item), []));
            spdata.updateKeywordBid(idList, bid).then(callback);
        }),
    });
    ReactDOM.render(aggContent, container[0]);
}

function activateKdpTab(container) {
    let kdpContent = React.createElement(KdpTab, {});
    ReactDOM.render(kdpContent, container[0]);
}

function addChartButtons(wrapper) {
    for (let { row, campaignCell } of findCampaignRows(wrapper)) {
        if ($(row).find(`.${DashboardHistoryButton.chartClass}`).length)
            continue;

        let link = $(campaignCell).find('a')[0];
        if (!link)
            continue;

        let href = link.href;
        let campaignId = spdata.getCampaignId(href);

        const renderButtons = ga.mcatch((allowed, anonymous, summary) => {
            for (let chart of charts) {
                const target = findTargetInRow(row, chart);
                if (target)
                    addChartButtonToCell({ summary, allowed, anonymous, target, chart });
            }
        });
        renderButtons(false, true, { campaignId });

        ga.mpromise(Promise.all([spdata.getCampaignAllowed(spdata.getEntityId(), campaignId), common.getUser(), spdata.getCampaignSummaries()]))
        .then(results => {
            const [allowed, user, summaries] = results;
            const summary = summaries.find(x => x.campaignId == campaignId) || { campaignId };
            renderButtons(allowed, user.isAnon, summary);
        });
    }
}

let columns = null;
function findCampaignRows(wrapper) {
    let tableRows = $('#campaignTable tbody tr');
    if (tableRows.length)
        return Array.from(tableRows).map(x => ({ row: x, campaignCell: $(x).find('td')[1] }));

    const rowGroups = wrapper.find('[role=rowgroup]');
    columns = Array.from($(rowGroups[1]).find('span')).filter(x => x.innerText);
    const cells = $(rowGroups[3]).children('div').children('div');
    const campaignCells = $(rowGroups[2]).children('div');

    const rows = Array.from(common.pageArray(cells, columns.length));
    return rows.map((x, index) => ({ row: x, campaignCell: campaignCells[(index * 3) + 2] }));
}

function findTargetInRow(row, chart) {
    if (columns && columns.length) {
        const columnTitles = columns.map(x => x.innerText);
        const cell = row[columnTitles.indexOf(chart.columnTitle)];
        return $(cell).children()[0];
    }
    return $(row).children()[chart.column];
}

function addChartButtonToCell({ summary, allowed, anonymous, target, chart }) {
    const dataPromiseFactory = () => ga.mpromise(async function() {
        const data = summary.campaignId ? await spdata.getCampaignHistory(spdata.getEntityId(), summary.campaignId) : [];
        const deltas = common.chunkSeries(data, 'day').filter(x => x.timestamp > startTimestamp);

        const knpe = spdata.calculateKnpIncome(deltas, summary.kdp);
        const campaignData = common.parallelizeSeries(knpe);
        return chart.metric.map(metric => common.formatParallelData(campaignData, metric));
    });

    let container = $(target).find('.machete-dash-container');
    if (!container.length) {
        container = $('');
        $(target).append(container);
    }

    let btn = React.createElement(DashboardHistoryButton, {
        allowed,
        anonymous,
        metric: chart.metric[0],
        title: chart.label,
        dataPromiseFactory,
        latestData: summary.latestData,
    });
    ReactDOM.render(btn, container[0]);
}
<|endoftext|>


<commit_before>tw.data.referenceWaters = {
	"Gemminger Mineralquelle": {
		"Natrium": 40.6,
		"Kalium": 5.4,
		"Calcium": 426,
		"Magnesium": 70.6,
		"Chlorid": 10.9,
		"Nitrat": 0.05,
		"Sulfat": 1065,
		"sources": ["http://www.wueteria.de/unser_wasser/index.php"]
	},
	"Teusser Naturell (Löwenstein)": {
		"Natrium": 53,
		"Kalium": 8,
		"Calcium": 62,
		"Magnesium": 565,
		"Chlorid": 27,
		"Nitrat": 0.5,
		"Sulfat": 1450,
		"sources": ["http://www.teusser.de/index.php?id=225"]
	},
	"Volvic": {
		"Natrium": 11.6,
		"Kalium": 6.2,
		"Calcium": 11.5,
		"Magnesium": 8,
		"Chlorid": 13.5,
		"Nitrat": 6.9,
		"Sulfat": 8.1,
		"sources": ["http://books.google.de/books?id=lzEoGWyqMBwC&pg=PA198&lpg=PA198&dq=volvic+nitratgehalt&source=bl&ots=pJEE0i9HwK&sig=OI_PeSr_QGBCfpeVCu70N4ohy8g&hl=de&ei=4-yvSuHrJ8jK_gbV0p3ZDA&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q&f=false"]
	}
};<commit_msg>added Biberacher sanft values<commit_after>tw.data.referenceWaters = {
	"Gemminger Mineralquelle": {
		"Natrium": 40.6,
		"Kalium": 5.4,
		"Calcium": 426,
		"Magnesium": 70.6,
		"Chlorid": 10.9,
		"Nitrat": 0.05,
		"Sulfat": 1065,
		"sources": ["http://www.wueteria.de/unser_wasser/index.php"]
	},
	"Teusser Naturell (Löwenstein)": {
		"Natrium": 53,
		"Kalium": 8,
		"Calcium": 62,
		"Magnesium": 565,
		"Chlorid": 27,
		"Nitrat": 0.5,
		"Sulfat": 1450,
		"sources": ["http://www.teusser.de/index.php?id=225"]
	},
	"Biberacher sanft": {
		"Natrium": 17.1,
		"Kalium": 8.65,
		"Calcium": 585,
		"Magnesium": 51.1,
		"Chlorid": 32.3,
		"Nitrat": 0.2,
		"Sulfat": 1359,
		"sources": []
	},
	"Volvic": {
		"Natrium": 11.6,
		"Kalium": 6.2,
		"Calcium": 11.5,
		"Magnesium": 8,
		"Chlorid": 13.5,
		"Nitrat": 6.9,
		"Sulfat": 8.1,
		"sources": ["http://books.google.de/books?id=lzEoGWyqMBwC&pg=PA198&lpg=PA198&dq=volvic+nitratgehalt&source=bl&ots=pJEE0i9HwK&sig=OI_PeSr_QGBCfpeVCu70N4ohy8g&hl=de&ei=4-yvSuHrJ8jK_gbV0p3ZDA&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q&f=false"]
	}
};<|endoftext|>


<commit_before>/* eslint-disable import/no-mutable-exports */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import RNFS from 'react-native-fs';

import { SETTINGS_KEYS } from '../settings';
import { formatDate, requestPermission, backupValidation } from '../utilities';

const { THIS_STORE_NAME_ID } = SETTINGS_KEYS;

const translateToCoreDatabaseType = type => {
  switch (type) {
    case 'CustomerInvoice':
    case 'Prescription':
    case 'SupplierInvoice':
    case 'Receipt':
    case 'CustomerCredit':
    case 'Payment':
    case 'CashTransaction':
      return 'Transaction';
    case 'CashTransactionName':
    case 'Customer':
    case 'Supplier':
    case 'InternalSupplier':
    case 'ExternalSupplier':
    case 'Patient':
      return 'Name';
    case 'CashTransactionReason':
      return 'Options';
    case 'RequestRequisition':
    case 'ResponseRequisition':
      return 'Requisition';
    case 'RequisitionReason':
    case 'NegativeAdjustmentReason':
    case 'PositiveAdjustmentReason':
      return 'Options';
    case 'Policy':
      return 'InsurancePolicy';
    case 'Provider':
      return 'InsuranceProvider';
    case 'PrescriptionCategory':
    case 'SupplierCreditCategory':
      return 'TransactionCategory';
    default:
      return type;
  }
};

class UIDatabase {
  constructor(database) {
    this.database = database;
    this.EXPORT_DIRECTORY = '/Download/mSupplyMobile_data';
    this.DEFAULT_EXPORT_FILE = 'msupply-mobile-data';
  }

  ERRORS = {
    ERROR_IN_TRANSACTION: { code: 'ERROR_IN_TRANSACTION', message: 'Database is in a transaction' },
    ERROR_NO_PERMISSION: { code: 'ERROR_NO_PERMISSION', message: 'Storage permission not granted' },
    ERROR_UNKNOWN: { code: 'ERROR_UNKNOWN', message: 'Unkown error occurred' },
  };

  /**
   * Exports the realm file to '/Download/mSupplyMobile\ data' on device file system.
   * Ensures there is enough space, the realm exists and requests storage permission,
   * if required.
   */

  async exportData(filename = this.DEFAULT_EXPORT_FILE) {
    const { realm } = this.database;
    const { path: realmPath } = realm;
    const exportFolder = `${RNFS.ExternalStorageDirectoryPath}${this.EXPORT_DIRECTORY}`;
    // Replace all invalid characters in the android file system with an empty string.
    const copyFileName = `${filename}${formatDate(new Date(), 'dashes')}`.replace(
      /[~\\\\/|?*<:>"+]/g,
      ''
    );

    const permissionParameters = {
      permissionType: 'WRITE_EXTERNAL_STORAGE',
      message: 'Export database',
    };

    // Before requesting permissions, ensure there is enough space and the realm
    // file exists.
    const exportValidation = await backupValidation(realmPath);
    const { success } = exportValidation;
    if (!success) return exportValidation;
    // Request permissions for external storage before trying to backup the realm file.
    const { success: permissionSuccess } = await requestPermission(permissionParameters);
    // If permission was granted, ensure the realm is not in a transaction and backup
    // the realm file.
    if (!permissionSuccess) return { success: false, ...this.ERRORS.ERROR_NO_PERMISSION };
    if (realm.isInTransaction) return { success: false, ...this.ERRORS.ERROR_IN_TRANSACTION };

    // Finally try to create the backup/exported realm
    try {
      await RNFS.mkdir(exportFolder);
      await RNFS.copyFile(realmPath, `${exportFolder}/${copyFileName}.realm`);
    } catch (error) {
      return { success: false, ...this.ERRORS.ERROR_UNKNOWN, error };
    }

    return { success: true };
  }

  objects(type) {
    const results = this.database.objects(translateToCoreDatabaseType(type));
    const thisStoreNameIdSetting = this.database
      .objects('Setting')
      .filtered('key == $0', THIS_STORE_NAME_ID)[0];
    // |ownStoreIdSetting| will not exist if not initialised.
    const thisStoreNameId = thisStoreNameIdSetting && thisStoreNameIdSetting.value;

    switch (type) {
      case 'CustomerInvoice':
        // Only show invoices generated from requisitions once finalised.
        return results.filtered(
          'type == $0 AND (linkedRequisition == $1 OR status == $2)',
          'customer_invoice',
          null,
          'finalised'
        );
      case 'SupplierInvoice':
        return results.filtered(
          'type == $0 AND mode == $1 AND otherParty.type != $2',
          'supplier_invoice',
          'store',
          'inventory_adjustment'
        );
      case 'Receipt':
        return results.filtered('type == $0', 'receipt');
      case 'Payment':
        return results.filtered('type == $0', 'payment');
      case 'CashTransaction':
        return results.filtered('type == $0 OR type == $1', 'receipt', 'payment');
      case 'CashTransactionName':
        return results
          .filtered('isVisible == true && id != $0', thisStoreNameId)
          .filtered('isSupplier == true || isCustomer == true || isPatient == true');
      case 'CashTransactionReason':
        return results.filtered('type == $0', 'newCashOutTransaction');
      case 'CustomerCredit':
        return results.filtered('type == $0', 'customer_credit');
      case 'Policy':
        return results.filtered(
          'insuranceProvider.isActive == $0 && expiryDate > $1',
          true,
          new Date()
        );
      case 'Provider':
        return results.filtered('isActive == $0', true);
      case 'Customer':
        return results.filtered(
          'isVisible == true AND isCustomer == true AND id != $0 AND isPatient == false',
          thisStoreNameId
        );
      case 'Supplier':
        return results.filtered(
          'isVisible == true AND isSupplier == true AND id != $0',
          thisStoreNameId
        );
      case 'Patient':
        return results.filtered(
          'isVisible == true AND isPatient == true AND id != $0',
          thisStoreNameId
        );
      case 'InternalSupplier':
        return results.filtered(
          'isVisible == true AND isSupplier == true AND type == "store" AND id != $0',
          thisStoreNameId
        );
      case 'ExternalSupplier':
        return results.filtered('isVisible == true AND isSupplier == true AND type == "facility"');
      case 'Item':
        return results.filtered('isVisible == true');
      case 'RequestRequisition':
        return results.filtered('type == "request"');
      case 'ResponseRequisition':
        return results.filtered('serialNumber != "-1" AND type == "response"');
      case 'NegativeAdjustmentReason':
        return results.filtered('type == $0 && isActive == true', 'negativeInventoryAdjustment');
      case 'PositiveAdjustmentReason':
        return results.filtered('type == $0 && isActive == true', 'positiveInventoryAdjustment');
      case 'Prescription':
        return results.filtered(
          'type == $0 AND otherParty.type == $1 AND (linkedRequisition == $2 OR status == $3)',
          'customer_invoice',
          'patient',
          null,
          'finalised'
        );
      case 'PrescriptionCategory':
        return results.filtered('type == $0', 'prescription');
      case 'SupplierCreditCategory':
        return results.filtered('type == $0', 'supplier_credit');
      case 'RequisitionReason':
        return results.filtered('type == $0 && isActive == true', 'requisitionLineVariance');
      default:
        return results;
    }
  }

  get(...args) {
    return this.database.get(...args);
  }

  addListener(...args) {
    return this.database.addListener(...args);
  }

  removeListener(...args) {
    return this.database.removeListener(...args);
  }

  alertListeners(...args) {
    return this.database.alertListeners(...args);
  }

  create(...args) {
    return this.database.create(...args);
  }

  getOrCreate(...args) {
    return this.database.getOrCreate(...args);
  }

  delete(...args) {
    return this.database.delete(...args);
  }

  deleteAll(...args) {
    return this.database.deleteAll(...args);
  }

  save(...args) {
    return this.database.save(...args);
  }

  update(...args) {
    return this.database.update(...args);
  }

  write(...args) {
    return this.database.write(...args);
  }

  getSetting(key) {
    const setting = this.database.get('Setting', key, 'key');
    return (setting && setting.value) || '';
  }
}

let UIDatabaseInstance;

export const getUIDatabaseInstance = database => {
  if (!UIDatabaseInstance) {
    UIDatabaseInstance = new UIDatabase(database);
  }
  return UIDatabaseInstance;
};

// Factory function for custom UIDatabase PropTypes.
const createUIDatabasePropType = isRequired => (props, propName, componentName) => {
  const { [propName]: prop } = props;

  if (prop == null) {
    if (isRequired) {
      return new TypeError(`Missing database prop in ${componentName}`);
    }
    return null;
  }

  if (prop instanceof UIDatabase) return null;
  return new TypeError(`Invalid database prop in ${componentName}`);
};

export const UIDatabaseType = createUIDatabasePropType(false);
UIDatabaseType.isRequired = createUIDatabasePropType(true);

export default getUIDatabaseInstance;
<commit_msg>Add supplierTransaction query<commit_after>/* eslint-disable import/no-mutable-exports */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import RNFS from 'react-native-fs';

import { SETTINGS_KEYS } from '../settings';
import { formatDate, requestPermission, backupValidation } from '../utilities';

const { THIS_STORE_NAME_ID } = SETTINGS_KEYS;

const translateToCoreDatabaseType = type => {
  switch (type) {
    case 'CustomerInvoice':
    case 'Prescription':
    case 'SupplierInvoice':
    case 'Receipt':
    case 'CustomerCredit':
    case 'Payment':
    case 'CashTransaction':
    case 'SupplierTransaction':
      return 'Transaction';
    case 'CashTransactionName':
    case 'Customer':
    case 'Supplier':
    case 'InternalSupplier':
    case 'ExternalSupplier':
    case 'Patient':
      return 'Name';
    case 'CashTransactionReason':
      return 'Options';
    case 'RequestRequisition':
    case 'ResponseRequisition':
      return 'Requisition';
    case 'RequisitionReason':
    case 'NegativeAdjustmentReason':
    case 'PositiveAdjustmentReason':
      return 'Options';
    case 'Policy':
      return 'InsurancePolicy';
    case 'Provider':
      return 'InsuranceProvider';
    case 'PrescriptionCategory':
    case 'SupplierCreditCategory':
      return 'TransactionCategory';
    default:
      return type;
  }
};

class UIDatabase {
  constructor(database) {
    this.database = database;
    this.EXPORT_DIRECTORY = '/Download/mSupplyMobile_data';
    this.DEFAULT_EXPORT_FILE = 'msupply-mobile-data';
  }

  ERRORS = {
    ERROR_IN_TRANSACTION: { code: 'ERROR_IN_TRANSACTION', message: 'Database is in a transaction' },
    ERROR_NO_PERMISSION: { code: 'ERROR_NO_PERMISSION', message: 'Storage permission not granted' },
    ERROR_UNKNOWN: { code: 'ERROR_UNKNOWN', message: 'Unkown error occurred' },
  };

  /**
   * Exports the realm file to '/Download/mSupplyMobile\ data' on device file system.
   * Ensures there is enough space, the realm exists and requests storage permission,
   * if required.
   */

  async exportData(filename = this.DEFAULT_EXPORT_FILE) {
    const { realm } = this.database;
    const { path: realmPath } = realm;
    const exportFolder = `${RNFS.ExternalStorageDirectoryPath}${this.EXPORT_DIRECTORY}`;
    // Replace all invalid characters in the android file system with an empty string.
    const copyFileName = `${filename}${formatDate(new Date(), 'dashes')}`.replace(
      /[~\\\\/|?*<:>"+]/g,
      ''
    );

    const permissionParameters = {
      permissionType: 'WRITE_EXTERNAL_STORAGE',
      message: 'Export database',
    };

    // Before requesting permissions, ensure there is enough space and the realm
    // file exists.
    const exportValidation = await backupValidation(realmPath);
    const { success } = exportValidation;
    if (!success) return exportValidation;
    // Request permissions for external storage before trying to backup the realm file.
    const { success: permissionSuccess } = await requestPermission(permissionParameters);
    // If permission was granted, ensure the realm is not in a transaction and backup
    // the realm file.
    if (!permissionSuccess) return { success: false, ...this.ERRORS.ERROR_NO_PERMISSION };
    if (realm.isInTransaction) return { success: false, ...this.ERRORS.ERROR_IN_TRANSACTION };

    // Finally try to create the backup/exported realm
    try {
      await RNFS.mkdir(exportFolder);
      await RNFS.copyFile(realmPath, `${exportFolder}/${copyFileName}.realm`);
    } catch (error) {
      return { success: false, ...this.ERRORS.ERROR_UNKNOWN, error };
    }

    return { success: true };
  }

  objects(type) {
    const results = this.database.objects(translateToCoreDatabaseType(type));
    const thisStoreNameIdSetting = this.database
      .objects('Setting')
      .filtered('key == $0', THIS_STORE_NAME_ID)[0];
    // |ownStoreIdSetting| will not exist if not initialised.
    const thisStoreNameId = thisStoreNameIdSetting && thisStoreNameIdSetting.value;

    switch (type) {
      case 'CustomerInvoice':
        // Only show invoices generated from requisitions once finalised.
        return results.filtered(
          'type == $0 AND (linkedRequisition == $1 OR status == $2)',
          'customer_invoice',
          null,
          'finalised'
        );
      case 'SupplierTransaction': {
        const queryString =
          // eslint-disable-next-line no-multi-str
          '((type == $0 AND mode == $2) OR (type == $1 AND status == $3))\
           AND otherParty.type != $4';
        return results.filtered(
          queryString,
          'supplier_invoice',
          'supplier_credit',
          'store',
          'finalised',
          'inventory_adjustment'
        );
      }
      case 'SupplierInvoice':
        return results.filtered(
          'type == $0 AND mode == $1 AND otherParty.type != $2',
          'supplier_invoice',
          'store',
          'inventory_adjustment'
        );
      case 'Receipt':
        return results.filtered('type == $0', 'receipt');
      case 'Payment':
        return results.filtered('type == $0', 'payment');
      case 'CashTransaction':
        return results.filtered('type == $0 OR type == $1', 'receipt', 'payment');
      case 'CashTransactionName':
        return results
          .filtered('isVisible == true && id != $0', thisStoreNameId)
          .filtered('isSupplier == true || isCustomer == true || isPatient == true');
      case 'CashTransactionReason':
        return results.filtered('type == $0', 'newCashOutTransaction');
      case 'CustomerCredit':
        return results.filtered('type == $0', 'customer_credit');
      case 'Policy':
        return results.filtered(
          'insuranceProvider.isActive == $0 && expiryDate > $1',
          true,
          new Date()
        );
      case 'Provider':
        return results.filtered('isActive == $0', true);
      case 'Customer':
        return results.filtered(
          'isVisible == true AND isCustomer == true AND id != $0 AND isPatient == false',
          thisStoreNameId
        );
      case 'Supplier':
        return results.filtered(
          'isVisible == true AND isSupplier == true AND id != $0',
          thisStoreNameId
        );
      case 'Patient':
        return results.filtered(
          'isVisible == true AND isPatient == true AND id != $0',
          thisStoreNameId
        );
      case 'InternalSupplier':
        return results.filtered(
          'isVisible == true AND isSupplier == true AND type == "store" AND id != $0',
          thisStoreNameId
        );
      case 'ExternalSupplier':
        return results.filtered('isVisible == true AND isSupplier == true AND type == "facility"');
      case 'Item':
        return results.filtered('isVisible == true');
      case 'RequestRequisition':
        return results.filtered('type == "request"');
      case 'ResponseRequisition':
        return results.filtered('serialNumber != "-1" AND type == "response"');
      case 'NegativeAdjustmentReason':
        return results.filtered('type == $0 && isActive == true', 'negativeInventoryAdjustment');
      case 'PositiveAdjustmentReason':
        return results.filtered('type == $0 && isActive == true', 'positiveInventoryAdjustment');
      case 'Prescription':
        return results.filtered(
          'type == $0 AND otherParty.type == $1 AND (linkedRequisition == $2 OR status == $3)',
          'customer_invoice',
          'patient',
          null,
          'finalised'
        );
      case 'PrescriptionCategory':
        return results.filtered('type == $0', 'prescription');
      case 'SupplierCreditCategory':
        return results.filtered('type == $0', 'supplier_credit');
      case 'RequisitionReason':
        return results.filtered('type == $0 && isActive == true', 'requisitionLineVariance');
      default:
        return results;
    }
  }

  get(...args) {
    return this.database.get(...args);
  }

  addListener(...args) {
    return this.database.addListener(...args);
  }

  removeListener(...args) {
    return this.database.removeListener(...args);
  }

  alertListeners(...args) {
    return this.database.alertListeners(...args);
  }

  create(...args) {
    return this.database.create(...args);
  }

  getOrCreate(...args) {
    return this.database.getOrCreate(...args);
  }

  delete(...args) {
    return this.database.delete(...args);
  }

  deleteAll(...args) {
    return this.database.deleteAll(...args);
  }

  save(...args) {
    return this.database.save(...args);
  }

  update(...args) {
    return this.database.update(...args);
  }

  write(...args) {
    return this.database.write(...args);
  }

  getSetting(key) {
    const setting = this.database.get('Setting', key, 'key');
    return (setting && setting.value) || '';
  }
}

let UIDatabaseInstance;

export const getUIDatabaseInstance = database => {
  if (!UIDatabaseInstance) {
    UIDatabaseInstance = new UIDatabase(database);
  }
  return UIDatabaseInstance;
};

// Factory function for custom UIDatabase PropTypes.
const createUIDatabasePropType = isRequired => (props, propName, componentName) => {
  const { [propName]: prop } = props;

  if (prop == null) {
    if (isRequired) {
      return new TypeError(`Missing database prop in ${componentName}`);
    }
    return null;
  }

  if (prop instanceof UIDatabase) return null;
  return new TypeError(`Invalid database prop in ${componentName}`);
};

export const UIDatabaseType = createUIDatabasePropType(false);
UIDatabaseType.isRequired = createUIDatabasePropType(true);

export default getUIDatabaseInstance;
<|endoftext|>


<commit_before>var net = require('net');

var shortid = require('shortid');
var Discord = require('discord.io');

class Bot {
	constructor(key, disnode) {
		this.key = key;
		this.client = {};
		this.disnode = disnode;
		this.bind_onMessage = null;
		this.isRemote = false;
		this.remoteID = "";
	}

	Connect() {
		var self = this;
		return new Promise(function (resolve, reject) {

			if (self.disnode.botConfig.balancerEnabled == true) {
				if (!self.disnode.botConfig.balancerIP) {
					reject("No Load Balancer IP!");
				}
				if (!self.disnode.botConfig.balancerPORT) {
					reject("No Load Balancer Port!");
				}

				self.client.type == "REMOTE";
				self.client = new net.Socket();
				self.client.connect(self.disnode.botConfig.balancerPORT, self.disnode.botConfig.balancerIP, function () {
					self.remoteID = shortid.generate();
					self.client.write(JSON.stringify({
						type: "REGISTER",
						id: self.remoteID
					}))
					self.client.on('data', (data) => self.ParseRemoteCommand(data));
					self.isRemote = true;
					resolve("Connected to remote Load Balancer!");
					return;
				});
			} else {
				self.client = new Discord.Client({
					autorun: true,
					token: self.key
				});

				self.client.on('ready', function (event) {
					self.SetUpLocalBinds();
					resolve();
				});

			}

		});
	}

	Disconnect() {
		var self = this;
		return new Promise(function (resolve, reject) {
			self.client.disconnect();
			resolve();
		});
	}

	Restart() {
		var self = this;
		self.Disconnect().then(function (){
			self.client.connect()
		});
	}

	ParseRemoteCommand(command) {
		var self = this;
		var obj = JSON.parse(command);

		switch (obj.type) {
		case "RECV_MESSAGE":

			if (self.bind_onMessage) {
				self.bind_onMessage(obj.data);
			} else {

			}
		}
	}

	SetUpLocalBinds() {
		var self = this;
		self.client.on('message', function (user, userID, channelID, message, event) {
			if (self.bind_onMessage) {
				var _server = "DM";
				if(self.client.channels[channelID]){
						_server = self.client.channels[channelID].guild_id;
				}
				var msgObject = {
					user: user,
					userID: userID,
					channel: channelID,
					message: message,
					server: _server
				}
				self.bind_onMessage(msgObject);
			}
		});
	}

	bindOnMessage(msgFunction) {
		this.bind_onMessage = msgFunction;
	}

	SendMessage(channel, msg, typing=false, tts=false) {
		var self = this;
		if (self.isRemote) {
			var msgOBJ = {
				channel: channel,
				msg: msg,
				typing: typing,
      	tts: tts
			};
			var commandObj = {
				type: "SEND_MESSAGE",
				id: self.remoteID,
				data: msgOBJ
			};

			self.client.write(JSON.stringify(commandObj));
		}else{
			return new Promise(function(resolve, reject) {
				self.client.sendMessage({
					to: channel,
					message: msg,
		 			typing: typing,
		      tts: tts
				}, function(err, resp) {
					if(err){
						reject(err);
					}else {
						resolve(resp);
					}
				});
			});
		}
	}
	SendEmbed(channel, embed){
		var self = this;
		self.client.sendMessage({
			to: channel,
			embed: embed
		});
	}
	SendCompactEmbed(channel, title, body) {
		var self = this;
		self.client.sendMessage({
			to: channel,
			embed: {
				color: 3447003,
				author: {},
				fields: [{
					name: title,
					inline: false,
					value: body,
				}],
				footer: {}
			}
		});
	}
	SetStatus(status){
		var self = this;
		self.client.setPresence({game: {name: status}});
	}

	SetUsername(name){
		var self = this;
		self.client.editUserInfo({username: name});
	}

	JoinVoiceChannel(voiceID){
		var self = this;
		this.client.joinVoiceChannel(voiceID,function(err){
			if(err){
				console.log(err);
			}else{
			}
		})
	}

  LeaveVoiceChannel(voiceID){
		var self = this;
		this.client.leaveVoiceChannel(voiceID,function(err){
			if(err){
				console.log(err);
			}else{
			}
		})
	}
		JoinUsersVoiceChannel(serverID, userID){
		var user = this.GetUserByID(serverID, userID);
		if(!user){
			return;
		}
		this.JoinVoiceChannel(user.voice_channel_id);
	}
    LeaveUsersVoiceChannel(serverID, userID) {
    var user = this.GetUserByID(serverID, userID);
		if(!user){
			return;
		}
			this.LeaveVoiceChannel(user.voice_channel_id);
  }
		GetServerByID(id){
		var servers = this.client.servers;
		return servers[id];
	}
		GetUserByID(serverId, userId){
		var server = this.GetServerByID(serverId);
		if(!server){
			return;
		}
		return server.members[userId];
	}
		GetUserRoles(serverId, userId){
		var user = this.GetUserByID(serverId, userId);
		if(!user){
			return;
		}
		return user.roles;
	}

	GetRoleById(serverId, roleId){
		var server = this.GetServerByID(serverId);
		if(!server){
			return;
		}
		return server.roles[roleId];
	}
	GetBotInfo(){
		var self = this;
		return {
			username: self.client.username,
			id: self.client.id,
			avatar: self.client.avatar,
			bot: self.client.bot,
			discriminator: self.client.discriminator,
		}
	}
	GetUserInfo(UserID){
		var self = this;
		return self.client.users[userID];
	}
}

module.exports = Bot;
<commit_msg>added a comment test<commit_after>var net = require('net');

var shortid = require('shortid');
var Discord = require('discord.io');

class Bot {
	constructor(key, disnode) {
		this.key = key;
		this.client = {};
		this.disnode = disnode;
		this.bind_onMessage = null;
		this.isRemote = false;
		this.remoteID = "";
	}

	Connect() {
		var self = this;
		return new Promise(function (resolve, reject) {

			if (self.disnode.botConfig.balancerEnabled == true) {
				if (!self.disnode.botConfig.balancerIP) {
					reject("No Load Balancer IP!");
				}
				if (!self.disnode.botConfig.balancerPORT) {
					reject("No Load Balancer Port!");
				}

				self.client.type == "REMOTE";
				self.client = new net.Socket();
				self.client.connect(self.disnode.botConfig.balancerPORT, self.disnode.botConfig.balancerIP, function () {
					self.remoteID = shortid.generate();
					self.client.write(JSON.stringify({
						type: "REGISTER",
						id: self.remoteID
					}))
					self.client.on('data', (data) => self.ParseRemoteCommand(data));
					self.isRemote = true;
					resolve("Connected to remote Load Balancer!");
					return;
				});
			} else {
				self.client = new Discord.Client({
					autorun: true,
					token: self.key
				});

				self.client.on('ready', function (event) {
					self.SetUpLocalBinds();
					resolve();
				});

			}

		});
	}

	Disconnect() {
		var self = this;
		return new Promise(function (resolve, reject) {
			self.client.disconnect();
			resolve();
		});
	}

	Restart() {
		var self = this;
		self.Disconnect().then(function (){
			self.client.connect()
		});
	}

	ParseRemoteCommand(command) {
		var self = this;
		var obj = JSON.parse(command);

		switch (obj.type) {
		case "RECV_MESSAGE":

			if (self.bind_onMessage) {
				self.bind_onMessage(obj.data);
			} else {

			}
		}
	}

	SetUpLocalBinds() {
		var self = this;
		self.client.on('message', function (user, userID, channelID, message, event) {
			if (self.bind_onMessage) {
				var _server = "DM";
				if(self.client.channels[channelID]){
						_server = self.client.channels[channelID].guild_id;
				}
				var msgObject = {
					user: user,
					userID: userID,
					channel: channelID,
					message: message,
					server: _server
				}
				self.bind_onMessage(msgObject);
			}
		});
	}

	bindOnMessage(msgFunction) {
		this.bind_onMessage = msgFunction;
	}

	SendMessage(channel, msg, typing=false, tts=false) {
		var self = this;
		if (self.isRemote) {
			var msgOBJ = {
				channel: channel,
				msg: msg,
				typing: typing,
      	tts: tts
			};
			var commandObj = {
				type: "SEND_MESSAGE",
				id: self.remoteID,
				data: msgOBJ
			};

			self.client.write(JSON.stringify(commandObj));
		}else{
			return new Promise(function(resolve, reject) {
				self.client.sendMessage({
					to: channel,
					message: msg,
		 			typing: typing,
		      tts: tts
				}, function(err, resp) {
					if(err){
						reject(err);
					}else {
						resolve(resp);
					}
				});
			});
		}
	}
	SendEmbed(channel, embed){
		var self = this;
		self.client.sendMessage({
			to: channel,
			embed: embed
		});
	}
	SendCompactEmbed(channel, title, body) {
		var self = this;
		self.client.sendMessage({
			to: channel,
			embed: {
				color: 3447003,
				author: {},
				fields: [{
					name: title,
					inline: false,
					value: body,
				}],
				footer: {}
			}
		});
	}
	SetStatus(status){
		var self = this;
		self.client.setPresence({game: {name: status}});
	}

	SetUsername(name){
		var self = this;
		self.client.editUserInfo({username: name});
	}

	JoinVoiceChannel(voiceID){
		var self = this;
		this.client.joinVoiceChannel(voiceID,function(err){
			if(err){
				console.log(err);
			}else{
			}
		})
	}

  LeaveVoiceChannel(voiceID){
		var self = this;
		this.client.leaveVoiceChannel(voiceID,function(err){
			if(err){
				console.log(err);
			}else{
			}
		})
	}
		JoinUsersVoiceChannel(serverID, userID){
		var user = this.GetUserByID(serverID, userID);
		if(!user){
			return;
		}
		this.JoinVoiceChannel(user.voice_channel_id);
	}
    LeaveUsersVoiceChannel(serverID, userID) {
    var user = this.GetUserByID(serverID, userID);
		if(!user){
			return;
		}
			this.LeaveVoiceChannel(user.voice_channel_id);
  }
		GetServerByID(id){
		var servers = this.client.servers;
		return servers[id];
	}
		GetUserByID(serverId, userId){
		var server = this.GetServerByID(serverId);
		if(!server){
			return;
		}
		return server.members[userId];
	}
		GetUserRoles(serverId, userId){
		var user = this.GetUserByID(serverId, userId);
		if(!user){
			return;
		}
		return user.roles;
	}

	GetRoleById(serverId, roleId){
		var server = this.GetServerByID(serverId);
		if(!server){
			return;
		}
		return server.roles[roleId];
	}
	//Oh hey im a comment!
	GetBotInfo(){
		var self = this;
		return {
			username: self.client.username,
			id: self.client.id,
			avatar: self.client.avatar,
			bot: self.client.bot,
			discriminator: self.client.discriminator,
		}
	}
	GetUserInfo(UserID){
		var self = this;
		return self.client.users[userID];
	}
}

module.exports = Bot;
<|endoftext|>


<commit_before>
var http = require("http");
var https = require("https");
var Promise = require("promise");

module.exports = {
  download: function(url) {
    url = this.completeUrl(url);

    return new Promise(function(resolve, reject) {
      var client = url.substring(0, 8) == "https://" ? https : http;

      client.get(url, function(res) {
        var chunks = [];

        res.on('data', function(chunk) {
          chunks.push(chunk);
        });

        res.on('end', function() {
          if (res.statusCode > 300 && res.statusCode <= 308) {
            if (res.headers.location) {
              resolve(module.exports.download(res.headers.location));
            }
          } else {
            resolve({
              data: Buffer.concat(chunks),
              headers: res.headers,
            });
          }
          reject("unknown failure");
        });
      })
      .on('error', function(err) {
        reject(err.message);
      });
    });
  },
  completeUrl: function(url) {
    if (!url.match('://')) {
      url = 'http://' + url;
    }
    return url;
  },
};
<commit_msg>Use 'return' to break out of function<commit_after>
var http = require("http");
var https = require("https");
var Promise = require("promise");

module.exports = {
  download: function(url) {
    url = this.completeUrl(url);

    return new Promise(function(resolve, reject) {
      var client = url.substring(0, 8) == "https://" ? https : http;

      client.get(url, function(res) {
        var chunks = [];

        res.on('data', function(chunk) {
          chunks.push(chunk);
        });

        res.on('end', function() {
          if (res.statusCode > 300 && res.statusCode <= 308) {
            if (res.headers.location) {
              return resolve(module.exports.download(res.headers.location));
            }
          } else {
            return resolve({
              data: Buffer.concat(chunks),
              headers: res.headers,
            });
          }
          reject("unknown failure");
        });
      })
      .on('error', function(err) {
        reject(err.message);
      });
    });
  },
  completeUrl: function(url) {
    if (!url.match('://')) {
      url = 'http://' + url;
    }
    return url;
  },
};
<|endoftext|>


<commit_before>import { directiveConfig } from '../util/helpers'

function dropdown (e, el, id, bus, hover) {
  e.preventDefault()

  const component = document.getElementById(id)

  if (!component
    ||!component.dataset.hover && hover
    || component.style.display !== 'none'
  ) {
    return
  }

  let width = 0
  let height = 0
  let offset = component.dataset.offset

  component.style.minWidth = `${el.clientWidth}px`
  component.style.display = 'block'
  let componentWidth = component.clientWidth
  let componentHeight = component.clientHeight
  component.style.display = 'none'

  if (component.dataset.bottom) {
    height = componentHeight - (offset ? 0 : el.clientHeight)
  } else {
    height = offset ? -el.clientHeight : 0
  }

  if (component.dataset.right) {
    width = componentWidth - (offset ? 0 : el.clientWidth)
  } else {
    width = offset ? -el.clientWidth : 0
  }

  component.style.left = `${el.offsetLeft - width}px`
  component.style.top = `${el.offsetTop - height}px`

  bus.pub(`dropdown:open:${id}`)
}

function directive (el, binding, v) {
  const config = directiveConfig(binding)
  let id = config.value
  let bus = v.context.$vuetify.bus

  el.dataset.dropdown = id

  // Directive binding happens before all components are rendered
  // When changing routes, dropdown element may not be ready
  // Do hover check within dropdown function
  el.onclick = e => dropdown(e, el, id, bus, false)
  el.onmouseenter = e => dropdown(e, el, id, bus, true)
}

export default {
  bind: directive,
  updated: directive,
  componentUpdated: directive,
  unbind (el) {
    el.removeAttribute('onclick')
    el.removeAttribute('onmouseenter')
    el.removeAttribute('onmouseleave')
    el.removeAttribute('data-dropdown')
  }
}<commit_msg>bug fix for #102<commit_after>import { directiveConfig } from '../util/helpers'

function dropdown (e, el, component, bus, hover) {
  e.preventDefault()

  let width = 0
  let height = 0
  let offset = component.dataset.offset

  component.style.minWidth = `${el.clientWidth}px`
  component.style.display = 'block'
  let componentWidth = component.clientWidth
  let componentHeight = component.clientHeight
  component.style.display = 'none'

  if (component.dataset.bottom) {
    height = componentHeight - (offset ? 0 : el.clientHeight)
  } else {
    height = offset ? -el.clientHeight : 0
  }

  if (component.dataset.right) {
    width = componentWidth - (offset ? 0 : el.clientWidth)
  } else {
    width = offset ? -el.clientWidth : 0
  }

  component.style.left = `${el.offsetLeft - width}px`
  component.style.top = `${el.offsetTop - height}px`

  bus.pub(`dropdown:open:${component.id}`)
}

function directive (el, binding, v) {
  const config = directiveConfig(binding)
  let id = config.value
  let bus = v.context.$vuetify.bus

  el.dataset.dropdown = id
  const component = document.getElementById(id)

  // Directive binding happens before all components are rendered
  // When changing routes, dropdown element may not be ready
  // Do hover check within dropdown function
  if (component.dataset && component.dataset.hover) {
    el.onmouseenter = e => dropdown(e, el, component, bus, true)
  } else {
    el.onclick = e => dropdown(e, el, component, bus, false)
  }
}

export default {
  bind: directive,
  updated: directive,
  componentUpdated: directive,
  unbind (el) {
    el.removeAttribute('onclick')
    el.removeAttribute('onmouseenter')
    el.removeAttribute('onmouseleave')
    el.removeAttribute('data-dropdown')
  }
}<|endoftext|>


<commit_before>(function() {
  /**
   * Main Angular Handsontable directive
   */
  function hotTable(settingFactory, autoCompleteFactory, $rootScope) {
    return {
      restrict: 'EA',
      scope: {},
      // for ng-repeat
      priority: -400,
      controller: ['$scope', function($scope) {
        this.setColumnSetting = function(column) {
          if (!$scope.htSettings) {
            $scope.htSettings = {};
          }
          if (!$scope.htSettings.columns) {
            $scope.htSettings.columns = [];
          }
          $scope.htSettings.columns.push(column);
          settingFactory.updateHandsontableSettings($scope.hotInstance, $scope.htSettings);
        };
        this.removeColumnSetting = function(column) {
          if ($scope.htSettings.columns.indexOf(column) > -1) {
            $scope.htSettings.columns.splice($scope.htSettings.columns.indexOf(column), 1);
            settingFactory.updateHandsontableSettings($scope.hotInstance, $scope.htSettings);
          }
        };
      }],
      compile: function(tElement, tAttrs) {
        var _this = this,
          bindingsKeys;

        this.scope = settingFactory.trimScopeDefinitionAccordingToAttrs(settingFactory.getTableScopeDefinition(), tAttrs);
        bindingsKeys = Object.keys(this.scope);

        angular.forEach(bindingsKeys, function(key) {
          var mode = _this.scope[key].charAt(0);
          _this.$$isolateBindings[key] = {
            attrName: _this.scope[key].length > 1 ? _this.scope[key].substr(1, _this.scope[key].length) : key,
            collection: false,
            mode: mode,
            optional: false
          };
        });

        return function(scope, element, attrs) {
          if (!scope.htSettings) {
            scope.htSettings = {};
          }
          settingFactory.mergeSettingsFromScope(scope.htSettings, scope);
          settingFactory.mergeHooksFromScope(scope.htSettings, scope);
          scope.htSettings.data = scope.datarows;
          scope.htSettings.dataSchema = scope.dataschema;
          scope.htSettings.hotId = attrs.hotId;
          scope.htSettings.observeDOMVisibility = scope.observeDomVisibility;

          if (scope.htSettings.columns) {
            for (var i = 0, length = scope.htSettings.columns.length; i < length; i++) {
              if (scope.htSettings.columns[i].type !== 'autocomplete') {
                continue;
              }
              if (typeof scope.htSettings.columns[i].optionList === 'string') {
                var optionList = {};
                var match = scope.htSettings.columns[i].optionList.match(/^\s*(.+)\s+in\s+(.*)\s*$/);

                if (match) {
                  optionList.property = match[1];
                  optionList.object = match[2];
                } else {
                  optionList.object = optionList;
                }
                scope.htSettings.columns[i].optionList = optionList;
              }
              autoCompleteFactory.parseAutoComplete(scope.htSettings.columns[i], scope.datarows, true);
            }
          }
          scope.hotInstance = settingFactory.initializeHandsontable(element, scope.htSettings);

          var origAfterChange = scope.htSettings.afterChange;

          scope.htSettings.afterChange = function() {
            if (origAfterChange) {
              origAfterChange.apply(this, arguments);
            }
            if (!$rootScope.$$phase) {
              scope.$apply();
            }
          };

          // TODO: Add watch properties descriptor
          angular.forEach(bindingsKeys, function(key) {
            scope.$watch(key, function(newValue) {
              if (newValue === void 0) {
                return;
              }
              if (key === 'datarows') {
                settingFactory.renderHandsontable(scope.hotInstance);
              } else {
                scope.htSettings[key] = newValue;
                settingFactory.updateHandsontableSettings(scope.hotInstance, scope.htSettings);
              }
            }, ['datarows', 'columns', 'colWidths', 'rowHeaders'].indexOf(key) >= 0);
          });

          /**
           * Check if data length has been changed
           */
          scope.$watchCollection('datarows', function(newValue, oldValue) {
            if (oldValue && oldValue.length === scope.htSettings.minSpareRows && newValue.length !== scope.htSettings.minSpareRows) {
              scope.htSettings.data = scope.datarows;
              settingFactory.updateHandsontableSettings(scope.hotInstance, scope.htSettings);
            }
          });
        };
      }
    };
  }
  hotTable.$inject = ['settingFactory', 'autoCompleteFactory', '$rootScope'];

  angular.module('ngHandsontable.directives').directive('hotTable', hotTable);
}());
<commit_msg>Update TODO list<commit_after>(function() {
  /**
   * Main Angular Handsontable directive
   */
  function hotTable(settingFactory, autoCompleteFactory, $rootScope) {
    return {
      restrict: 'EA',
      scope: {},
      // for ng-repeat
      priority: -400,
      controller: ['$scope', function($scope) {
        this.setColumnSetting = function(column) {
          if (!$scope.htSettings) {
            $scope.htSettings = {};
          }
          if (!$scope.htSettings.columns) {
            $scope.htSettings.columns = [];
          }
          $scope.htSettings.columns.push(column);
          settingFactory.updateHandsontableSettings($scope.hotInstance, $scope.htSettings);
        };
        this.removeColumnSetting = function(column) {
          if ($scope.htSettings.columns.indexOf(column) > -1) {
            $scope.htSettings.columns.splice($scope.htSettings.columns.indexOf(column), 1);
            settingFactory.updateHandsontableSettings($scope.hotInstance, $scope.htSettings);
          }
        };
      }],
      compile: function(tElement, tAttrs) {
        var _this = this,
          bindingsKeys;

        this.scope = settingFactory.trimScopeDefinitionAccordingToAttrs(settingFactory.getTableScopeDefinition(), tAttrs);
        bindingsKeys = Object.keys(this.scope);

        angular.forEach(bindingsKeys, function(key) {
          var mode = _this.scope[key].charAt(0);
          _this.$$isolateBindings[key] = {
            attrName: _this.scope[key].length > 1 ? _this.scope[key].substr(1, _this.scope[key].length) : key,
            collection: false,
            mode: mode,
            optional: false
          };
        });

        return function(scope, element, attrs) {
          if (!scope.htSettings) {
            scope.htSettings = {};
          }
          settingFactory.mergeSettingsFromScope(scope.htSettings, scope);
          settingFactory.mergeHooksFromScope(scope.htSettings, scope);
          scope.htSettings.data = scope.datarows;
          scope.htSettings.dataSchema = scope.dataschema;
          scope.htSettings.hotId = attrs.hotId;
          scope.htSettings.observeDOMVisibility = scope.observeDomVisibility;

          if (scope.htSettings.columns) {
            for (var i = 0, length = scope.htSettings.columns.length; i < length; i++) {
              if (scope.htSettings.columns[i].type !== 'autocomplete') {
                continue;
              }
              if (typeof scope.htSettings.columns[i].optionList === 'string') {
                var optionList = {};
                var match = scope.htSettings.columns[i].optionList.match(/^\s*(.+)\s+in\s+(.*)\s*$/);

                if (match) {
                  optionList.property = match[1];
                  optionList.object = match[2];
                } else {
                  optionList.object = optionList;
                }
                scope.htSettings.columns[i].optionList = optionList;
              }
              autoCompleteFactory.parseAutoComplete(scope.htSettings.columns[i], scope.datarows, true);
            }
          }
          scope.hotInstance = settingFactory.initializeHandsontable(element, scope.htSettings);

          var origAfterChange = scope.htSettings.afterChange;

          scope.htSettings.afterChange = function() {
            if (origAfterChange) {
              origAfterChange.apply(this, arguments);
            }
            if (!$rootScope.$$phase) {
              scope.$apply();
            }
          };

          // TODO: Add watch properties descriptor + needs perf test watch equality vs toJson
          angular.forEach(bindingsKeys, function(key) {
            scope.$watch(key, function(newValue) {
              if (newValue === void 0) {
                return;
              }
              if (key === 'datarows') {
                settingFactory.renderHandsontable(scope.hotInstance);
              } else {
                scope.htSettings[key] = newValue;
                settingFactory.updateHandsontableSettings(scope.hotInstance, scope.htSettings);
              }
            }, ['datarows', 'columns', 'colWidths', 'rowHeaders'].indexOf(key) >= 0);
          });

          /**
           * Check if data length has been changed
           */
          scope.$watchCollection('datarows', function(newValue, oldValue) {
            if (oldValue && oldValue.length === scope.htSettings.minSpareRows && newValue.length !== scope.htSettings.minSpareRows) {
              scope.htSettings.data = scope.datarows;
              settingFactory.updateHandsontableSettings(scope.hotInstance, scope.htSettings);
            }
          });
        };
      }
    };
  }
  hotTable.$inject = ['settingFactory', 'autoCompleteFactory', '$rootScope'];

  angular.module('ngHandsontable.directives').directive('hotTable', hotTable);
}());
<|endoftext|>


<commit_before>'use strict'
export const STARTUP_TAB = 'STARTUP_TAB'
export const FOLDER_TAB = 'FOLDER_TAB'
export const CHAT_TAB = 'CHAT_TAB'
export const PEOPLE_TAB = 'PEOPLE_TAB'
export const DEVICES_TAB = 'DEVICES_TAB'
export const MORE_TAB = 'MORE_TAB'
<commit_msg>Add prettify function for tab constants<commit_after>'use strict'
export const STARTUP_TAB = 'STARTUP_TAB'
export const FOLDER_TAB = 'FOLDER_TAB'
export const CHAT_TAB = 'CHAT_TAB'
export const PEOPLE_TAB = 'PEOPLE_TAB'
export const DEVICES_TAB = 'DEVICES_TAB'
export const MORE_TAB = 'MORE_TAB'

const prettyNames = {
  [STARTUP_TAB]: null,
  [FOLDER_TAB]: 'Folder',
  [CHAT_TAB]: 'Chat',
  [PEOPLE_TAB]: 'People',
  [DEVICES_TAB]: 'Devices',
  [MORE_TAB]: 'More'
}

export function prettify (tabName) {
  return prettyNames[tabName] || 'You have found a bug'
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { isEmpty } from 'lodash';

import { setEmail } from 'app/actions';

import './Nav.scss';

class Nav extends Component {
    componentWillMount() {
        const token = localStorage.getItem('bap-token');

        if (!isEmpty(token)) {
            fetch('/api/authenticate', {
                method: 'POST',
                headers: {
                    'content-type': 'application/json'
                },
                body: JSON.stringify({
                    token
                })
            })
                .then(response => response.json())
                .then(json => {
                    if (json.email) {
                        this.props.onSetEmail(json.email);
                    }
                });
        }
    }

    logout = event => {
        event.preventDefault();

        localStorage.setItem('bap-token', '');
        this.props.onSetEmail('');
    };

    renderLogin() {
        if (!this.props.email) {
            return (
                <Link className="Nav__right-link" to="/login">
                    Log in
                </Link>
            );
        }

        return (
            <Link className="Nav__right-link" to="/" onClick={this.logout}>
                Log out
            </Link>
        );
    }

    render() {
        return (

                <Link className="Nav__logo-section" to="/">

BEST

ACT

PREP

                </Link>

                <Link className="Nav__right-link" to="/course">
                    Start for free
                </Link>
                <Link className="Nav__right-link Nav__right-link--buy" to="/buy">
                    Get NO RISK, FULL access
                </Link>
                <Link className="Nav__right-link" to="/contact">
                    Contact
                </Link>
                {this.renderLogin()}

        );
    }
}

const mapStateToProps = function(state) {
    return {
        email: state.app.email
    };
};

const mapActionsToProps = {
    onSetEmail: setEmail
};

export default connect(mapStateToProps, mapActionsToProps)(Nav);
<commit_msg>fix nav links<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { isEmpty } from 'lodash';

import { setEmail } from 'app/actions';

import './Nav.scss';

class Nav extends Component {
    componentWillMount() {
        const token = localStorage.getItem('bap-token');

        if (!isEmpty(token)) {
            fetch('/api/authenticate', {
                method: 'POST',
                headers: {
                    'content-type': 'application/json'
                },
                body: JSON.stringify({
                    token
                })
            })
                .then(response => response.json())
                .then(json => {
                    if (json.email) {
                        this.props.onSetEmail(json.email);
                    }
                });
        }
    }

    logout = event => {
        event.preventDefault();

        localStorage.setItem('bap-token', '');
        this.props.onSetEmail('');
    };

    renderCourse() {
        return (
            <Link className="Nav__right-link" to="/course">
                {this.props.email ? 'Course Home' : 'Start for Free'}
            </Link>
        );
    }

    renderBuy() {
        if (this.props.email) { return null; }

        return (
            <Link className="Nav__right-link Nav__right-link--buy" to="/buy">
                Get NO RISK, FULL access
            </Link>
        );
    }

    renderLogin() {
        if (!this.props.email) {
            return (
                <Link className="Nav__right-link" to="/login">
                    Log in
                </Link>
            );
        }

        return (
            <Link className="Nav__right-link" to="/" onClick={this.logout}>
                Log out
            </Link>
        );
    }

    render() {
        return (

                <Link className="Nav__logo-section" to="/">

BEST

ACT

PREP

                </Link>

                {this.renderCourse()}
                {this.renderBuy()}
                <Link className="Nav__right-link" to="/contact">
                    Contact
                </Link>
                {this.renderLogin()}

        );
    }
}

const mapStateToProps = function(state) {
    return {
        email: state.app.email
    };
};

const mapActionsToProps = {
    onSetEmail: setEmail
};

export default connect(mapStateToProps, mapActionsToProps)(Nav);
<|endoftext|>


<commit_before>// @flow

import { MiddlewareRegistry } from '../base/redux';
import { updateSettings } from '../base/settings';
import { getLocalVideoTrack, replaceLocalTrack } from '../base/tracks';

import { PREJOIN_START_CONFERENCE } from './actionTypes';
import { setPrejoinPageVisibility } from './actions';

declare var APP: Object;

/**
 * The redux middleware for {@link PrejoinPage}.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => async action => {
    switch (action.type) {
    case PREJOIN_START_CONFERENCE: {
        const { getState, dispatch } = store;
        const state = getState();
        const { userSelectedSkipPrejoin } = state['features/prejoin'];
        const localVideoTrack = getLocalVideoTrack(state['features/base/tracks']);

        userSelectedSkipPrejoin && dispatch(updateSettings({
            userSelectedSkipPrejoin
        }));

        if (localVideoTrack?.muted) {
            await dispatch(replaceLocalTrack(localVideoTrack.jitsiTrack, null));
        }

        const jitsiTracks = getState()['features/base/tracks'].map(t => t.jitsiTrack);

        dispatch(setPrejoinPageVisibility(false));
        APP.conference.prejoinStart(jitsiTracks);

        break;
    }
    }

    return next(action);
});
<commit_msg>feat(prejoin) cache media start options when on prejoin screen<commit_after>// @flow

import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../base/media';
import { MiddlewareRegistry } from '../base/redux';
import { updateSettings } from '../base/settings';
import { getLocalVideoTrack, replaceLocalTrack } from '../base/tracks';

import { PREJOIN_START_CONFERENCE } from './actionTypes';
import { setPrejoinPageVisibility } from './actions';
import { isPrejoinPageVisible } from './functions';

declare var APP: Object;

/**
 * The redux middleware for {@link PrejoinPage}.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => async action => {
    switch (action.type) {
    case PREJOIN_START_CONFERENCE: {
        const { getState, dispatch } = store;
        const state = getState();
        const { userSelectedSkipPrejoin } = state['features/prejoin'];
        const localVideoTrack = getLocalVideoTrack(state['features/base/tracks']);

        userSelectedSkipPrejoin && dispatch(updateSettings({
            userSelectedSkipPrejoin
        }));

        if (localVideoTrack?.muted) {
            await dispatch(replaceLocalTrack(localVideoTrack.jitsiTrack, null));
        }

        const jitsiTracks = getState()['features/base/tracks'].map(t => t.jitsiTrack);

        dispatch(setPrejoinPageVisibility(false));
        APP.conference.prejoinStart(jitsiTracks);

        break;
    }

    case SET_AUDIO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithAudioMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    case SET_VIDEO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithVideoMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    }

    return next(action);
});
<|endoftext|>


<commit_before>// @flow

import { updateConfig } from '../base/config';
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../base/media';
import { MiddlewareRegistry } from '../base/redux';
import { updateSettings } from '../base/settings';
import {
    getLocalTracks,
    replaceLocalTrack,
    TRACK_ADDED,
    TRACK_NO_DATA_FROM_SOURCE
} from '../base/tracks';

import { PREJOIN_START_CONFERENCE } from './actionTypes';
import {
    setDeviceStatusOk,
    setDeviceStatusWarning,
    setPrejoinPageVisibility
} from './actions';
import { isPrejoinPageVisible } from './functions';

declare var APP: Object;

/**
 * The redux middleware for {@link PrejoinPage}.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => async action => {
    switch (action.type) {
    case PREJOIN_START_CONFERENCE: {
        const { getState, dispatch } = store;
        const state = getState();
        const { userSelectedSkipPrejoin } = state['features/prejoin'];
        const localTracks = getLocalTracks(state['features/base/tracks']);
        const { options } = action;

        options && store.dispatch(updateConfig(options));

        userSelectedSkipPrejoin && dispatch(updateSettings({
            userSelectedSkipPrejoin
        }));

        // Do not signal audio/video tracks if the user joins muted.
        for (const track of localTracks) {
            if (track.muted) {
                await dispatch(replaceLocalTrack(track.jitsiTrack, null));
            }
        }
        const jitsiTracks = localTracks.map(t => t.jitsiTrack);

        dispatch(setPrejoinPageVisibility(false));
        APP.conference.prejoinStart(jitsiTracks);

        break;
    }

    case SET_AUDIO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithAudioMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    case SET_VIDEO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithVideoMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    case TRACK_ADDED:
    case TRACK_NO_DATA_FROM_SOURCE: {
        const state = store.getState();

        if (isPrejoinPageVisible(state)) {
            const { track: { jitsiTrack: track } } = action;
            const { deviceStatusType, deviceStatusText } = state['features/prejoin'];

            if (!track.isAudioTrack()) {
                break;
            }

            if (track.isReceivingData()) {
                if (deviceStatusType === 'warning'
                    && deviceStatusText === 'prejoin.audioDeviceProblem') {
                    store.dispatch(setDeviceStatusOk('prejoin.lookGood'));
                }
            } else if (deviceStatusType === 'ok') {
                store.dispatch(setDeviceStatusWarning('prejoin.audioDeviceProblem'));
            }
        }
        break;
    }

    }

    return next(action);
});
<commit_msg>fix(prejoin): disposed track was added to the conference<commit_after>// @flow

import { updateConfig } from '../base/config';
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../base/media';
import { MiddlewareRegistry } from '../base/redux';
import { updateSettings } from '../base/settings';
import {
    getLocalTracks,
    replaceLocalTrack,
    TRACK_ADDED,
    TRACK_NO_DATA_FROM_SOURCE
} from '../base/tracks';

import { PREJOIN_START_CONFERENCE } from './actionTypes';
import {
    setDeviceStatusOk,
    setDeviceStatusWarning,
    setPrejoinPageVisibility
} from './actions';
import { isPrejoinPageVisible } from './functions';

declare var APP: Object;

/**
 * The redux middleware for {@link PrejoinPage}.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => async action => {
    switch (action.type) {
    case PREJOIN_START_CONFERENCE: {
        const { getState, dispatch } = store;
        const state = getState();
        const { userSelectedSkipPrejoin } = state['features/prejoin'];
        let localTracks = getLocalTracks(state['features/base/tracks']);
        const { options } = action;

        options && store.dispatch(updateConfig(options));

        userSelectedSkipPrejoin && dispatch(updateSettings({
            userSelectedSkipPrejoin
        }));

        // Do not signal audio/video tracks if the user joins muted.
        for (const track of localTracks) {
            if (track.muted) {
                await dispatch(replaceLocalTrack(track.jitsiTrack, null));
            }
        }

        // Re-fetch the local tracks after muted tracks have been removed above.
        // This is needed, because the tracks are effectively disposed by the replaceLocalTrack and should not be used
        // anymore.
        localTracks = getLocalTracks(getState()['features/base/tracks']);

        const jitsiTracks = localTracks.map(t => t.jitsiTrack);

        dispatch(setPrejoinPageVisibility(false));
        APP.conference.prejoinStart(jitsiTracks);

        break;
    }

    case SET_AUDIO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithAudioMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    case SET_VIDEO_MUTED: {
        if (isPrejoinPageVisible(store.getState())) {
            store.dispatch(updateSettings({
                startWithVideoMuted: Boolean(action.muted)
            }));
        }
        break;
    }

    case TRACK_ADDED:
    case TRACK_NO_DATA_FROM_SOURCE: {
        const state = store.getState();

        if (isPrejoinPageVisible(state)) {
            const { track: { jitsiTrack: track } } = action;
            const { deviceStatusType, deviceStatusText } = state['features/prejoin'];

            if (!track.isAudioTrack()) {
                break;
            }

            if (track.isReceivingData()) {
                if (deviceStatusType === 'warning'
                    && deviceStatusText === 'prejoin.audioDeviceProblem') {
                    store.dispatch(setDeviceStatusOk('prejoin.lookGood'));
                }
            } else if (deviceStatusType === 'ok') {
                store.dispatch(setDeviceStatusWarning('prejoin.audioDeviceProblem'));
            }
        }
        break;
    }

    }

    return next(action);
});
<|endoftext|>


<commit_before>(function (angular, buildfire) {
    'use strict';
    if (!buildfire) {
        throw ("buildfire not found");
    }
    angular
        .module('placesModals', ['placesFilters', 'ui.bootstrap'])
        .factory('Modals', ['$modal', '$q','$timeout', function ($modal, $q,$timeout) {
            return {
                removePopupModal: function (info) {
                    var removePopupDeferred = $q.defer();
                    var removePopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/rm-section-modal.html',
                            controller: 'RemovePopupCtrl',
                            controllerAs: 'RemovePopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                }
                            }
                        });
                    removePopupModal.result.then(function (imageInfo) {
                        removePopupDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        removePopupDeferred.reject(err);
                    });
                    return removePopupDeferred.promise;
                },
                DeeplinkPopupModal: function (info) {
                    var DeeplinkPopupDeferred = $q.defer();
                    var DeeplinkPopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/deep-link-copy.html',
                            controller: 'DeepLinkPopupCtrl',
                            controllerAs: 'DeepLinkPopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                }
                            }
                        });
                    DeeplinkPopupModal.result.then(function (imageInfo) {
                        DeeplinkPopupDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        DeeplinkPopupDeferred.reject(err);
                    });
                    return DeeplinkPopupDeferred.promise;
                },
                editSectionModal: function (sections, info) {
                    var editSectionDeferred = $q.defer();
                    var editSectionPopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/edit-section-modal.html',
                            controller: 'ContentSectionPopupCtrl',
                            controllerAs: 'ContentSectionPopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                },
                                Sections: function () {
                                    return sections;
                                }
                            }
                        });
                    editSectionPopupModal.result.then(function (imageInfo) {
                        editSectionDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        editSectionDeferred.reject(err);
                    });
                    return editSectionDeferred.promise;
                },
                selectAllItemImageModal: function (PlaceInfo) {
                    var selectImageDeferred = $q.defer();
                    var selectImagePopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/add-image-allitems.html',
                            controller: 'SelectImagePopupCtrl',
                            controllerAs: 'SelectImagePopup',
                            size: 'sm',
                            resolve: {
                                PlaceInfo: function () {
                                    return PlaceInfo;
                                }
                            }
                        });
                    selectImagePopupModal.result.then(function (_placeInfo) {
                        selectImageDeferred.resolve(_placeInfo);
                    }, function (err) {
                        //do something on cancel
                        selectImageDeferred.reject(err);
                    });
                    return selectImageDeferred.promise;
                }

            };
        }])
        .controller('RemovePopupCtrl', ['$scope', '$modalInstance', 'Info','$timeout', function ($scope, $modalInstance, Info,$timeout) {
            console.log('RemovePopup Controller called-----');
            $timeout(function () {
                console.log('Modal Top Changed');
                var top =  Info.event.pageY-50;
                $('.modal-dialog.modal-sm').offset({top: top, left: 0});
            }, 30);
            $scope.ok = function () {
                $modalInstance.close('yes');
            };
            $scope.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }])
        .controller('DeepLinkPopupCtrl', ['$scope', '$modalInstance', 'Info', function ($scope, $modalInstance, Info) {
            var DeepLinkPopup = this;
            if (Info) {
                DeepLinkPopup.deepLinkUrl = Info;
            }
            DeepLinkPopup.ok = function () {
                $modalInstance.close('yes');
            };
            DeepLinkPopup.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }])
        .controller('SelectImagePopupCtrl', ['$scope', '$modalInstance', 'PlaceInfo', 'Buildfire', function ($scope, $modalInstance, PlaceInfo, Buildfire) {
            var SelectImagePopup = this;
            if (PlaceInfo) {
                SelectImagePopup.PlaceInfo = PlaceInfo;
            }
            SelectImagePopup.selectImage = function () {
                var options = {showIcons: false, multiSelection: false}
                    , callback = function (error, result) {
                        if (error) {
                            console.error('Error:', error);
                        } else {
                            SelectImagePopup.PlaceInfo.data.content.allItemImage = result.selectedFiles && result.selectedFiles[0] || null;

                            if (!$scope.$$phase)$scope.$digest();
                        }
                    };
                Buildfire.imageLib.showDialog(options, callback);
            };
            SelectImagePopup.removeImage = function () {
                SelectImagePopup.PlaceInfo.data.content.allItemImage = null;
            };
            SelectImagePopup.ok = function () {
                $modalInstance.close(SelectImagePopup.PlaceInfo);
            };
            SelectImagePopup.cancel = function () {
                $modalInstance.dismiss();
            };
        }])
        .controller('ContentSectionPopupCtrl', ['$scope', '$modalInstance', 'Info', 'Sections', function ($scope, $modalInstance, Info, Sections) {

            if (Info) {
                $scope.info = Info;
            }
            if (Sections) {
                $scope.sections = Sections;

                angular.forEach($scope.sections, function (value) {
                    value.data.selected = ($scope.info.data.sections.indexOf(value.id) >= 0);
                });
            }
            $scope.ok = function () {
                $scope.info.data.sections = [];
                angular.forEach($scope.sections, function (value) {
                    if (value.data.selected)
                        $scope.info.data.sections.push(value.id);
                });
                $modalInstance.close($scope.info);
            };
            $scope.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }]);
})(window.angular, window.buildfire);
<commit_msg>Increased the delay time<commit_after>(function (angular, buildfire) {
    'use strict';
    if (!buildfire) {
        throw ("buildfire not found");
    }
    angular
        .module('placesModals', ['placesFilters', 'ui.bootstrap'])
        .factory('Modals', ['$modal', '$q','$timeout', function ($modal, $q,$timeout) {
            return {
                removePopupModal: function (info) {
                    var removePopupDeferred = $q.defer();
                    var removePopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/rm-section-modal.html',
                            controller: 'RemovePopupCtrl',
                            controllerAs: 'RemovePopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                }
                            }
                        });
                    removePopupModal.result.then(function (imageInfo) {
                        removePopupDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        removePopupDeferred.reject(err);
                    });
                    return removePopupDeferred.promise;
                },
                DeeplinkPopupModal: function (info) {
                    var DeeplinkPopupDeferred = $q.defer();
                    var DeeplinkPopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/deep-link-copy.html',
                            controller: 'DeepLinkPopupCtrl',
                            controllerAs: 'DeepLinkPopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                }
                            }
                        });
                    DeeplinkPopupModal.result.then(function (imageInfo) {
                        DeeplinkPopupDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        DeeplinkPopupDeferred.reject(err);
                    });
                    return DeeplinkPopupDeferred.promise;
                },
                editSectionModal: function (sections, info) {
                    var editSectionDeferred = $q.defer();
                    var editSectionPopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/edit-section-modal.html',
                            controller: 'ContentSectionPopupCtrl',
                            controllerAs: 'ContentSectionPopup',
                            size: 'sm',
                            resolve: {
                                Info: function () {
                                    return info;
                                },
                                Sections: function () {
                                    return sections;
                                }
                            }
                        });
                    editSectionPopupModal.result.then(function (imageInfo) {
                        editSectionDeferred.resolve(imageInfo);
                    }, function (err) {
                        //do something on cancel
                        editSectionDeferred.reject(err);
                    });
                    return editSectionDeferred.promise;
                },
                selectAllItemImageModal: function (PlaceInfo) {
                    var selectImageDeferred = $q.defer();
                    var selectImagePopupModal = $modal
                        .open({
                            templateUrl: 'templates/modals/add-image-allitems.html',
                            controller: 'SelectImagePopupCtrl',
                            controllerAs: 'SelectImagePopup',
                            size: 'sm',
                            resolve: {
                                PlaceInfo: function () {
                                    return PlaceInfo;
                                }
                            }
                        });
                    selectImagePopupModal.result.then(function (_placeInfo) {
                        selectImageDeferred.resolve(_placeInfo);
                    }, function (err) {
                        //do something on cancel
                        selectImageDeferred.reject(err);
                    });
                    return selectImageDeferred.promise;
                }

            };
        }])
        .controller('RemovePopupCtrl', ['$scope', '$modalInstance', 'Info','$timeout', function ($scope, $modalInstance, Info,$timeout) {
            console.log('RemovePopup Controller called-----');
            $timeout(function () {
                console.log('Modal Top Changed');
                var top =  Info.event.pageY-50;
                $('.modal-dialog.modal-sm').offset({top: top, left: 0});
            }, 1000);
            $scope.ok = function () {
                $modalInstance.close('yes');
            };
            $scope.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }])
        .controller('DeepLinkPopupCtrl', ['$scope', '$modalInstance', 'Info', function ($scope, $modalInstance, Info) {
            var DeepLinkPopup = this;
            if (Info) {
                DeepLinkPopup.deepLinkUrl = Info;
            }
            DeepLinkPopup.ok = function () {
                $modalInstance.close('yes');
            };
            DeepLinkPopup.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }])
        .controller('SelectImagePopupCtrl', ['$scope', '$modalInstance', 'PlaceInfo', 'Buildfire', function ($scope, $modalInstance, PlaceInfo, Buildfire) {
            var SelectImagePopup = this;
            if (PlaceInfo) {
                SelectImagePopup.PlaceInfo = PlaceInfo;
            }
            SelectImagePopup.selectImage = function () {
                var options = {showIcons: false, multiSelection: false}
                    , callback = function (error, result) {
                        if (error) {
                            console.error('Error:', error);
                        } else {
                            SelectImagePopup.PlaceInfo.data.content.allItemImage = result.selectedFiles && result.selectedFiles[0] || null;

                            if (!$scope.$$phase)$scope.$digest();
                        }
                    };
                Buildfire.imageLib.showDialog(options, callback);
            };
            SelectImagePopup.removeImage = function () {
                SelectImagePopup.PlaceInfo.data.content.allItemImage = null;
            };
            SelectImagePopup.ok = function () {
                $modalInstance.close(SelectImagePopup.PlaceInfo);
            };
            SelectImagePopup.cancel = function () {
                $modalInstance.dismiss();
            };
        }])
        .controller('ContentSectionPopupCtrl', ['$scope', '$modalInstance', 'Info', 'Sections', function ($scope, $modalInstance, Info, Sections) {

            if (Info) {
                $scope.info = Info;
            }
            if (Sections) {
                $scope.sections = Sections;

                angular.forEach($scope.sections, function (value) {
                    value.data.selected = ($scope.info.data.sections.indexOf(value.id) >= 0);
                });
            }
            $scope.ok = function () {
                $scope.info.data.sections = [];
                angular.forEach($scope.sections, function (value) {
                    if (value.data.selected)
                        $scope.info.data.sections.push(value.id);
                });
                $modalInstance.close($scope.info);
            };
            $scope.cancel = function () {
                $modalInstance.dismiss('no');
            };
        }]);
})(window.angular, window.buildfire);
<|endoftext|>