<commit_before>import { h, Component } from 'preact';
import { connect } from 'preact-redux';

import Container from './../Container';
import Button from './elements/Button';

import { setWindowAction, WINDOW_ACTION_BROWSE } from './../../actions/window';
import { commandDeleteFiles } from './../../actions/commands';

const BUTTON_DELETE = 'DELETE';
const BUTTON_CLOSE = 'CLOSE';
const BUTTONS = [ BUTTON_DELETE, BUTTON_CLOSE ];

class DeleteDialog extends Component {
    constructor(props) {
        super(props);

        this.state = {
            activeButtonIdx: 0,
            activeButton: BUTTON_DELETE
        };
    }

    componentDidMount() {
        document.getElementsByClassName('dialog')[0].focus();
    }

    closeDialog() {
        this.props.dispatch( setWindowAction( WINDOW_ACTION_BROWSE ));        
    }

    deleteFiles() {
        // TODO: add support for selected files/records
        this.props.dispatch(
            commandDeleteFiles(this.props.activePath, [this.props.activeRecord])
        );

        this.closeDialog();
    }

    processKey(e) {
        const code = e.code;
        if (code === 'Tab') {
            let activeButtonIdx = this.state.activeButtonIdx;
            
            activeButtonIdx += 1;
            activeButtonIdx = activeButtonIdx < BUTTONS.length ? activeButtonIdx : 0;
            
            const newState = {
                activeButtonIdx,
                activeButton: BUTTONS[activeButtonIdx]
            };

            this.setState(
                Object.assign({}, this.state, newState)
            );
            e.preventDefault();
        } else if (code === 'Enter') {
            this.processEnterKey();
            e.stopPropagation();
        }
    }

    processEnterKey() {
        const activeButton = this.state.activeButton;

        switch(activeButton) {
            case BUTTON_DELETE:
                this.deleteFiles();
                break;
            default:
                this.closeDialog();
        }
    }    

    render() {
        const activeButton = this.state.activeButton;
        return (
            <Container className="dialog" hasFocus="1" onKeyDown={ (e) => this.processKey(e) }>
                <Container className="title">Delete file(s)</Container>
                <Container className="content">
                    <p style={{ flex: 1, textAlign: 'center', color: 'yellow', fontWeight: 'bold' }}>{ this.props.activeRecord }</p>
                </Container>
                <Container className="buttons">

                    <Button
                        isSelected={ activeButton === BUTTON_CLOSE } 
                        onClick={ () => { this.closeDialog() } }
                    >{ BUTTON_CLOSE }</Button>

                    <Button 
                        isSelected={ activeButton === BUTTON_DELETE } 
                        onClick={ () => { this.deleteFiles() }}
                    >{ BUTTON_DELETE }</Button>

                </Container>
            </Container>
        );
    }
}

export default connect(
    (state) => ({
        activePath: state.get('data').getIn(
            ['panels', state.get('data').get('activePanel'), 'activePath']
        ),
        activeRecord: state.get('data').getIn(
            ['panels', state.get('data').get('activePanel'), 'activeRecord']
        ),
    })
)(DeleteDialog);<commit_msg>Updated delete dialog.<commit_after>import { h, Component } from 'preact';
import { connect } from 'preact-redux';

import fs from 'fs-extra';

import Container from './../Container';
import Button from './elements/Button';

import { setWindowAction, WINDOW_ACTION_BROWSE } from './../../actions/window';
import { panelLoadContent, panelSetActiveRecord } from './../../actions/panels';

const BUTTON_DELETE = 'DELETE';
const BUTTON_CLOSE = 'CLOSE';
const BUTTONS = [ BUTTON_DELETE, BUTTON_CLOSE ];

class DeleteDialog extends Component {
    constructor(props) {
        super(props);

        this.state = {
            activeButtonIdx: 0,
            activeButton: BUTTON_DELETE,

            collectingRecords: true,
            processingRecord: undefined,
            filesToDelete: 0,
            directoriesToDelete: 0
        };
    }

