<commit_before>import React, { useState, useEffect, useReducer } from 'react';
import { Quandl } from 'stockflux-core';
import Components from 'stockflux-components';

import SearchResult from './search-result';
import styles from './App.module.css';

const SEARCHING = 'searching';
const SUCCESS = 'success';
const ERROR = 'error';
const INITIALISE = 'initialise';

const SEARCH_TIMEOUT_INTERVAL = 250;

const initialSearchState = {
    isSearching: false,
    hasErrors: false,
};

const getMessage = (state, results) => {
    if (state.isSearching) {
        return 'Loading search results...';
    } else if (state.hasErrors) {
        return 'An error occurred while retrieving data. Please check your internet connection or wait for our data services to be re-established.';
    } else if (results && results.length === 0) {
        return 'No matches were found.'
    } else {
        return 'Use the search bar above to add new stocks / symbols.';
    }
};

const searchReducer = (state, { type, results }) => {
    switch (type) {
        case SEARCHING:
            return {
                ...state,
                hasErrors: false,
                isSearching: true,
            };
        case SUCCESS:
            return {
                ...state,
                isSearching: false,
                results
            };
        case ERROR:
            return {
                ...state,
                hasErrors: true,
                isSearching: false,
            };
        case INITIALISE:
            return initialSearchState;
        default:
            throw new Error();
    }
};

const App = () => {
    const [searchState, dispatch] = useReducer(searchReducer, initialSearchState);
    const [query, setQuery] = useState('');
    const [debouncedQuery, setDebouncedQuery] = useState(null);
    const { isSearching, results } = searchState;

    useEffect(() => {
        const quandlSearch = async () => {
            if (debouncedQuery) {
                dispatch({ type: SEARCHING });

                try {
                    const quandlResults = await Quandl.search(debouncedQuery);
                    dispatch({ type: SUCCESS, results: quandlResults });
                } catch {
                    dispatch({ type: ERROR });
                }
            } else {
                dispatch({ type: INITIALISE });
            }
        };
        quandlSearch();
    }, [debouncedQuery]);

    useEffect(() => {
        const handler = setTimeout(() => setDebouncedQuery(query), SEARCH_TIMEOUT_INTERVAL);
        return () => clearTimeout(handler);
    }, [query]);

    return (
        <>
            <Components.Titlebar />
            <input type="text" className={styles.input} onChange={event => setQuery(event.target.value)} placeholder="Enter stock name or symbol" />
            <div className={styles.containerList}>
                <Components.ScrollWrapperY contentChanged={Boolean(results)}>
                    {!isSearching && results && results.length ? 
                        results.map(result => (
                            <SearchResult
                                key={result.code}
                                code={result.code}
                                name={result.name}
                            />
                            )) : 
                        <div className={styles.message}>
                            {getMessage(searchState, results)}
                        </div>
                    }
                </Components.ScrollWrapperY>
            </div>
        </>
    );
};

export default App;
<commit_msg>Updated the scroll wrapper prop to take in changed data everytime the search fetches something<commit_after>import React, { useState, useEffect, useReducer } from 'react';
import { Quandl } from 'stockflux-core';
import Components from 'stockflux-components';

import SearchResult from './search-result';
import styles from './App.module.css';

const SEARCHING = 'searching';
const SUCCESS = 'success';
const ERROR = 'error';
const INITIALISE = 'initialise';

const SEARCH_TIMEOUT_INTERVAL = 250;

const initialSearchState = {
    isSearching: false,
    hasErrors: false,
};

const getMessage = (state, results) => {
    if (state.isSearching) {
        return 'Loading search results...';
    } else if (state.hasErrors) {
        return 'An error occurred while retrieving data. Please check your internet connection or wait for our data services to be re-established.';
    } else if (results && results.length === 0) {
        return 'No matches were found.'
    } else {
        return 'Use the search bar above to add new stocks / symbols.';
    }
};

const searchReducer = (state, { type, results }) => {
    switch (type) {
        case SEARCHING:
            return {
                ...state,
                hasErrors: false,
                isSearching: true,
            };
        case SUCCESS:
            return {
                ...state,
                isSearching: false,
                results
            };
        case ERROR:
            return {
                ...state,
                hasErrors: true,
                isSearching: false,
            };
        case INITIALISE:
            return initialSearchState;
        default:
            throw new Error();
    }
};

const App = () => {
    const [searchState, dispatch] = useReducer(searchReducer, initialSearchState);
    const [query, setQuery] = useState('');
    const [debouncedQuery, setDebouncedQuery] = useState(null);
    const { isSearching, results } = searchState;

    useEffect(() => {
        const quandlSearch = async () => {
            if (debouncedQuery) {
                dispatch({ type: SEARCHING });

                try {
                    const quandlResults = await Quandl.search(debouncedQuery);
                    dispatch({ type: SUCCESS, results: quandlResults });
                } catch {
                    dispatch({ type: ERROR });
                }
            } else {
                dispatch({ type: INITIALISE });
            }
        };
        quandlSearch();
    }, [debouncedQuery]);

    useEffect(() => {
        const handler = setTimeout(() => setDebouncedQuery(query), SEARCH_TIMEOUT_INTERVAL);
        return () => clearTimeout(handler);
    }, [query]);

    return (
        <>
            <Components.Titlebar />
            <input type="text" className={styles.input} onChange={event => setQuery(event.target.value)} placeholder="Enter stock name or symbol" />
            <div className={styles.containerList}>
                <Components.ScrollWrapperY contentChanged={results}>
                    {!isSearching && results && results.length ?
                        results.map(result => (
                            <SearchResult
                                key={result.code}
                                code={result.code}
                                name={result.name}
                            />
                            )) : 
                        <div className={styles.message}>
                            {getMessage(searchState, results)}
                        </div>
                    }
                </Components.ScrollWrapperY>
            </div>
        </>
    );
};

export default App;

{'fraction_non_alphanumeric': 0.10941999177293295, 'fraction_numerical': 0.0010969422734128616, 'mean_word_length': 1.5737473535638673, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 45, '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': '4597498', 'n_tokens_mistral': 1865, 'n_tokens_neox': 1771, 'n_words': 472}