<commit_before>import * as ReactDOM from "react-dom";
import * as React from "react";

import { ComponentsRefs } from "./../../components-refs";
import { CustomComponent } from "./../custom-component";
import { Http } from "./../../util/http";
import { FeedParser } from "./../../util/feed-parser";
import { FeedStorage, StoredFeed } from "./../../storage";

export class Feed extends CustomComponent<FeedProp, FeedState>{

    constructor(props: FeedProp) {
        super();

        this.props = props;

        this.state = {
            articles: this.props.articles,
            selected: false
        };

        this.handleSelect = this.handleSelect.bind(this);
    }

    fetch() {
        return new Promise((resolve, reject) => {
            Http.get(this.props.link).then(xmlContent => {
                this.mergeArticles(FeedParser.parse(xmlContent));
                FeedStorage.store();
                resolve();
            }).catch(reject);
        });
    }

    render() {
        const unreadNb = this.state.articles.filter(article => {
            return !article.read;
        }).length;

        return (
            <li className={this.state.selected && "selected"} onClick={this.handleSelect} >
                <i className="fa fa-rss" aria-hidden="true"></i>
                <span className="title">{this.props.title}</span>
                <span className="notif" style={{ display: !unreadNb && "none" }}>{unreadNb}</span>
            </li>
        );
    }

    handleSelect(event: React.MouseEvent<HTMLLIElement>) {
        if (!this.state.selected) {
            ComponentsRefs.feedList.feedComponents.forEach(feedComponent => { feedComponent.editState({ selected: false }); });
            this.editState({ selected: true });

            ComponentsRefs.feedList.selectedFeed = this;

            ComponentsRefs.articleList.updateArticles(this.state.articles);

            ComponentsRefs.articleList.resetScrollbar();
        }
    }


    getStoreValue(): StoredFeed {
        return {
            uuid: this.props.uuid,
            title: this.props.title,
            link: this.props.link,
            articles: this.state.articles
        };
    }

    mergeArticles(newArticles: IArticle[]) {
        const newArticlesList = this.state.articles.slice(0);
        for (let i = 0; i < newArticles.length; i++) {
            if (this.getArticleByID(newArticles[i].id)) continue;

            newArticles[i].read = false;
            newArticlesList[newArticlesList.length] = newArticles[i];
        }

        newArticlesList.sort((articleA, articleB) => {
            return articleA.date > articleB.date ? -1 : 1;
        });

        this.editState({ articles: newArticlesList });
        
        ComponentsRefs.articleList.updateArticles(newArticlesList);
    }

    getArticleByID(id: string) {
        return this.state.articles.find(article => {
            return article.id == id;
        });
    }
}

export interface FeedProp {
    uuid: string;
    title: string;
    link: string;
    articles: IArticle[];
}<commit_msg>Remove trailing whitespace<commit_after>import * as ReactDOM from "react-dom";
import * as React from "react";

import { ComponentsRefs } from "./../../components-refs";
import { CustomComponent } from "./../custom-component";
import { Http } from "./../../util/http";
import { FeedParser } from "./../../util/feed-parser";
import { FeedStorage, StoredFeed } from "./../../storage";

export class Feed extends CustomComponent<FeedProp, FeedState>{

    constructor(props: FeedProp) {
        super();

        this.props = props;

        this.state = {
            articles: this.props.articles,
            selected: false
        };

        this.handleSelect = this.handleSelect.bind(this);
    }

    fetch() {
        return new Promise((resolve, reject) => {
            Http.get(this.props.link).then(xmlContent => {
                this.mergeArticles(FeedParser.parse(xmlContent));
                FeedStorage.store();
                resolve();
            }).catch(reject);
        });
    }

    render() {
        const unreadNb = this.state.articles.filter(article => {
            return !article.read;
        }).length;

        return (
            <li className={this.state.selected && "selected"} onClick={this.handleSelect} >
                <i className="fa fa-rss" aria-hidden="true"></i>
                <span className="title">{this.props.title}</span>
                <span className="notif" style={{ display: !unreadNb && "none" }}>{unreadNb}</span>
            </li>
        );
    }

    handleSelect(event: React.MouseEvent<HTMLLIElement>) {
        if (!this.state.selected) {
            ComponentsRefs.feedList.feedComponents.forEach(feedComponent => { feedComponent.editState({ selected: false }); });
            this.editState({ selected: true });

            ComponentsRefs.feedList.selectedFeed = this;

            ComponentsRefs.articleList.updateArticles(this.state.articles);

            ComponentsRefs.articleList.resetScrollbar();
        }
    }


    getStoreValue(): StoredFeed {
        return {
            uuid: this.props.uuid,
            title: this.props.title,
            link: this.props.link,
            articles: this.state.articles
        };
    }

    mergeArticles(newArticles: IArticle[]) {
        const newArticlesList = this.state.articles.slice(0);
        for (let i = 0; i < newArticles.length; i++) {
            if (this.getArticleByID(newArticles[i].id)) continue;

            newArticles[i].read = false;
            newArticlesList[newArticlesList.length] = newArticles[i];
        }

        newArticlesList.sort((articleA, articleB) => {
            return articleA.date > articleB.date ? -1 : 1;
        });

        this.editState({ articles: newArticlesList });

        ComponentsRefs.articleList.updateArticles(newArticlesList);
    }

    getArticleByID(id: string) {
        return this.state.articles.find(article => {
            return article.id == id;
        });
    }
}

export interface FeedProp {
    uuid: string;
    title: string;
    link: string;
    articles: IArticle[];
}
{'fraction_non_alphanumeric': 0.13925492109972346, 'fraction_numerical': 0.001301447860745079, 'mean_word_length': 2.1066195048004044, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, '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': '5917903', 'n_tokens_mistral': 1777, 'n_tokens_neox': 1682, 'n_words': 320}