aboutsummaryrefslogtreecommitdiffstats
path: root/htdocs/src/js/app.js
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-10-30 22:11:00 +0200
committerArmand Philippot <git@armandphilippot.com>2021-10-30 22:52:23 +0200
commit3a3baddad1c801d77dc398d2c6980f3c14f4a47c (patch)
tree9e06aef730504470111c010e53a1857f7b01ab83 /htdocs/src/js/app.js
parentc3045b163e74b42c0a0e71c646740c76d3bb5ba1 (diff)
chore: move htdocs to repo root
Diffstat (limited to 'htdocs/src/js/app.js')
-rw-r--r--htdocs/src/js/app.js382
1 files changed, 0 insertions, 382 deletions
diff --git a/htdocs/src/js/app.js b/htdocs/src/js/app.js
deleted file mode 100644
index 38aee0e..0000000
--- a/htdocs/src/js/app.js
+++ /dev/null
@@ -1,382 +0,0 @@
-import projects from './config/projects';
-import {
- translate,
- setLocale,
- currentLocale,
- supportedLanguages,
-} from './i18n/i18n';
-import {
- hideToBottom,
- hideToLeft,
- showFromBottom,
- showFromLeft,
-} from './utilities/animations';
-import { isSmallVw, isStyleJsExists } from './utilities/helpers';
-
-/**
- * Show/hide header and footer with slide animation (left).
- */
-function toggleHeaderFooter() {
- const header = document.querySelector('header');
- const footer = document.querySelector('footer');
- const elements = [header, footer];
-
- elements.forEach((el) => {
- if (el.classList.contains('hide')) {
- showFromLeft(el);
- } else {
- hideToLeft(el);
- }
- });
-}
-
-/**
- * Show/hide project details with slide animation (bottom).
- */
-function toggleProjectDetails() {
- const details = document.querySelector('.project-details');
-
- if (details.classList.contains('hide')) {
- showFromBottom(details);
- } else {
- hideToBottom(details);
- }
-}
-
-/**
- * Add an event listener to show or hide header and footer.
- */
-function listenMenuBtn() {
- const menuBtn = document.querySelector('.btn--menu');
- menuBtn.addEventListener('click', toggleHeaderFooter);
-}
-
-/**
- * Show or hide the project details button depending on current location.
- */
-function toggleProjectDetailsBtn() {
- const button = document.querySelector('.btn--details');
- const currentPath = window.location.hash;
-
- if (currentPath) {
- button.style.display = '';
- } else {
- button.style.display = 'none';
- }
-}
-
-/**
- * Update the visibility of some DOM elements depending on viewport.
- */
-function updateView() {
- const header = document.querySelector('header');
- const footer = document.querySelector('footer');
- const toolbar = document.querySelector('.toolbar');
- const details = document.querySelector('.project-details');
-
- if (isSmallVw()) {
- header.classList.add('hide');
- footer.classList.add('hide');
- toolbar.classList.remove('hide');
- details?.classList.add('hide');
- details?.classList.remove('fade-in');
- } else {
- showFromLeft(header);
- showFromLeft(footer);
- toolbar.classList.add('hide');
- details?.classList.remove('hide');
- details?.classList.add('fade-in');
- }
-
- toggleProjectDetailsBtn();
-}
-
-/**
- * Update view when the window size changes.
- */
-function listenWindowSize() {
- window.addEventListener('resize', updateView);
-}
-
-/**
- * Retrieve a project by id.
- * @param {Integer} id - The project id.
- * @returns {Object} The current project.
- */
-function getCurrentProject(id) {
- return projects.find((project) => project.id === id);
-}
-
-/**
- * Get a list item for the given repo.
- * @param {String} name - The repository name.
- * @param {String} url - The repository URL.
- * @returns {HTMLElement} A list item.
- */
-function getRepoItem(name, url) {
- const item = document.createElement('li');
- const link = document.createElement('a');
- const span = document.createElement('span');
- span.classList.add('screen-reader-text');
- span.textContent = name;
- link.classList.add('list__link', `list__link--${name.toLocaleLowerCase()}`);
- link.href = url;
- link.appendChild(span);
- item.classList.add('list__item');
- item.appendChild(link);
- return item;
-}
-
-/**
- * Get the repos list wrapped inside ul element and the title.
- * @param {Object[]} repos - An array of repo with name and URL.
- * @returns {[title, list]} An array of HTMLElements for title and list.
- */
-function getRepos(repos) {
- if (repos.length === 0) return [];
-
- const wrapper = document.createElement('div');
- const title = document.createElement('h3');
- const list = document.createElement('ul');
- const items = repos.map((repo) => getRepoItem(repo.name, repo.url));
- title.classList.add('project-details__title');
- title.textContent = translate('main.project.details.repo', {
- count: repos.length,
- });
- list.classList.add('list', 'list--repos');
- list.append(...items);
- wrapper.append(title, list);
- return [title, list];
-}
-
-/**
- * Get the technologies list wrapped inside ul element and the title.
- * @param {String[]} technologies - An array of technology names.
- * @returns {[title, list]} An array of HTMLElements for title and list.
- */
-function getTechs(technologies) {
- if (technologies.length === 0) return [];
-
- const title = document.createElement('h3');
- title.classList.add('project-details__title');
- title.textContent = translate('main.project.details.tech', {
- count: technologies.length,
- });
- const list = document.createElement('ul');
- const items = technologies.map((technology) => {
- const item = document.createElement('li');
- item.textContent = technology;
- return item;
- });
- list.classList.add('list', 'list--tech');
- list.append(...items);
- return [title, list];
-}
-
-/**
- * Retrieve the project details.
- * @param {Object} project - The project.
- * @returns {HTMLElement} The project details wrapped in a div.
- */
-function getProjectDetails(project) {
- const details = document.createElement('div');
- const title = document.createElement('h2');
- const techList = project?.technologies ? getTechs(project.technologies) : [];
- const reposList = getRepos(project.repo);
- const locale = currentLocale();
- let description;
-
- if (project.description) {
- description = document.createElement('div');
- description.classList.add('project-details__description');
- description.textContent = project.description[locale] || '';
- } else {
- description = '';
- }
-
- title.classList.add('project-details__title');
- title.textContent = translate('main.project.details.about', {
- name: project.name,
- });
- details.classList.add('project-details');
- if (!isSmallVw()) details.classList.add('fade-in');
- details.replaceChildren(title, description, ...techList, ...reposList);
-
- return details;
-}
-
-/**
- * Get an iframe for the given path/url.
- * @param {String} src - The path/url to use as source.
- * @returns {HTMLElement} The iframe.
- */
-function getIframe(src) {
- const iframe = document.createElement('iframe');
- iframe.src = src;
- return iframe;
-}
-
-/**
- * Retrieve the project preview.
- * @param {String} projectPath - The project path.
- * @returns {HTMLElement} The project preview wrapped in a div.
- */
-function getProjectPreview(projectPath) {
- const preview = document.createElement('div');
- const iframe = getIframe(projectPath);
- preview.classList.add('project-preview', 'fade-in');
- preview.replaceChildren(iframe);
- return preview;
-}
-
-/**
- * Display the targeted project.
- * @param {String} id - The project id.
- */
-function showProject(id) {
- const currentProject = getCurrentProject(id);
- const main = document.querySelector('.main');
- const details = getProjectDetails(currentProject);
- const preview = getProjectPreview(currentProject.path);
- const detailsBtn = document.querySelector('.btn--details');
-
- if (isSmallVw()) details.classList.add('hide');
-
- detailsBtn.textContent = translate('main.project.details.about', {
- name: currentProject.name,
- });
- detailsBtn.addEventListener('click', toggleProjectDetails);
- window.history.pushState({}, currentProject.name, `/#${id}`);
- document.title = `${currentProject.name} | Demo | Armand Philippot`;
- main.replaceChildren(preview, details);
-}
-
-/**
- * Add a CSS class to the current project in projects nav.
- * @param {String} id - The project id.
- */
-function setSelectedProject(id) {
- const links = document.querySelectorAll('.nav__link');
- links.forEach((link) => {
- if (link.id === id) {
- link.classList.add('nav__link--selected');
- } else {
- link.classList.remove('nav__link--selected');
- }
- });
-}
-
-/**
- * Create a list item for a project.
- * @param {String} id - The project id.
- * @param {String} name - The project name.
- * @returns {HTMLElement} The list item.
- */
-function getProjectsNavItem(id, name) {
- const item = document.createElement('li');
- const link = document.createElement('a');
- link.classList.add('nav__link');
- link.href = `/#${id}`;
- link.id = id;
- link.textContent = name;
- link.addEventListener('click', (e) => {
- e.preventDefault();
- showProject(id);
- setSelectedProject(id);
- toggleProjectDetailsBtn();
- if (isSmallVw()) toggleHeaderFooter();
- });
- item.classList.add('nav__item');
- item.appendChild(link);
- return item;
-}
-
-/**
- * Print the list of available projects.
- */
-function printProjectsNav() {
- const ul = document.querySelector('.nav .nav__list');
-
- projects.forEach((project) => {
- const item = getProjectsNavItem(project.id, project.name);
- ul.appendChild(item);
- });
-}
-
-/**
- * Add style.js script for development purposes.
- */
-function loadWebpackStyles() {
- if (isStyleJsExists()) {
- const head = document.querySelector('head');
- const script = document.createElement('script');
- script.src = 'assets/js/style.js';
- head.appendChild(script);
- }
-}
-
-/**
- * Load corresponding project if the requested page contains a hash.
- */
-function printRequestedPage() {
- const currentPath = window.location.hash;
-
- if (currentPath) {
- const id = currentPath.replace('#', '');
- showProject(id);
- setSelectedProject(id);
- }
-}
-
-/**
- * Replace the legal notice link and text.
- */
-function replaceLegalNoticeLink() {
- const link = document.querySelector('.nav__link--legal');
- link.href = translate('footer.legalNotice.link');
- link.textContent = translate('footer.legalNotice.txt');
-}
-
-/**
- * Translate all text available in HTML templates.
- */
-function translateHTMLContent() {
- const brandingDesc = document.querySelector('.branding__description');
- const navLabel = document.querySelector('.nav__label');
- const license = document.querySelector('.copyright__license');
- const instructions = document.querySelector('.instructions');
- brandingDesc.textContent = translate('branding.description');
- navLabel.textContent = translate('nav.title');
- license.title = translate('footer.license');
- if (instructions) instructions.textContent = translate('main.instructions');
-}
-
-/**
- * Translate the website according to the user preferred language.
- */
-function setAppLocale() {
- const preferredLanguage = navigator.language;
- const supportedLanguage = supportedLanguages.find(
- (lang) => preferredLanguage.startsWith(lang.code)
- // eslint-disable-next-line function-paren-newline -- Conflict with Prettier
- );
- const locale = supportedLanguage?.code || 'en';
- setLocale(locale);
-}
-
-/**
- * Initialize the website with the projects list.
- */
-function init() {
- setAppLocale();
- translateHTMLContent();
- replaceLegalNoticeLink();
- loadWebpackStyles();
- printProjectsNav();
- updateView();
- listenWindowSize();
- listenMenuBtn();
- printRequestedPage();
-}
-
-init();