<commit_before>// dependencies ----------------------------------------------------------------------

import React           from 'react';
import Reflux          from 'reflux';
import Actions         from './upload.actions.js';
import notifications   from '../notification/notification.actions.js';
import scitran         from '../utils/scitran';
import upload          from './upload';
import files           from '../utils/files';
import validate        from 'bids-validator';
import userStore       from '../user/user.store';
import datasetsActions from '../dashboard/datasets.actions';
import datasetActions  from '../dataset/dataset.actions';
import favico          from 'favico.js';
import bowser          from 'bowser';

let favicon = new favico();

// store setup -----------------------------------------------------------------------

let UploadStore = Reflux.createStore({

    listenables: Actions,

    init: function () {
        // Reset Favico incase timeout or issues
        favicon.reset();
        this.setInitialState();
    },

    getInitialState: function () {
        return this.data;
    },

// state data ------------------------------------------------------------------------

    data: {},

    update: function (data, callback) {
        for (let prop in data) {this.data[prop] = data[prop];}
        this.trigger(this.data, callback);
    },

    /**
     * Set Initial State
     *
     * Sets the state to the data object defined
     * inside the function. Also takes a diffs object
     * which will set the state to the initial state
     * with any differences passed.
     */
    setInitialState: function (diffs, callback) {
        let data = {
            activeKey: 1,
            changeName: false,
            dirName: '',
            disabledTab: false,
            errors: [],
            list: {},
            nameError: null,
            progress: {total: 0, completed: 0, currentFiles: []},
            projectId: '',
            refs: {},
            resuming: false,
            selectedName: '',
            showModal: false,
            showSelect: true,
            showRename: false,
            renameEnabled: true,
            showRenameInput: true,
            showIssues: false,
            showResume: false,
            showProgress: false,
            showSuccess: false,
            tree: [],
            uploadStatus: 'not-started',
            warnings: []
        };
        for (let prop in diffs) {data[prop] = diffs[prop];}
        this.update(data, callback);
    },

// actions ---------------------------------------------------------------------------

    /**
     * Toggle Modal
     */
    toggleModal () {
        if (!bowser.chrome) {
            let chromeMessage = (
                <span>This is a Google Chrome only feature. <a href="http://www.google.com/chrome/">Please consider using Chrome as your browser</a>.</span>
            );
            notifications.createAlert({
                type: 'Error',
                message: chromeMessage
            });
        }else{
            if (this.data.uploadStatus === 'uploading') {
                this.update({showModal: !this.data.showModal});
            } else {
                this.setInitialState({showModal: !this.data.showModal});
            }
        }
    },

    /**
     * On Change
     *
     * On file select this adds files to the state
     * and starts validation.
     */
    onChange (selectedFiles) {
        let dirName = selectedFiles.tree[0].name,
            nameError = null;
        if (dirName.length > 32) {
            nameError = 'Names must be 32 characters or less';
        }
        this.setInitialState({
            refs: this.data.refs,
            tree: selectedFiles.tree,
            list: selectedFiles.list,
            dirName: dirName,
            nameError: nameError,
            uploadStatus: 'files-selected',
            showModal: true,
            showRename: true,
            activeKey: 2
        });
    },

    /**
     * On Resume
     *
     * A file select on change handler for resuming
     * incomplete uploads.
     */
    onResume (selectedFiles, originalName) {
        let dirName = selectedFiles.tree[0].name,
            renameEnabled = true,
            activeKey, callback;
        if (dirName !== originalName) {
            activeKey = 2;
        } else {
            activeKey = 3;
            renameEnabled = false;
            callback = () => {this.validate(selectedFiles.list);};
        }
        this.setInitialState({
            refs: this.data.refs,
            tree: selectedFiles.tree,
            list: selectedFiles.list,
            dirName: originalName,
            uploadStatus: 'files-selected',
            showRename: true,
            showModal: true,<commit_msg>Fixed issue with validated callback cancelling 'uploading' status due to race conditions<commit_after>// dependencies ----------------------------------------------------------------------

import React           from 'react';
import Reflux          from 'reflux';
import Actions         from './upload.actions.js';
import notifications   from '../notification/notification.actions.js';
import scitran         from '../utils/scitran';
import upload          from './upload';
import files           from '../utils/files';
import validate        from 'bids-validator';
import userStore       from '../user/user.store';
import datasetsActions from '../dashboard/datasets.actions';
import datasetActions  from '../dataset/dataset.actions';
import favico          from 'favico.js';
import bowser          from 'bowser';

let favicon = new favico();

// store setup -----------------------------------------------------------------------

let UploadStore = Reflux.createStore({

    listenables: Actions,

    init: function () {
        // Reset Favico incase timeout or issues
        favicon.reset();
        this.setInitialState();
    },

    getInitialState: function () {
        return this.data;
    },

// state data ------------------------------------------------------------------------

    data: {},

    update: function (data, callback) {
        for (let prop in data) {this.data[prop] = data[prop];}
        this.trigger(this.data, callback);
    },

    /**
     * Set Initial State
     *
     * Sets the state to the data object defined
     * inside the function. Also takes a diffs object
     * which will set the state to the initial state
     * with any differences passed.
     */
    setInitialState: function (diffs, callback) {
        let data = {
            activeKey: 1,
            changeName: false,
            dirName: '',
            disabledTab: false,
            errors: [],
            list: {},
            nameError: null,
            progress: {total: 0, completed: 0, currentFiles: []},
            projectId: '',
            refs: {},
            resuming: false,
            selectedName: '',
            showModal: false,
            showSelect: true,
            showRename: false,
            renameEnabled: true,
            showRenameInput: true,
            showIssues: false,
            showResume: false,
            showProgress: false,
            showSuccess: false,
            tree: [],
            uploadStatus: 'not-started',
            warnings: []
        };
        for (let prop in diffs) {data[prop] = diffs[prop];}
        this.update(data, callback);
    },

// actions ---------------------------------------------------------------------------

    /**
     * Toggle Modal
     */
    toggleModal () {
        if (!bowser.chrome) {
            let chromeMessage = (
                <span>This is a Google Chrome only feature. <a href="http://www.google.com/chrome/">Please consider using Chrome as your browser</a>.</span>
            );
            notifications.createAlert({
                type: 'Error',
                message: chromeMessage
            });
        }else{
            if (this.data.uploadStatus === 'uploading') {
                this.update({showModal: !this.data.showModal});
            } else {
                this.setInitialState({showModal: !this.data.showModal});
            }
        }
    },

    /**
     * On Change
     *
     * On file select this adds files to the state
     * and starts validation.
     */
    onChange (selectedFiles) {
        let dirName = selectedFiles.tree[0].name,
            nameError = null;
        if (dirName.length > 32) {
            nameError = 'Names must be 32 characters or less';
        }
        this.setInitialState({
            refs: this.data.refs,
            tree: selectedFiles.tree,
            list: selectedFiles.list,
            dirName: dirName,
            nameError: nameError,
            uploadStatus: 'files-selected',
            showModal: true,
            showRename: true,
            activeKey: 2
        });
    },

    /**
     * On Resume
     *
     * A file select on change handler for resuming
     * incomplete uploads.
     */
    onResume (selectedFiles, originalName) {
        let dirName = selectedFiles.tree[0].name,
            renameEnabled = true,
            activeKey, callback;
        if (dirName !== originalName) {
            activeKey = 2;
        } else {
            activeKey = 3;
            renameEnabled = false;
            callback = () => {
                if (this.data.uploadStatus == 'files-selected') {
                    this.validate(selectedFiles.list);
                }
            };
        }
        this.setInitialState({
            refs: this.data.refs,
            tree: selectedFiles.tree,
            list: selectedFiles.list,
            dirName: originalName,
            uploadStatus: 'files-selected',
            showRename: true,
            showModal: true,
{'fraction_non_alphanumeric': 0.16048626008785372, 'fraction_numerical': 0.002451731535396874, 'mean_word_length': 1.383735086437789, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1192990', 'n_tokens_mistral': 2461, 'n_tokens_neox': 2382, 'n_words': 659}