<commit_before>import {h, Component}					from 'preact/preact';
import ContentList						from 'com/content-list/list';
import ContentLoading					from 'com/content-loading/loading';
import InputDropdown					from 'com/input-dropdown/dropdown';

import GradedItem						from './mygrades-graded-item';
import GradeGraphs						from './mygrades-grade-graphs';

import $Grade							from 'shrub/js/grade/grade';
import $Node							from 'shrub/js/node/node';
import $Comment							from 'shrub/js/comment/comment';

const SORT_ORDER = 0;
const SORT_ALPHA = 1;
const SORT_TYPE = 2;
const SORT_GRADE_AVERAGE = 3; //The value should be the highest of the permanent sortings!

const pad = ( number, digits ) => {
	return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
};

export default class MyGrades extends Component {
	constructor( props ) {
		super(props);
		this.state = {
			'loading': true,
		};
		this.onSortByChange = this.onSortByChange.bind(this);
	}

	componentDidMount() {
		const eventId = this.props.node.id;
		$Grade.GetAllMy(eventId)
			.then(r => {
				this.setState({'grades': r.grade});
			});
		$Grade.GetMyList(this.props.node.id)
			.then(r => {
				this.setState({
					'gameIds': r.items,
					'nodes': new Map(),
					'loading': true,
					'error': null});
				this.collectNodes(r.items, eventId);
			})
			.catch(r => {
				this.setState({'error': r, 'gameIds': null, 'loading': false});
			});
		$Comment.GetMyListByParentNode(eventId).then(r => (this.collectComments(r.comment)));
	}

	collectComments( commentIds ) {
		const chunkSize = 200;
		let chunkStart = 0;
		const promises = [];
		const nodesWithMyComments = new Map();
		while ( true ) {
			const chunk = commentIds.slice(chunkStart, chunkSize);
			if ( chunk.length == 0 ) {
				break;
			}
			promises.push($Comment.Get(chunk).then(r => {
				r.comment.forEach(comment => {
					if (nodesWithMyComments[comment.node]) {
						nodesWithMyComments[comment.node] += 1;
					}
					else {
						nodesWithMyComments[comment.node] = 1;
					}
				});
			}));
			chunkStart += chunkSize;
		}
		return Promise.all(promises).then(r => {
			this.setState({'myComments': nodesWithMyComments});
		});
	}

	collectNodes( gameIds, eventId ) {
		const promises = [];
		let nodeMapping = new Map();
		let gradeMapping = new Map();
		const chunkSize = 20;
		let i = 0;
		promises.push($Node.Get(eventId).then(r => {
			const {meta} = r.node[0];
			let gradeIndex = 1;
			while ( true ) {
				const gradeKey = 'grade-' + pad(gradeIndex, 2);
				const gradeName = meta[gradeKey];
				if ( gradeName ) {
					gradeMapping[gradeKey] = gradeName;
					gradeIndex += 1;
				}
				else {
					break;
				}
			}
		}));
		while ( true ) {
			const chunk = gameIds.slice(i, i + chunkSize);
			if ( chunk.length == 0 ) {
				break;
			}
			promises.push($Node.Get(chunk)
				.then(r => {
					r.node.map(node => {
						nodeMapping[node.id] = node;
					});
				})
				.catch(r => {
					this.setState({'error': r});
				})
			);
			i += chunkSize;
		}
		return Promise.all(promises)
			.then(r => {
				this.setState({'loading': false, 'nodes': nodeMapping, 'gradeNames': gradeMapping});
				return this.collectAuthors(nodeMapping, gameIds);
			});
	}

