Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
articles.js 6.02 KiB
Newer Older
peter_rabbit's avatar
peter_rabbit committed
"use strict";

const { articles_url } = require("../../constants");
const { fetchjson, fetchtext } = require("../lib/fetch");
const objectHtmlRenderer = require("../lib/object-html-renderer");
const ImageCarousel = require("./image-carousel");

class Articles {
    constructor() {
        this.id = performance.now().toString();
        this.state = {
            loading: true,
            articles: [],
            showArticleIndex: -1,
        };
        this.loadArticles();
    }

    loadArticles() {
        fetchjson(`${articles_url}/index.json`)
            .then(json => {
                Promise.all(
                    json.map(async articlePath => {
                        const art = await fetchjson(`${articles_url}/${articlePath}`);
                        const tmpSplit = articlePath.split("/");
                        tmpSplit.pop();
                        const absArtPath = `${articles_url}/${tmpSplit.join("/")}`;
                        return Object.assign(art, { path: absArtPath });
                    })
                )
                    .then(articles => this.setArticles(articles))
                    .catch(e => console.log(e));
            })
            .catch(e => console.log(e));
    }

    async setArticles(articles) {
        for (const article of articles) {
            if (article.content_text.indexOf("<file>") !== -1) {
                const txtPath = article.content_text.replace("<file>", "");
                const txtValue = await fetchtext(`${article.path}/${txtPath}`);
                article.content_text = txtValue;
            }
            article.date = new Date(article.date);
        }
        this.state.articles = articles.sort((a, b) => a.date - b.date);
        this.state.showArticleIndex = this.state.articles.length - 1;
        this.refresh();
    }

    refresh() {
        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
            mode: "replace",
        });
    }

    getArticleDate(date) {
        return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
    }

    getArticleBody(text) {
        return text
            .split(" ")
            .map(word => {
                if (word.includes("http://") || word.includes("https://")) {
                    const splitword = word.split("||");
                    const href = splitword[0];
                    const text = splitword.length > 1 ? splitword[1] : href;
                    return `<a href=${href} target="_blank">${text}</a>`;
                } else return word;
            })
            .join(" ")
            .replaceAll("\n", "<br/>");
    }

    renderArticle(articleData) {
        return {
            tag: "article",
            contents: [
                {
                    tag: "div",
                    class: "date",
                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
                },
                {
                    tag: "div",
                    class: "title",
                    contents: [
                        {
                            tag: "h3",
                            contents: articleData.title,
                        },
                    ],
                },
                {
                    tag: "div",
                    class: "subtitle",
                    contents: [
                        {
                            tag: "strong",
                            contents: articleData.subtitle,
                        },
                    ],
                },
                {
                    tag: "div",
                    class: "body",
                    contents: [
                        {
                            tag: "p",
                            contents: this.getArticleBody(articleData.content_text),
                        },
                    ],
                },
                new ImageCarousel({
                    images: articleData.images.map(img => `${articleData.path}/images/${img}`),
                }).render(),
            ],
        };
    }

    renderArticlePlaceholder() {
        return {
            tag: "article",
            class: "article-placeholder page-contents-center",
            contents: [
                { tag: "div", class: "date" },
                { tag: "div", class: "title" },
                { tag: "div", class: "subtitle" },
                { tag: "div", class: "body" },
                { tag: "div", class: "image" },
            ],
        };
    }

    handleChangeArticle(dir) {
        let { showArticleIndex, articles } = this.state;
        showArticleIndex =
            dir === "prev"
                ? showArticleIndex - 1 >= 0
                    ? showArticleIndex - 1
                    : 0
                : showArticleIndex + 1 <= articles.length - 1
                ? showArticleIndex + 1
                : articles.length - 1;
        this.state.showArticleIndex = showArticleIndex;
        this.refresh();
    }

    render() {
        const { articles, showArticleIndex } = this.state,
            showNext = showArticleIndex < articles.length - 1,
            showPrev = showArticleIndex > 0;
        return {
            tag: "div",
            id: this.id,
            class: "articles-displayer page-contents-center",
            contents:
                articles.length > 0
                    ? [
                          {
                              tag: "button",
                              class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
                              onclick: this.handleChangeArticle.bind(this, "prev"),
                          },
                          this.renderArticle(articles[showArticleIndex]),
                          {
                              tag: "button",
                              class: `next-btn ${!showNext ? "disabled" : "active"}`,
                              onclick: this.handleChangeArticle.bind(this, "next"),
                          },
                      ]
                    : [this.renderArticlePlaceholder()],
        };
    }
}

module.exports = Articles;