-
peter_rabbit authoredpeter_rabbit authored
games.js 21.04 KiB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
const ENV = "dev";
let server_url;
switch (ENV) {
case "dev":
server_url = "http://localhost";
break;
case "prod":
server_url = "http://kuadrado-software.fr";
}
module.exports = { server_url, in_construction: true };
},{}],2:[function(require,module,exports){
const { server_url } = require("./config");
module.exports = {
images_url: `${server_url}/assets/images`,
news_articles_url: `${server_url}/news-articles`,
game_articles_url: `${server_url}/game-articles`,
software_articles_url: `${server_url}/software-articles`,
};
},{"./config":1}],3:[function(require,module,exports){
"use strict";
const objectHtmlRenderer = require("../lib/object-html-renderer");
class ImageCarousel {
constructor(props) {
this.props = props;
this.id = performance.now();
this.state = {
showImageIndex: 0,
};
this.RUN_INTERVAL = 5000;
this.run();
}
run() {
this.runningInterval = setInterval(() => {
let { showImageIndex } = this.state;
const { images } = this.props;
this.state.showImageIndex = showImageIndex < images.length - 1 ? ++showImageIndex : 0;
this.refreshImage();
}, this.RUN_INTERVAL);
}
setImageIndex(i) {
clearInterval(this.runningInterval);
this.state.showImageIndex = i;
this.refreshImage();
}
refreshImage() {
objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
mode: "replace",
});
}
render() {
const { showImageIndex } = this.state;
const { images } = this.props;
return {
tag: "div",
id: this.id,
class: "image-carousel",
contents: [
{ tag: "img", src: images[showImageIndex] },
images.length > 1 && {
tag: "div",
class: "carousel-bullets",
contents: images.map((_, i) => {
const active = showImageIndex === i;
return {
tag: "span",
class: `bullet ${active ? "active" : ""}`,
onclick: this.setImageIndex.bind(this, i),
};
}),
},
],
};
}
}
module.exports = ImageCarousel;
},{"../lib/object-html-renderer":6}],4:[function(require,module,exports){
"use strict";
const { fetchjson, fetchtext } = require("./fetch");
function getArticleBody(text) {
return text
.split(" ")
.map(word => {
if (word.includes("http://") || word.includes("https://")) {
const splitword = word.split("||");
const href = splitword[0].match(/http.+/);
const text = splitword.length > 1 ? splitword[1].replaceAll("_", " ") : href;
return word.replace(/http.*/, `<a href=${href} target="_blank">${text}</a>`);
} else return word;
})
.join(" ")
.replaceAll("\n", "<br/>");
}
function getArticleDate(date) {
return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
}
function loadArticles(dir_url) {
return new Promise((resolve, reject) => {
fetchjson(`${dir_url}/index.json`)
.then(json => {
Promise.all(
json.articles.map(async articlePath => {
const art = await fetchjson(`${dir_url}/${articlePath}`);
const tmpSplit = articlePath.split("/");
tmpSplit.pop();
const absArtPath = `${dir_url}/${tmpSplit.join("/")}`;
return Object.assign(art, { path: absArtPath });
})
)
.then(articles => {
populateArticles(articles)
.then(completeArticles => resolve(completeArticles))
.catch(e => reject(e));
})
.catch(e => reject(e));
})
.catch(e => console.log(e));
});
}
function populateArticles(articles) {
return new Promise((resolve, reject) => {
Promise.all(
articles.map(async article => {
if (article.body.indexOf("<file>") !== -1) {
const txtPath = article.body.replace("<file>", "");
const textValue = await fetchtext(`${article.path}/${txtPath}`);
article.body = textValue;
article.date = article.date ? new Date(article.date) : undefined;
}
return article;
})
)
.then(completeArticles => resolve(completeArticles.sort((a, b) => a.date - b.date)))
.catch(e => reject(e));
});
}
module.exports = {
loadArticles,
getArticleBody,
getArticleDate,
populateArticles,
};
},{"./fetch":5}],5:[function(require,module,exports){
"use strict";
function fetchjson(url) {
return new Promise((resolve, reject) => {
const headers = new Headers();
headers.append("Accept", "application/json");
fetch(url, { mode: "no-cors", headers })
.then(r => r.json())
.then(r => resolve(r))
.catch(e => reject(e));
});
}
function fetchtext(url) {
const headers = new Headers();
headers.append("Accept", "text/html");
return new Promise((resolve, reject) => {
fetch(url, { mode: "no-cors", headers })
.then(r => r.text())
.then(r => resolve(r))
.catch(e => reject(e));
});
}
module.exports = {
fetchjson,
fetchtext,
};
},{}],6:[function(require,module,exports){
"use strict";
module.exports = {
setRenderCycleRoot(renderCycleRoot) {
this.renderCycleRoot = renderCycleRoot;
},
objectToHtml: function objectToHtml(obj) {
const { tag } = obj;
const node = document.createElement(tag);
const excludeKeys = ["tag", "contents", "style_rules", "state"];
Object.keys(obj)
.filter(attr => !excludeKeys.includes(attr))
.forEach(attr => {
if (attr === "class") {
node.classList.add(...obj[attr].split(" ").filter(s => s !== ""));
} else {
node[attr] = obj[attr];
}
});
if (obj.contents && typeof obj.contents === "string") {
node.innerHTML = obj.contents;
} else {
obj.contents &&
obj.contents.length > 0 &&
obj.contents.forEach(el => {
switch (typeof el) {
case "string":
node.innerHTML = el;
break;
case "object":
node.appendChild(objectToHtml(el));
break;
}
});
}
if (obj.style_rules) {
Object.keys(obj.style_rules).forEach(rule => {
node.style[rule] = obj.style_rules[rule];
});
}
return node;
},
renderCycle: function () {
this.subRender(this.renderCycleRoot.render(), document.getElementsByTagName("main")[0], {
mode: "replace",
});
},
subRender(object, htmlNode, options = { mode: "append" }) {
const insert = this.objectToHtml(object);
switch (options.mode) {
case "append":
htmlNode.appendChild(insert);
break;
case "override":
htmlNode.innerHTML = "";
htmlNode.appendChild(insert);
break;
case "insert-before":
htmlNode.insertBefore(insert, htmlNode.childNodes[options.insertIndex]);
break;
case "adjacent":
/**
* options.insertLocation must be one of:
*
* afterbegin
* afterend
* beforebegin
* beforeend
*/
htmlNode.insertAdjacentHTML(options.insertLocation, insert);
break;
case "replace":
htmlNode.parentNode.replaceChild(insert, htmlNode);
break;
case "remove":
htmlNode.remove();
break;
}
},
};
},{}],7:[function(require,module,exports){
"use strict";
const ImageCarousel = require("../../../generic-components/image-carousel");
const { getArticleBody } = require("../../../lib/article-utils");
class TeamMember {
constructor(props) {
this.props = props;
}
render() {
const { title, subtitle, body, images, path } = this.props;
return {
tag: "div",
class: "team-member",
contents: [
{
tag: "div",
class: "team-member-img",
contents: [{ tag: "img", src: images.map(im => `${path}/images/${im}`)[0] }],
},
{
tag: "h3",
class: "team-member-title",
contents: title,
},
{
tag: "strong",
class: "team-member-subtitle",
contents: subtitle,
},
{
tag: "p",
class: "team-member-body",
contents: getArticleBody(body),
},
],
};
}
}
class GameArticle {
constructor(props) {
this.props = props;
}
render() {
const { title, tags, body, subtitle, images, path, team_subarticles } = this.props;
return {
tag: "article",
class: "game-article",
contents: [
{
tag: "h2",
class: "game-title",
contents: title,
},
{
tag: "div",
class: "game-tags",
contents: tags.map(tag => {
return { tag: "span", contents: tag };
}),
},
{
tag: "h3",
class: "game-subtitle",
contents: subtitle,
},
{
tag: "div",
class: "game-description",
contents: getArticleBody(body),
},
new ImageCarousel({ images: images.map(img => `${path}/images/${img}`) }).render(),
{
tag: "div",
class: "game-team",
contents: [
{
tag: "h2",
contents: "L'équipe",
},
{
tag: "div",
class: "team-members",
contents: team_subarticles.map(tsa =>
new TeamMember({ ...tsa }).render()
),
},
],
},
],
};
}
}
module.exports = GameArticle;
},{"../../../generic-components/image-carousel":3,"../../../lib/article-utils":4}],8:[function(require,module,exports){
"use strict";
const { game_articles_url } = require("../../../../constants");
const { loadArticles, populateArticles } = require("../../../lib/article-utils");
const objectHtmlRenderer = require("../../../lib/object-html-renderer");
const GameArticle = require("./game-article");
class GameArticles {
constructor(props) {
this.props = props;
this.state = {
articles: [],
};
this.id = performance.now();
this.loadArticles();
}
loadArticles() {
loadArticles(game_articles_url)
.then(articles => {
Promise.all(
articles.map(async a => {
if (a.team_subarticles) {
a.team_subarticles = await populateArticles(
a.team_subarticles.map(sa => Object.assign(sa, { path: a.path }))
);
}
return a;
})
).then(completeArticles => {
this.state.articles = completeArticles;
this.refresh();
});
})
.catch(e => console.log(e));
}
renderPlaceholder() {
return {
tag: "article",
class: "placeholder",
contents: [{ tag: "div" }, { tag: "div" }],
};
}
refresh() {
objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
mode: "replace",
});
}
render() {
const { articles } = this.state;
return {
tag: "section",
class: "game-articles page-contents-center",
id: this.id,
contents:
articles.length > 0
? articles.map(article => new GameArticle({ ...article }).render())
: [this.renderPlaceholder()],
};
}
}
module.exports = GameArticles;
},{"../../../../constants":2,"../../../lib/article-utils":4,"../../../lib/object-html-renderer":6,"./game-article":7}],9:[function(require,module,exports){
"use strict";
const GameArticles = require("./components/game-articles");
class GamesPage {
constructor(args) {
Object.assign(this, args);
}
render() {
return {
tag: "div",
id:"games-page",
contents: [
{
tag: "div",
class: "page-header",
contents: [
{ tag: "h1", contents: "Jeux", class: "page-contents-center" },
{
tag: "p",
class: "page-contents-center",
contents: `Créer des jeux vidéos c'est cœur de ce qui nous passionne.
<br/>Retrouvez ici nos créations, à jouer en ligne ou à télécharger, et découvrez nos projets en cours.`,
},
],
},
new GameArticles().render(),
],
};
}
}
module.exports = GamesPage;
},{"./components/game-articles":8}],10:[function(require,module,exports){
"use strict";
"use strict";
const runPage = require("../../run-page");
const GamesPage = require("./games");
runPage(GamesPage);
},{"../../run-page":11,"./games":9}],11:[function(require,module,exports){
"use strict";
const objectHtmlRenderer = require("./lib/object-html-renderer");
const Template = require("./template/template");
module.exports = function runPage(PageComponent) {
const template = new Template({ page: new PageComponent() });
objectHtmlRenderer.setRenderCycleRoot(template);
objectHtmlRenderer.renderCycle();
};
},{"./lib/object-html-renderer":6,"./template/template":13}],12:[function(require,module,exports){
"use strict";
const { images_url } = require("../../../constants");
const NAV_MENU_ITEMS = [
["/games/", "Jeux"],
["/software-development/", "Software"],
[
"/education/",
"Pédagogie",
[
// submenu
["/education/#game-studio-club", "Game Studio Club"],
["/education/#popularization", "Vulgarisation numérique"],
],
],
];
class NavBar {
constructor() {
this.initEventHandlers();
}
handleBurgerClick() {
document.getElementById("nav-menu-list").classList.toggle("responsive-show");
}
initEventHandlers() {
window.addEventListener("click", event => {
if (
event.target.id !== "nav-menu-list" &&
!event.target.classList.contains("burger") &&
!event.target.parentNode.classList.contains("burger")
) {
document.getElementById("nav-menu-list").classList.remove("responsive-show");
}
});
}
renderHome() {
return {
tag: "div",
class: "home",
contents: [
{
tag: "a",
href: "/",
contents: [
{ tag: "img", src: `${images_url}/logo_kuadrado.svg` },
{
tag: "img",
class: "logo-text",
src: `${images_url}/logo_kuadrado_txt.svg`,
},
],
},
],
};
}
renderMenu(menuItemsArray, isSubmenu = false) {
return {
tag: "ul",
id: "nav-menu-list",
class: isSubmenu ? "submenu" : "",
contents: menuItemsArray.map(link => {
const [href, text, submenu] = link;
return {
tag: "li",
class: !isSubmenu && window.location.pathname === href ? "active" : "",
contents: [
{
tag: "a",
href,
contents: text,
},
].concat(submenu ? [this.renderMenu(submenu, true)] : []),
};
}),
};
}
renderResponsiveBurger() {
return {
tag: "div",
class: "burger",
onclick: this.handleBurgerClick.bind(this),
contents: [{ tag: "span", contents: "···" }],
};
}
render() {
return {
tag: "nav",
contents: [
this.renderHome(),
this.renderResponsiveBurger(),
this.renderMenu(NAV_MENU_ITEMS),
],
};
}
}
module.exports = NavBar;
},{"../../../constants":2}],13:[function(require,module,exports){
"use strict";
const { in_construction } = require("../../config");
const { images_url } = require("../../constants");
const NavBar = require("./components/navbar");
class Template {
constructor(props) {
this.props = props;
}
render() {
return {
tag: "main",
contents: [
{
tag: "header",
contents: [new NavBar().render()],
},
in_construction && {
tag: "section",
class: "warning-banner",
contents: [
{
tag: "strong",
class: "page-contents-center",
contents: "Site en construction ...",
},
],
},
{
tag: "section",
id: "page-container",
contents: [this.props.page.render()],
},
{
tag: "footer",
contents: [
{
tag: "div",
class: "logo",
contents: [
{
tag: "img",
src: `${images_url}/logo_kuadrado.svg`,
},
{
tag: "img",
class: "text-logo",
src: `${images_url}/logo_kuadrado_txt.svg`,
},
],
},
{
tag: "span",
contents:
"Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
},
{
tag: "a",
href: "mailto:contact@kuadrado-software.fr",
contents: "contact@kuadrado-software.fr",
},
],
},
],
};
}
}
module.exports = Template;
},{"../../config":1,"../../constants":2,"./components/navbar":12}]},{},[10]);