	collectAuthors( mapping, gameIds ) {
		let authors = [];
		const authorsMapping = new Map();
		let promises = [];
		const chunkSize = 20;
		for ( let i = 0; i < gameIds.length; i+=1 ) {<commit_msg>Better promises and loading flag<commit_after>import {h, Component}					from 'preact/preact';
import ContentList						from 'com/content-list/list';
import ContentLoading					from 'com/content-loading/loading';
import InputDropdown					from 'com/input-dropdown/dropdown';

import GradedItem						from './mygrades-graded-item';
import GradeGraphs						from './mygrades-grade-graphs';

import $Grade							from 'shrub/js/grade/grade';
import $Node							from 'shrub/js/node/node';
import $Comment							from 'shrub/js/comment/comment';

const SORT_ORDER = 0;
const SORT_ALPHA = 1;
const SORT_TYPE = 2;
const SORT_GRADE_AVERAGE = 3; //The value should be the highest of the permanent sortings!

const pad = ( number, digits ) => {
	return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
};

export default class MyGrades extends Component {
	constructor( props ) {
		super(props);
		this.state = {
			'loading': true,
		};
		this.onSortByChange = this.onSortByChange.bind(this);
	}

	componentDidMount() {
		const eventId = this.props.node.id;
		const promiseAllMy = $Grade.GetAllMy(eventId)
			.then(r => {
				this.setState({'grades': r.grade});
			});
		const promiseMyList = $Grade.GetMyList(this.props.node.id)
			.then(r => {
				this.setState({
					'gameIds': r.items,
					'nodes': new Map(),
					'error': null});
				return this.collectNodes(r.items, eventId);
			})
			.catch(r => {
				this.setState({'error': r, 'gameIds': null});
			});
		const promiseComments = $Comment.GetMyListByParentNode(eventId).then(r => (this.collectComments(r.comment)));
		Promise.all([promiseAllMy, promiseMyList, promiseComments]).then(() => {
			this.setState({'loading': false});
		});
	}

	collectComments( commentIds ) {
		const chunkSize = 200;
		let chunkStart = 0;
		const promises = [];
		const nodesWithMyComments = new Map();
		while ( true ) {
			const chunk = commentIds.slice(chunkStart, chunkSize);
			if ( chunk.length == 0 ) {
				break;
			}
			promises.push($Comment.Get(chunk).then(r => {
				r.comment.forEach(comment => {
					if (nodesWithMyComments[comment.node]) {
						nodesWithMyComments[comment.node] += 1;
					}
					else {
						nodesWithMyComments[comment.node] = 1;
					}
				});
			}));
			chunkStart += chunkSize;
		}
		return Promise.all(promises).then(r => {
			this.setState({'myComments': nodesWithMyComments});
		});
	}

	collectNodes( gameIds, eventId ) {
		const promises = [];
		let nodeMapping = new Map();
		let gradeMapping = new Map();
		const chunkSize = 20;
		let i = 0;
		promises.push($Node.Get(eventId).then(r => {
			const {meta} = r.node[0];
			let gradeIndex = 1;
			while ( true ) {
				const gradeKey = 'grade-' + pad(gradeIndex, 2);
				const gradeName = meta[gradeKey];
				if ( gradeName ) {
					gradeMapping[gradeKey] = gradeName;
					gradeIndex += 1;
				}
				else {
					break;
				}
			}
		}));
		while ( true ) {
			const chunk = gameIds.slice(i, i + chunkSize);
			if ( chunk.length == 0 ) {
				break;
			}
			promises.push($Node.Get(chunk)
				.then(r => {
					r.node.map(node => {
						nodeMapping[node.id] = node;
					});
				})
				.catch(r => {
					this.setState({'error': r});
				})
			);
			i += chunkSize;
		}
		return Promise.all(promises)
			.then(r => {
				this.setState({'nodes': nodeMapping, 'gradeNames': gradeMapping});
				return this.collectAuthors(nodeMapping, gameIds);
			});
	}

	collectAuthors( mapping, gameIds ) {
		let authors = [];
		const authorsMapping = new Map();
		let promises = [];
		const chunkSize = 20;
		for ( let i = 0; i < gameIds.length; i+=1 ) {
{'fraction_non_alphanumeric': 0.15776699029126215, 'fraction_numerical': 0.0074243289548829245, 'mean_word_length': 3.06794425087108, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 30, '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': '6874358', 'n_tokens_mistral': 2954, 'n_tokens_neox': 2381, 'n_words': 512}