Refactor and minor fixes
This commit is contained in:
parent
2dc9c45642
commit
fe75f9af88
31 changed files with 187 additions and 193 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { PageBackground } from '../page/background/background';
|
||||
import { Image } from '../page/basics/image/image';
|
||||
import { PageFooter } from '../page/footer/footer';
|
||||
import { Image } from '../page/basics/image/image.html';
|
||||
import { Footer } from '../page/footer/footer.html';
|
||||
import { PageHeader } from '../page/header/header';
|
||||
import { PageImageViewer } from '../page/image-viewer/image-viewer';
|
||||
import { Main } from '../page/main/main';
|
||||
|
|
@ -28,7 +28,11 @@ export const create = (): Array<PageElement> => [
|
|||
new PageBackground(1, 1),
|
||||
new PageHeader({
|
||||
name: `András Schmelczer`,
|
||||
photo: new Image(meWebP, meJpeg, `a picture of me`, false),
|
||||
photo: Image({
|
||||
imageWebP: meWebP,
|
||||
imageJpeg: meJpeg,
|
||||
alt: `a picture of me`,
|
||||
}),
|
||||
about: [
|
||||
`
|
||||
I have always been fascinated by the engineering feats that surround us and pervade every aspect
|
||||
|
|
@ -62,7 +66,7 @@ export const create = (): Array<PageElement> => [
|
|||
ledsTimelineElement,
|
||||
],
|
||||
}),
|
||||
new PageFooter({
|
||||
Footer({
|
||||
title: `Learn more`,
|
||||
curriculaVitae: [{ name: `Curriculum vitae`, url: cvEnglish }],
|
||||
email: `andras@schmelczer.dev`,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import colourJpeg from '../media/color.jpg?format=jpg';
|
||||
import colourWebP from '../media/color.jpg?format=webp';
|
||||
|
|
@ -6,7 +6,12 @@ import colourWebP from '../media/color.jpg?format=webp';
|
|||
export const colorsTimelineElement: TimelineElementParameters = {
|
||||
title: `Photo colour grader`,
|
||||
date: `2018 June`,
|
||||
figure: new Image(colourWebP, colourJpeg, `a picture of the app`),
|
||||
figure: Image({
|
||||
imageWebP: colourWebP,
|
||||
imageJpeg: colourJpeg,
|
||||
alt: `a picture of the app`,
|
||||
container: true,
|
||||
}),
|
||||
description: `An innovative (at least I thought so) colour grader web application.`,
|
||||
more: [
|
||||
`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import myNotesJpeg from '../media/my-notes.png?format=jpg';
|
||||
import myNotesWebP from '../media/my-notes.png?format=webp';
|
||||
|
|
@ -7,7 +7,12 @@ import { GitHub } from '../shared';
|
|||
export const myNotesTimelineElement: TimelineElementParameters = {
|
||||
title: `My Notes`,
|
||||
date: `2019 November`,
|
||||
figure: new Image(myNotesWebP, myNotesJpeg, `two screenshots of the application`),
|
||||
figure: Image({
|
||||
imageWebP: myNotesWebP,
|
||||
imageJpeg: myNotesJpeg,
|
||||
alt: `two screenshots of the application`,
|
||||
container: true,
|
||||
}),
|
||||
description: `A minimalist note organiser and editor powered by Markwon.`,
|
||||
more: [
|
||||
`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import processSimulatorInputJpeg from '../media/process-simulator-input.jpg?format=jpg';
|
||||
import processSimulatorInputWebP from '../media/process-simulator-input.jpg?format=webp';
|
||||
|
|
@ -6,11 +6,12 @@ import processSimulatorInputWebP from '../media/process-simulator-input.jpg?form
|
|||
export const nuclearEditorTimelineElement: TimelineElementParameters = {
|
||||
title: `Graph editing application`,
|
||||
date: `2018 October - November`,
|
||||
figure: new Image(
|
||||
processSimulatorInputWebP,
|
||||
processSimulatorInputJpeg,
|
||||
`a picture of the simulator's UI`
|
||||
),
|
||||
figure: Image({
|
||||
imageWebP: processSimulatorInputWebP,
|
||||
imageJpeg: processSimulatorInputJpeg,
|
||||
alt: `a picture of the simulator's UI`,
|
||||
container: true,
|
||||
}),
|
||||
description: `
|
||||
An intuitive editor to create and edit input for the nuclear facility simulator.
|
||||
`,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import processSimulatorJpeg from '../media/process-simulator.jpg?format=jpg';
|
||||
import processSimulatorWebP from '../media/process-simulator.jpg?format=webp';
|
||||
|
|
@ -6,11 +6,12 @@ import processSimulatorWebP from '../media/process-simulator.jpg?format=webp';
|
|||
export const nuclearTimelineElement: TimelineElementParameters = {
|
||||
title: `Simulating the cooling system of a nuclear facility`,
|
||||
date: `2018 October - November`,
|
||||
figure: new Image(
|
||||
processSimulatorWebP,
|
||||
processSimulatorJpeg,
|
||||
`a screenshot of the simulator`
|
||||
),
|
||||
figure: Image({
|
||||
imageWebP: processSimulatorWebP,
|
||||
imageJpeg: processSimulatorJpeg,
|
||||
alt: `a screenshot of the simulator`,
|
||||
container: true,
|
||||
}),
|
||||
description: `
|
||||
The temperatures and flow velocities are dynamically calculated in a fluid-based
|
||||
cooling system based on a simple model.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import photosJpeg from '../media/photos.jpg?format=jpg';
|
||||
import photosWebP from '../media/photos.jpg?format=webp';
|
||||
|
|
@ -7,7 +7,12 @@ import { Open } from '../shared';
|
|||
export const photosTimelineElement: TimelineElementParameters = {
|
||||
title: `Photos`,
|
||||
date: `2016 summer`,
|
||||
figure: new Image(photosWebP, photosJpeg, `a picture of the website`),
|
||||
figure: Image({
|
||||
imageWebP: photosWebP,
|
||||
imageJpeg: photosJpeg,
|
||||
alt: `a picture of the website`,
|
||||
container: true,
|
||||
}),
|
||||
description: `A simple webpage where you can view my photos.`,
|
||||
more: [
|
||||
`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Image } from '../../page/basics/image/image';
|
||||
import { Image } from '../../page/basics/image/image.html';
|
||||
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters';
|
||||
import towersJpeg from '../media/towers.png?format=jpg';
|
||||
import towersWebP from '../media/towers.png?format=webp';
|
||||
|
|
@ -7,7 +7,12 @@ import { GitHub, Open } from '../shared';
|
|||
export const towersTimelineElement: TimelineElementParameters = {
|
||||
title: `Towers tracking app`,
|
||||
date: `2019 August - September`,
|
||||
figure: new Image(towersWebP, towersJpeg, `a picture of the website`),
|
||||
figure: Image({
|
||||
imageWebP: towersWebP,
|
||||
imageJpeg: towersJpeg,
|
||||
alt: `a picture of the website`,
|
||||
container: true,
|
||||
}),
|
||||
description: `An aesthetic representation of your previous and current goals/tasks.`,
|
||||
more: [
|
||||
`
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import openIcon from '../../static/icons/open.svg';
|
|||
import packageIcon from '../../static/icons/package.svg';
|
||||
import pythonIcon from '../../static/icons/python.svg';
|
||||
import youtubeIcon from '../../static/icons/youtube.svg';
|
||||
import { ImageAnchorFactory } from '../page/basics/image-anchor/image-anchor';
|
||||
import { ImageAnchorFactory } from '../page/basics/image-anchor/image-anchor.html';
|
||||
|
||||
export const GitHub = ImageAnchorFactory(githubIcon, 'Open on GitHub');
|
||||
export const NPM = ImageAnchorFactory(packageIcon, 'Open on npm');
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
import { html } from '../../../types/html';
|
||||
import { url } from '../../../types/url';
|
||||
import './image-anchor.scss';
|
||||
|
||||
export const generate = ({
|
||||
href,
|
||||
svg,
|
||||
title,
|
||||
shouldDownload,
|
||||
}: {
|
||||
href: url;
|
||||
svg: url;
|
||||
title: string;
|
||||
shouldDownload: boolean;
|
||||
}): html => `
|
||||
export const ImageAnchorFactory =
|
||||
(
|
||||
svg: string,
|
||||
title: string,
|
||||
{ shouldDownload = false }: { shouldDownload?: boolean } = {}
|
||||
) =>
|
||||
(href: url) =>
|
||||
`
|
||||
<a class="image-anchor"
|
||||
href="${href}"
|
||||
rel="noopener"
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
import { url } from '../../../types/url';
|
||||
import { generate } from './image-anchor.html';
|
||||
|
||||
export const ImageAnchorFactory =
|
||||
(
|
||||
svg: string,
|
||||
title: string,
|
||||
{ shouldDownload = false }: { shouldDownload?: boolean } = {}
|
||||
) =>
|
||||
(href: url) =>
|
||||
generate({ href, svg, title, shouldDownload });
|
||||
|
|
@ -3,18 +3,18 @@ import { html } from '../../../types/html';
|
|||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import './image.scss';
|
||||
|
||||
export const generate = ({
|
||||
sizes,
|
||||
export const Image = ({
|
||||
imageWebP,
|
||||
imageJpeg,
|
||||
alt,
|
||||
container,
|
||||
container = false,
|
||||
isIgnoredByImageViewer = false,
|
||||
}: {
|
||||
sizes: string;
|
||||
imageWebP: ResponsiveImage;
|
||||
imageJpeg: ResponsiveImage;
|
||||
alt: string;
|
||||
container: boolean;
|
||||
container?: boolean;
|
||||
isIgnoredByImageViewer?: boolean;
|
||||
}): html => `
|
||||
${
|
||||
container
|
||||
|
|
@ -23,33 +23,39 @@ export const generate = ({
|
|||
}%">`
|
||||
: ''
|
||||
}
|
||||
<picture loading="lazy">
|
||||
<source
|
||||
srcset="${imageWebP.srcSet}"
|
||||
sizes="${sizes}"
|
||||
width="${imageWebP.width}"
|
||||
height="${imageWebP.height}"
|
||||
type="image/webp"
|
||||
alt="${alt}"
|
||||
/>
|
||||
<source
|
||||
srcset="${imageJpeg.srcSet}"
|
||||
sizes="${sizes}"
|
||||
width="${imageJpeg.width}"
|
||||
height="${imageJpeg.height}"
|
||||
type="image/jpeg"
|
||||
alt="${alt}"
|
||||
/>
|
||||
<img
|
||||
tabindex="0"
|
||||
loading="lazy"
|
||||
srcset="${imageJpeg.srcSet}"
|
||||
sizes="${sizes}"
|
||||
width="${imageJpeg.width}"
|
||||
height="${imageJpeg.height}"
|
||||
src="${last(imageJpeg.images)?.path}"
|
||||
alt="${alt}"
|
||||
/>
|
||||
</picture>
|
||||
<picture loading="lazy">
|
||||
<source
|
||||
srcset="${imageWebP.srcSet}"
|
||||
sizes="${getSizes(imageWebP)}"
|
||||
width="${imageWebP.width}"
|
||||
height="${imageWebP.height}"
|
||||
type="image/webp"
|
||||
alt="${alt}"
|
||||
/>
|
||||
<source
|
||||
srcset="${imageJpeg.srcSet}"
|
||||
sizes="${getSizes(imageJpeg)}"
|
||||
width="${imageJpeg.width}"
|
||||
height="${imageJpeg.height}"
|
||||
type="image/jpeg"
|
||||
alt="${alt}"
|
||||
/>
|
||||
<img
|
||||
${isIgnoredByImageViewer ? 'image-viewer-ignore' : ''}
|
||||
tabindex="0"
|
||||
loading="lazy"
|
||||
width="${imageJpeg.width}"
|
||||
height="${imageJpeg.height}"
|
||||
src="${last(imageJpeg.images)?.path}"
|
||||
alt="${alt}"
|
||||
/>
|
||||
</picture>
|
||||
${container ? `</div>` : ''}
|
||||
`;
|
||||
|
||||
const IMAGE_SCREEN_RATIO = 0.8;
|
||||
const getSizes = (image: ResponsiveImage): string =>
|
||||
image.images
|
||||
.slice(0, -1)
|
||||
.map((d) => `(max-width: ${d.width / IMAGE_SCREEN_RATIO}px) ${d.width}px,`)
|
||||
.join('\n') + `\n${last(image.images)!.width}px`;
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import { last } from '../../../helper/last';
|
||||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { generate } from './image.html';
|
||||
|
||||
export class Image extends PageElement {
|
||||
private static readonly imageScreenRatio = 0.8;
|
||||
|
||||
public constructor(
|
||||
imageWebP: ResponsiveImage,
|
||||
imageJpeg: ResponsiveImage,
|
||||
alt: string,
|
||||
container = true
|
||||
) {
|
||||
super(
|
||||
createElement(
|
||||
generate({
|
||||
imageWebP,
|
||||
imageJpeg,
|
||||
alt,
|
||||
container,
|
||||
sizes: Image.getSizes(imageWebP),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static getSizes(image: ResponsiveImage): string {
|
||||
return (
|
||||
image.images
|
||||
.slice(0, -1)
|
||||
.map((d) => `(max-width: ${d.width / Image.imageScreenRatio}px) ${d.width}px,`)
|
||||
.join('\n') + `\n${last(image.images)!.width}px`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,27 @@
|
|||
import loading from '../../../../static/icons/loading.svg';
|
||||
import play from '../../../../static/icons/play-button.svg';
|
||||
import { html } from '../../../types/html';
|
||||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import { Image } from '../../basics/image/image.html';
|
||||
import './preview.scss';
|
||||
|
||||
export const generate = ({ alt }: { alt: string }): html => `
|
||||
export const generate = ({
|
||||
alt,
|
||||
posterWebP,
|
||||
posterJpeg,
|
||||
}: {
|
||||
alt: string;
|
||||
posterWebP: ResponsiveImage;
|
||||
posterJpeg: ResponsiveImage;
|
||||
}): html => `
|
||||
<div class="preview">
|
||||
<img image-viewer-ignore class="poster"/>
|
||||
${Image({
|
||||
imageWebP: posterWebP,
|
||||
imageJpeg: posterJpeg,
|
||||
alt,
|
||||
container: true,
|
||||
isIgnoredByImageViewer: true,
|
||||
})}
|
||||
<div class="overlay">
|
||||
<div class="loading">${loading}</div>
|
||||
<iframe title="${alt}" allowfullscreen loading="lazy"></iframe>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { Image } from '../image/image';
|
||||
import { generate } from './preview.html';
|
||||
|
||||
export class Preview extends PageElement {
|
||||
|
|
@ -11,9 +10,8 @@ export class Preview extends PageElement {
|
|||
private readonly url: string,
|
||||
alt: string
|
||||
) {
|
||||
super(createElement(generate({ alt })));
|
||||
super(createElement(generate({ posterWebP, posterJpeg, alt })));
|
||||
this.url += '?portfolioView';
|
||||
this.attachElementByReplacing('.poster', new Image(posterWebP, posterJpeg, alt));
|
||||
this.query('.start-button').addEventListener('click', this.loadContent.bind(this));
|
||||
}
|
||||
|
||||
|
|
|
|||
10
src/page/basics/video/video-parameters.ts
Normal file
10
src/page/basics/video/video-parameters.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import { url } from '../../../types/url';
|
||||
|
||||
export interface VideoParameters {
|
||||
mp4: url;
|
||||
webm: url;
|
||||
posterWebP: ResponsiveImage;
|
||||
posterJpeg: ResponsiveImage;
|
||||
invertButton?: boolean;
|
||||
}
|
||||
|
|
@ -1,19 +1,26 @@
|
|||
import loading from '../../../../static/icons/loading.svg';
|
||||
import play from '../../../../static/icons/play-button.svg';
|
||||
import { html } from '../../../types/html';
|
||||
import { VideoParameters } from './video';
|
||||
import { Image } from '../../basics/image/image.html';
|
||||
import { VideoParameters } from './video-parameters';
|
||||
import './video.scss';
|
||||
|
||||
export const generate = ({
|
||||
webm,
|
||||
mp4,
|
||||
posterWebP,
|
||||
posterJpeg,
|
||||
invertButton,
|
||||
}: VideoParameters): html => `
|
||||
<div class="figure-container video-container" style="padding-top:${
|
||||
(posterJpeg.height / posterJpeg.width) * 100
|
||||
}%">
|
||||
<img image-viewer-ignore class="poster"/>
|
||||
${Image({
|
||||
imageWebP: posterWebP,
|
||||
imageJpeg: posterJpeg,
|
||||
alt: `thumbnail for the video`,
|
||||
isIgnoredByImageViewer: true,
|
||||
})}
|
||||
<div class="loading">${loading}</div>
|
||||
<video playsinline preload="none">
|
||||
<source src="${webm}" type="video/webm"/>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,13 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import { ResponsiveImage } from '../../../types/responsive-image';
|
||||
import { url } from '../../../types/url';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { Image } from '../image/image';
|
||||
import { VideoParameters } from './video-parameters';
|
||||
import { generate } from './video.html';
|
||||
|
||||
export interface VideoParameters {
|
||||
mp4: url;
|
||||
webm: url;
|
||||
posterWebP: ResponsiveImage;
|
||||
posterJpeg: ResponsiveImage;
|
||||
invertButton?: boolean;
|
||||
}
|
||||
|
||||
export class Video extends PageElement {
|
||||
private video: HTMLVideoElement;
|
||||
|
||||
public constructor(options: VideoParameters) {
|
||||
super(createElement(generate(options)));
|
||||
this.attachElementByReplacing(
|
||||
'.poster',
|
||||
new Image(options.posterWebP, options.posterJpeg, `thumbnail for the video`, false)
|
||||
);
|
||||
|
||||
this.video = this.query('video') as HTMLVideoElement;
|
||||
this.video.addEventListener('click', this.startVideo.bind(this));
|
||||
this.video.addEventListener('play', () =>
|
||||
|
|
|
|||
|
|
@ -2,17 +2,27 @@ import cvIcon from '../../../static/icons/cv.svg';
|
|||
import emailIcon from '../../../static/icons/email.svg';
|
||||
import linkedinIcon from '../../../static/icons/linkedin.svg';
|
||||
import { html } from '../../types/html';
|
||||
import { FooterParameters } from './footer';
|
||||
import { url } from '../../types/url';
|
||||
import './footer.scss';
|
||||
|
||||
export const generate = ({
|
||||
export const Footer = ({
|
||||
title,
|
||||
email,
|
||||
curriculaVitae,
|
||||
linkedin,
|
||||
lastEditText,
|
||||
lastEdit,
|
||||
}: FooterParameters): html => `
|
||||
}: {
|
||||
title: string;
|
||||
email: url;
|
||||
linkedin: url;
|
||||
curriculaVitae: Array<{
|
||||
name: string;
|
||||
url: url;
|
||||
}>;
|
||||
lastEditText: string;
|
||||
lastEdit: Date;
|
||||
}): html => `
|
||||
<footer id="footer">
|
||||
<h2>${title}</h2>
|
||||
<ul>
|
||||
|
|
@ -25,7 +35,7 @@ export const generate = ({
|
|||
</li>
|
||||
`
|
||||
)
|
||||
.join('\n')}
|
||||
.join('')}
|
||||
<li>
|
||||
${linkedinIcon}
|
||||
<a id="linkedin" target="_blank" href="${linkedin}">Find me on LinkedIn</a>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
@use '../../style/mixins' as *;
|
||||
|
||||
#footer {
|
||||
footer#footer {
|
||||
text-align: center;
|
||||
|
||||
margin-top: var(--large-margin);
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
@include link;
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { url } from '../../types/url';
|
||||
import { PageElement } from '../page-element';
|
||||
import { generate } from './footer.html';
|
||||
|
||||
export interface FooterParameters {
|
||||
title: string;
|
||||
email: url;
|
||||
linkedin: url;
|
||||
curriculaVitae: Array<{
|
||||
name: string;
|
||||
url: url;
|
||||
}>;
|
||||
lastEditText: string;
|
||||
lastEdit: Date;
|
||||
}
|
||||
|
||||
export class PageFooter extends PageElement {
|
||||
constructor(footer: FooterParameters) {
|
||||
super(createElement(generate(footer)));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,14 +4,16 @@ import './header.scss';
|
|||
export const generate = ({
|
||||
name,
|
||||
about,
|
||||
photo,
|
||||
}: {
|
||||
name: string;
|
||||
about: Array<string>;
|
||||
photo: html;
|
||||
}): html => `
|
||||
<section id="about">
|
||||
<div class="picture"></div>
|
||||
${photo}
|
||||
<div class="placeholder"></div>
|
||||
<h1>${name}</h1>
|
||||
${about.map((t) => `<p>${t}</p>`).join('\n')}
|
||||
${about.map((t) => `<p>${t}</p>`).join('')}
|
||||
</section>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { Image } from '../basics/image/image';
|
||||
import { html } from '../../types/html';
|
||||
import { PageElement } from '../page-element';
|
||||
import { PageThemeSwitcher } from '../theme-switcher/theme-switcher';
|
||||
import { generate } from './header.html';
|
||||
import { PageThemeSwitcher } from './theme-switcher/theme-switcher';
|
||||
|
||||
export class PageHeader extends PageElement {
|
||||
public constructor({
|
||||
|
|
@ -11,12 +11,10 @@ export class PageHeader extends PageElement {
|
|||
about,
|
||||
}: {
|
||||
name: string;
|
||||
photo: Image;
|
||||
photo: html;
|
||||
about: Array<string>;
|
||||
}) {
|
||||
super(createElement(generate({ name, about })));
|
||||
|
||||
this.attachElementByReplacing('.picture', photo);
|
||||
super(createElement(generate({ name, about, photo })));
|
||||
this.attachElement(new PageThemeSwitcher());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { html } from '../../types/html';
|
||||
import { html } from '../../../types/html';
|
||||
import './theme-switcher.scss';
|
||||
|
||||
export const generate = (): html => `
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@use '../../style/mixins' as *;
|
||||
@use '../../../style/mixins' as *;
|
||||
|
||||
#theme-switcher {
|
||||
@include on-large-screen {
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { turnOffAnimations, turnOnAnimations } from '../../style/animations/animations';
|
||||
import { createElement } from '../../../helper/create-element';
|
||||
import {
|
||||
turnOffAnimations,
|
||||
turnOnAnimations,
|
||||
} from '../../../style/animations/animations';
|
||||
import {
|
||||
isSystemLevelDarkModeEnabled,
|
||||
turnOnDarkMode,
|
||||
turnOnLightMode,
|
||||
} from '../../style/dark-mode/dark-mode';
|
||||
import { PageElement } from '../page-element';
|
||||
} from '../../../style/dark-mode/dark-mode';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { generate } from './theme-switcher.html';
|
||||
|
||||
export class PageThemeSwitcher extends PageElement {
|
||||
|
|
@ -3,8 +3,11 @@ import { PageElement } from '../page-element';
|
|||
import { generate } from './main.html';
|
||||
|
||||
export class Main extends PageElement {
|
||||
constructor(...children: Array<PageElement>) {
|
||||
super(createElement(generate()), children);
|
||||
children.forEach((c) => this.attachElement(c));
|
||||
constructor(...children: Array<PageElement | string>) {
|
||||
const actualChildren = children.map((c) =>
|
||||
c instanceof PageElement ? c : new PageElement(createElement(c))
|
||||
);
|
||||
super(createElement(generate()), actualChildren);
|
||||
actualChildren.forEach((c) => this.attachElement(c));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export abstract class PageElement {
|
||||
export class PageElement {
|
||||
public constructor(
|
||||
public readonly htmlRoot: HTMLElement,
|
||||
protected children: Array<PageElement> = []
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { html } from '../../../types/html';
|
||||
import { Image } from '../../basics/image/image';
|
||||
import { Preview } from '../../basics/preview/preview';
|
||||
import { Video } from '../../basics/video/video';
|
||||
|
||||
export interface TimelineElementParameters {
|
||||
date: string;
|
||||
figure: Image | Video | Preview;
|
||||
figure: html | Video | Preview;
|
||||
title: string;
|
||||
description: string;
|
||||
more: Array<string>;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export const generate = (
|
|||
more
|
||||
? `
|
||||
<div class="more">
|
||||
${more.map((t) => `<p>${t}</p>`).join('\n')}
|
||||
${more.map((t) => `<p>${t}</p>`).join('')}
|
||||
</div>`
|
||||
: ''
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@
|
|||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: -10px;
|
||||
|
||||
> a {
|
||||
@include sub-title-font();
|
||||
|
|
@ -131,7 +132,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
.description,
|
||||
.info-button {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,12 @@ export class PageTimelineElement extends PageElement {
|
|||
addEventListener('resize', this.handleResize.bind(this));
|
||||
|
||||
this.query('.info-button').addEventListener('click', this.toggleOpen.bind(this));
|
||||
this.attachElementByReplacing('.figure', timelineElement.figure);
|
||||
this.attachElementByReplacing(
|
||||
'.figure',
|
||||
timelineElement.figure instanceof PageElement
|
||||
? timelineElement.figure
|
||||
: new PageElement(createElement(timelineElement.figure))
|
||||
);
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue