<commit_before>import * as _ from "lodash";
import * as React from "react";
import {connect} from "react-redux";
const fuzzy = require("fuzzy");
const latinize = require("latinize");
const TreeView = require("react-treeview");

function ItemLabelView(
    {label, tracks, on_text_click = null, dispatch}:
    {label: string, tracks: ITrack[], dispatch: any, on_text_click: any}
) {
    return <span>
        <span onClick={on_text_click}>{label}</span>
        <span
            style={{backgroundColor: "black", color: "white", marginLeft: "1em"}}
            onClick={() => dispatch({type: "add_to_playlist", tracks: tracks})}
        >
            +
        </span>
    </span>;
}
const ItemLabel = connect(
    null,
    {dispatch: action => action}
)(ItemLabelView) as React.ComponentClass<{
    label: string, tracks: ITrack[], on_text_click?: any
}>;

function LibraryTrack({track, onClick}) {
    const label =
        <ItemLabel
            label={track.title}
            tracks={[track]}
            on_text_click={() => onClick(track)}
        />
    return <div key={track.title}>
        {label}
    </div>;
}

const LibraryTrackContainer = connect(
    null,
    {
        onClick: (track) => ({type: "play_track", track})
    }
)(LibraryTrack) as React.ComponentClass<{track: ITrack}>;

function LibraryAlbum({album, tracks}) {
    const label = <ItemLabel label={album} tracks={tracks} />
    return <TreeView key={album} nodeLabel={label} defaultCollapsed={true}>
        {_.map(tracks, (track:ITrack, album_name) =>
            <LibraryTrackContainer key={`${album}.${track.title}`} track={track} />
        )}
    </TreeView>
}

function LibraryArtist({artist, tracks}) {
    const by_album = _.groupBy<ITrack, string>(tracks, "album");
    const label = <ItemLabel label={artist} tracks={tracks} />

    return <TreeView key={artist} nodeLabel={label} defaultCollapsed={true}>
        {_.map(by_album, (tracks, album) =>
            <LibraryAlbum key={`${artist}.${album}`} album={album} tracks={tracks} />
        )}
    </TreeView>
}

const fuzzy_filter = (library, filter) =>
    fuzzy.filter(
        latinize(filter),
        library,
        {extract: track => latinize(`${track.title} - ${track.artist} - ${track.album}`)}
    ).map(result => result.original);

const filter_dispatch = _.debounce((filter_string, dispatch) =>
    dispatch({type: "library_filter", filter: filter_string}),
    250);

function Library({library, filter, dispatch}) {
    const filtered = fuzzy_filter(library, filter);
    const by_artist = _.groupBy<ITrack, string>(filtered, "artist");

    return <div>
        <input onChange={<commit_msg>Lazy library rendering. Use local fork of react-treeview for that.<commit_after>import * as _ from "lodash";
import * as React from "react";
import {connect} from "react-redux";
const fuzzy = require("fuzzy");
const latinize = require("latinize");
//const TreeView = require("react-treeview");
const TreeView = require("../../cloned/react-treeview/build/react-treeview");

function ItemLabelView(
    {label, tracks, on_text_click = null, dispatch}:
    {label: string, tracks: ITrack[], dispatch: any, on_text_click: any}
) {
    return <span>
        <span onClick={on_text_click}>{label}</span>
        <span
            style={{backgroundColor: "black", color: "white", marginLeft: "1em"}}
            onClick={() => dispatch({type: "add_to_playlist", tracks: tracks})}
        >
            +
        </span>
    </span>;
}
const ItemLabel = connect(
    null,
    {dispatch: action => action}
)(ItemLabelView) as React.ComponentClass<{
    label: string, tracks: ITrack[], on_text_click?: any
}>;

function LibraryTrack({track, onClick}) {
    const label =
        <ItemLabel
            label={track.title}
            tracks={[track]}
            on_text_click={() => onClick(track)}
        />
    return <div key={track.title}>
        {label}
    </div>;
}

const LibraryTrackContainer = connect(
    null,
    {
        onClick: (track) => ({type: "play_track", track})
    }
)(LibraryTrack) as React.ComponentClass<{track: ITrack}>;

function LibraryAlbum({album, tracks}) {
    const label = <ItemLabel label={album} tracks={tracks} />
    return <TreeView key={album} lazy={true} nodeLabel={label} defaultCollapsed={true}>
        {_.map(tracks, (track:ITrack, album_name) =>
            <LibraryTrackContainer key={`${album}.${track.title}`} track={track} />
        )}
    </TreeView>
}

function LibraryArtist({artist, tracks}) {
    const by_album = _.groupBy<ITrack, string>(tracks, "album");
    const label = <ItemLabel label={artist} tracks={tracks} />

    return <TreeView key={artist} lazy={true} nodeLabel={label} defaultCollapsed={true}>
        {_.map(by_album, (tracks, album) =>
            <LibraryAlbum key={`${artist}.${album}`} album={album} tracks={tracks} />
        )}
    </TreeView>
}

const fuzzy_filter = (library, filter) =>
    fuzzy.filter(
        latinize(filter),
        library,
        {extract: track => latinize(`${track.title} - ${track.artist} - ${track.album}`)}
    ).map(result => result.original);

const filter_dispatch = _.debounce((filter_string, dispatch) =>
    dispatch({type: "library_filter", filter: filter_string}),
    250);

function Library({library, filter, dispatch}) {
    const filtered = fuzzy_filter(library, filter);
    const by_artist = _.groupBy<ITrack, string>(filtered, "artist");

    return <div>
        <input onChange={
{'fraction_non_alphanumeric': 0.1637062809009339, 'fraction_numerical': 0.0014649331624244644, 'mean_word_length': 3.362619808306709, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 67, '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': '1251597', 'n_tokens_mistral': 1693, 'n_tokens_neox': 1658, 'n_words': 383}