    componentDidMount() {
        document.getElementsByClassName('dialog')[0].focus();

        this.collectFiles([ this.props.activePath + '/' + this.props.activeRecord ]);
    }

    closeDialog() {
        this.props.dispatch( setWindowAction( WINDOW_ACTION_BROWSE ));        
    }

    deleteFiles() {
        // TODO: add support for selected files/records
        // this.props.dispatch(
        //     commandDeleteFiles(this.props.activePath, [this.props.activeRecord])
        // );

        //this.collectFiles([ this.props.activePath + '/' + this.props.activeRecord ]);

        this.closeDialog();
    }

    processKey(e) {
        const code = e.code;
        if (code === 'Tab') {
            let activeButtonIdx = this.state.activeButtonIdx;
            
            activeButtonIdx += 1;
            activeButtonIdx = activeButtonIdx < BUTTONS.length ? activeButtonIdx : 0;
            
            const newState = {
                activeButtonIdx,
                activeButton: BUTTONS[activeButtonIdx]
            };

            this.setState(
                Object.assign({}, this.state, newState)
            );
            e.preventDefault();
        } else if (code === 'Enter') {
            this.processEnterKey();
            e.stopPropagation();
        }
    }

    processEnterKey() {
        const activeButton = this.state.activeButton;

        switch(activeButton) {
            case BUTTON_DELETE:
                this.deleteFiles();
                break;
            default:
                this.closeDialog();
        }
    }

    collectFiles(recordsToDelete) {
        let records = [];
        let countFiles = 0;
        let countDirs = 0;

        // todo: delete all selected files
        fs.walk(recordsToDelete[0])
        .on('data', (item) => {            
            if(item.path.endsWith('..')) return;

            const isDir = item.stats.isDirectory();
            countFiles += isDir ? 0 : 1;
            countDirs += isDir ? 1 : 0;
            
            records.push({
                path: item.path, isDir
            });

            this.setState(
                Object.assign({}, this.state, {
                    processingRecord: item.path,
                    filesToDelete: countFiles,
                    directoriesToDelete: countDirs
                })
            );          
        })
        .on('end', (files) => {
            
            // delete all files first
            for(let record of records.reverse()) {
                if (!record.isDir) {
                    fs.removeSync(record.path);
                }
            }

            // todo: remove all directories
            // fs.removeSync(record.path);

            this.props.dispatch(
                panelLoadContent(this.props.side, this.props.activePath)
            );
            // this.props.dispatch(
            //     panelSetActiveRecord(this.props.side, this.textInput.value)
            // );            
        });
    }  

    render() {
        const activeButton = this.state.activeButton;
        return (
            <Container className="dialog" hasFocus="1" onKeyDown={ (e) => this.processKey(e) }>
                <Container className="title">Delete file(s)</Container>
                <Container className="content">
                    { this.state.collectingRecords ? <p>Do you want to delete { this.state.filesToDelete } files and { this.state.directoriesToDelete } directories ? </p> : null }
                </Container>
                <Container className="buttons">

                    <Button
                        isSelected={ activeButton === BUTTON_CLOSE } 
                        onClick={ () => { this.closeDialog() } }
                    >{ BUTTON_CLOSE }</Button>

                    <Button 
                        isSelected={ activeButton === BUTTON_DELETE } 
                        onClick={ () => { this.deleteFiles() }}
                    >{ BUTTON_DELETE }</Button>

                </Container>
            </Container>
        );
    }
}

export default connect(
    (state) => ({
        side: state.get('data').get('activePanel'),
        activePath: state.get('data').getIn(
            ['panels', state.get('data').get('activePanel'), 'activePath']
        ),
        activeRecord: state.get('data').getIn(
            ['panels', state.get('data').get('activePanel'), 'activeRecord']
        ),
    })
)(DeleteDialog);
{'fraction_non_alphanumeric': 0.12615526802218113, 'fraction_numerical': 0.0023105360443622922, 'mean_word_length': 1.6138285024154588, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '4611541', 'n_tokens_mistral': 2312, 'n_tokens_neox': 2210, 'n_words': 434}