@simple-photo-gallery/theme-modern 2.0.3 → 2.0.10-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/features/themes/base-theme/components/gallery-section/GallerySectionHeader.astro +2 -1
- package/src/features/themes/base-theme/components/gallery-section/GallerySectionItem.astro +2 -2
- package/src/features/themes/base-theme/components/hero/Hero.astro +80 -52
- package/src/features/themes/base-theme/layouts/MainHead.astro +7 -3
- package/src/features/themes/base-theme/layouts/MainLayout.astro +11 -2
- package/src/features/themes/base-theme/pages/index.astro +3 -3
- package/src/features/themes/base-theme/utils/index.ts +4 -5
package/package.json
CHANGED
package/src/features/themes/base-theme/components/gallery-section/GallerySectionHeader.astro
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { GallerySection as GallerySectionType } from '@simple-photo-gallery/common';
|
|
3
2
|
import { renderMarkdown } from '@/lib/markdown';
|
|
4
3
|
|
|
4
|
+
import type { GallerySection as GallerySectionType } from '@simple-photo-gallery/common';
|
|
5
|
+
|
|
5
6
|
interface Props {
|
|
6
7
|
section: GallerySectionType;
|
|
7
8
|
}
|
|
@@ -19,8 +19,8 @@ const captionHtml = parsedCaption ? `<div class="image-caption markdown-content"
|
|
|
19
19
|
|
|
20
20
|
<a
|
|
21
21
|
class="gallery-section__item"
|
|
22
|
-
href={getPhotoPath(image.
|
|
23
|
-
data-pswp-src={getPhotoPath(image.
|
|
22
|
+
href={getPhotoPath(image.filename, mediaBaseUrl)}
|
|
23
|
+
data-pswp-src={getPhotoPath(image.filename, mediaBaseUrl)}
|
|
24
24
|
data-pswp-width={image.width}
|
|
25
25
|
data-pswp-height={image.height}
|
|
26
26
|
data-pswp-type={image.type}
|
|
@@ -1,69 +1,79 @@
|
|
|
1
1
|
---
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
2
4
|
import HeroScrollToGalleryBtn from '@/features/themes/base-theme/components/hero/HeroScrollToGalleryBtn.astro';
|
|
3
5
|
import { renderMarkdown } from '@/lib/markdown';
|
|
4
6
|
|
|
5
7
|
interface Props {
|
|
6
8
|
title: string;
|
|
7
9
|
description?: string;
|
|
10
|
+
headerImage?: string;
|
|
11
|
+
headerImageBlurHash?: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
10
|
-
const { title, description } = Astro.props;
|
|
14
|
+
const { title, description, headerImage, headerImageBlurHash } = Astro.props;
|
|
11
15
|
|
|
12
16
|
// Parse description as Markdown if it exists
|
|
13
17
|
const parsedDescription: string = description ? await renderMarkdown(description) : '';
|
|
18
|
+
|
|
19
|
+
// Extract basename from headerImage filename, fallback to generic name
|
|
20
|
+
const imgBasename = headerImage ? path.basename(headerImage, path.extname(headerImage)) : 'header';
|
|
14
21
|
---
|
|
15
22
|
|
|
16
23
|
<section class="hero">
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
24
|
+
<div class="hero__bg-wrapper">
|
|
25
|
+
{headerImageBlurHash && <canvas data-blur-hash={headerImageBlurHash} width={32} height={32} ></canvas>}
|
|
26
|
+
<picture class="hero__bg">
|
|
27
|
+
<!-- Portrait -->
|
|
28
|
+
<source
|
|
29
|
+
type="image/avif"
|
|
30
|
+
media="(max-aspect-ratio: 3/4)"
|
|
31
|
+
srcset={`
|
|
32
|
+
gallery/images/${imgBasename}_portrait_360.avif 360w,
|
|
33
|
+
gallery/images/${imgBasename}_portrait_480.avif 480w,
|
|
34
|
+
gallery/images/${imgBasename}_portrait_720.avif 720w,
|
|
35
|
+
gallery/images/${imgBasename}_portrait_1080.avif 1080w`}
|
|
36
|
+
sizes="(max-aspect-ratio: 3/4) 160vw, 100vw"
|
|
37
|
+
/>
|
|
38
|
+
<source
|
|
39
|
+
type="image/jpeg"
|
|
40
|
+
media="(max-aspect-ratio: 3/4)"
|
|
41
|
+
srcset={`
|
|
42
|
+
gallery/images/${imgBasename}_portrait_360.jpg 360w,
|
|
43
|
+
gallery/images/${imgBasename}_portrait_480.jpg 480w,
|
|
44
|
+
gallery/images/${imgBasename}_portrait_720.jpg 720w,
|
|
45
|
+
gallery/images/${imgBasename}_portrait_1080.jpg 1080w`}
|
|
46
|
+
sizes="(max-aspect-ratio: 3/4) 160vw, 100vw"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
<!-- Landscape -->
|
|
50
|
+
<source
|
|
51
|
+
type="image/avif"
|
|
52
|
+
srcset={`
|
|
53
|
+
gallery/images/${imgBasename}_landscape_640.avif 640w,
|
|
54
|
+
gallery/images/${imgBasename}_landscape_960.avif 960w,
|
|
55
|
+
gallery/images/${imgBasename}_landscape_1280.avif 1280w,
|
|
56
|
+
gallery/images/${imgBasename}_landscape_1920.avif 1920w,
|
|
57
|
+
gallery/images/${imgBasename}_landscape_2560.avif 2560w,
|
|
58
|
+
gallery/images/${imgBasename}_landscape_3840.avif 3840w`}
|
|
59
|
+
sizes="100vw"
|
|
60
|
+
/>
|
|
61
|
+
<source
|
|
62
|
+
type="image/jpg"
|
|
63
|
+
srcset={`
|
|
64
|
+
gallery/images/${imgBasename}_landscape_640.jpg 640w,
|
|
65
|
+
gallery/images/${imgBasename}_landscape_960.jpg 960w,
|
|
66
|
+
gallery/images/${imgBasename}_landscape_1280.jpg 1280w,
|
|
67
|
+
gallery/images/${imgBasename}_landscape_1920.jpg 1920w,
|
|
68
|
+
gallery/images/${imgBasename}_landscape_2560.jpg 2560w,
|
|
69
|
+
gallery/images/${imgBasename}_landscape_3840.jpg 3840w`}
|
|
70
|
+
sizes="100vw"
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
<!-- Fallback -->
|
|
74
|
+
<img src={`gallery/images/${imgBasename}_landscape_1920.jpg`} class="hero__bg-img" />
|
|
75
|
+
</picture>
|
|
76
|
+
</div>
|
|
67
77
|
<div class="hero__overlay"></div>
|
|
68
78
|
<div class="hero__content">
|
|
69
79
|
<h1 class="hero__title">{title}</h1>
|
|
@@ -83,6 +93,14 @@ const parsedDescription: string = description ? await renderMarkdown(description
|
|
|
83
93
|
overflow: hidden;
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
.hero__bg-wrapper {
|
|
97
|
+
position: absolute;
|
|
98
|
+
top: 0;
|
|
99
|
+
left: 0;
|
|
100
|
+
width: 100%;
|
|
101
|
+
height: 100%;
|
|
102
|
+
}
|
|
103
|
+
|
|
86
104
|
.hero__bg {
|
|
87
105
|
position: absolute;
|
|
88
106
|
top: 0;
|
|
@@ -91,13 +109,23 @@ const parsedDescription: string = description ? await renderMarkdown(description
|
|
|
91
109
|
height: 100%;
|
|
92
110
|
}
|
|
93
111
|
|
|
94
|
-
.hero__bg
|
|
112
|
+
.hero__bg-img {
|
|
95
113
|
width: 100%;
|
|
96
114
|
height: 100%;
|
|
97
115
|
object-fit: cover;
|
|
98
116
|
object-position: center;
|
|
99
117
|
}
|
|
100
118
|
|
|
119
|
+
.hero__bg-wrapper canvas {
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: 0;
|
|
122
|
+
left: 0;
|
|
123
|
+
width: 100%;
|
|
124
|
+
height: 100%;
|
|
125
|
+
display: block;
|
|
126
|
+
transition: transform 0.5s ease;
|
|
127
|
+
}
|
|
128
|
+
|
|
101
129
|
.hero__overlay {
|
|
102
130
|
position: absolute;
|
|
103
131
|
top: 0;
|
|
@@ -6,9 +6,13 @@ interface Props {
|
|
|
6
6
|
description?: string;
|
|
7
7
|
url?: string;
|
|
8
8
|
metadata?: GalleryMetadata;
|
|
9
|
+
headerImageBasename?: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
const { title, description, url, metadata } = Astro.props;
|
|
12
|
+
const { title, description, url, metadata, headerImageBasename } = Astro.props;
|
|
13
|
+
|
|
14
|
+
// Use headerImageBasename for dynamic image paths, fallback to generic name
|
|
15
|
+
const imgBasename = headerImageBasename || 'header';
|
|
12
16
|
---
|
|
13
17
|
|
|
14
18
|
<head>
|
|
@@ -74,7 +78,7 @@ const { title, description, url, metadata } = Astro.props;
|
|
|
74
78
|
as="image"
|
|
75
79
|
type="image/avif"
|
|
76
80
|
media="(max-aspect-ratio: 3/4)"
|
|
77
|
-
imagesrcset=
|
|
81
|
+
imagesrcset={`gallery/images/${imgBasename}_portrait_360.avif 360w, gallery/images/${imgBasename}_portrait_480.avif 480w, gallery/images/${imgBasename}_portrait_720.avif 720w, gallery/images/${imgBasename}_portrait_1080.avif 1080w`}
|
|
78
82
|
imagesizes="(max-aspect-ratio: 3/4) 160vw, 100vw"
|
|
79
83
|
fetchpriority="high"
|
|
80
84
|
/>
|
|
@@ -83,7 +87,7 @@ const { title, description, url, metadata } = Astro.props;
|
|
|
83
87
|
as="image"
|
|
84
88
|
type="image/avif"
|
|
85
89
|
media="(min-aspect-ratio: 3/4)"
|
|
86
|
-
imagesrcset=
|
|
90
|
+
imagesrcset={`gallery/images/${imgBasename}_landscape_640.avif 640w, gallery/images/${imgBasename}_landscape_960.avif 960w, gallery/images/${imgBasename}_landscape_1280.avif 1280w, gallery/images/${imgBasename}_landscape_1920.avif 1920w, gallery/images/${imgBasename}_landscape_2560.avif 2560w, gallery/images/${imgBasename}_landscape_3840.avif 3840w`}
|
|
87
91
|
imagesizes="100vw"
|
|
88
92
|
fetchpriority="high"
|
|
89
93
|
/>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
2
4
|
import MainHead from '@/features/themes/base-theme/layouts/MainHead.astro';
|
|
3
5
|
|
|
4
6
|
import type { GalleryMetadata } from '@simple-photo-gallery/common';
|
|
@@ -8,16 +10,23 @@ interface Props {
|
|
|
8
10
|
description?: string;
|
|
9
11
|
url?: string;
|
|
10
12
|
metadata?: GalleryMetadata;
|
|
13
|
+
analyticsScript?: string;
|
|
14
|
+
headerImage?: string;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
const { title, description, metadata, url } = Astro.props;
|
|
17
|
+
const { title, description, metadata, url, analyticsScript, headerImage } = Astro.props;
|
|
18
|
+
|
|
19
|
+
// Extract basename from headerImage filename
|
|
20
|
+
const headerImageBasename = headerImage ? path.basename(headerImage, path.extname(headerImage)) : undefined;
|
|
14
21
|
---
|
|
15
22
|
|
|
16
23
|
<!doctype html>
|
|
17
24
|
<html lang={metadata?.language || 'en'}>
|
|
18
|
-
<MainHead title={title} description={description} metadata={metadata} url={url} />
|
|
25
|
+
<MainHead title={title} description={description} metadata={metadata} url={url} headerImageBasename={headerImageBasename} />
|
|
19
26
|
<body>
|
|
20
27
|
<slot />
|
|
28
|
+
|
|
29
|
+
{analyticsScript && <Fragment set:html={analyticsScript} />}
|
|
21
30
|
</body>
|
|
22
31
|
</html>
|
|
23
32
|
|
|
@@ -16,7 +16,7 @@ const galleryData = JSON.parse(fs.readFileSync(galleryJsonPath, 'utf8'));
|
|
|
16
16
|
|
|
17
17
|
const gallery = galleryData as GalleryData;
|
|
18
18
|
|
|
19
|
-
const { title, description, metadata, sections, subGalleries, mediaBaseUrl, url } = gallery;
|
|
19
|
+
const { title, description, metadata, sections, subGalleries, mediaBaseUrl, url, analyticsScript, headerImage, headerImageBlurHash } = gallery;
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
<script>
|
|
@@ -39,8 +39,8 @@ const { title, description, metadata, sections, subGalleries, mediaBaseUrl, url
|
|
|
39
39
|
}
|
|
40
40
|
</script>
|
|
41
41
|
|
|
42
|
-
<MainLayout title={title} description={description} metadata={metadata} url={url}>
|
|
43
|
-
<Hero title={title} description={description} />
|
|
42
|
+
<MainLayout title={title} description={description} metadata={metadata} url={url} analyticsScript={analyticsScript} headerImage={headerImage}>
|
|
43
|
+
<Hero title={title} description={description} headerImage={headerImage} headerImageBlurHash={headerImageBlurHash} />
|
|
44
44
|
|
|
45
45
|
{
|
|
46
46
|
subGalleries && subGalleries.galleries.length > 0 && (
|
|
@@ -19,13 +19,12 @@ export const getRelativePath = (resourcePath: string) => {
|
|
|
19
19
|
/**
|
|
20
20
|
* Get the path to a photo that is always in the gallery root directory.
|
|
21
21
|
*
|
|
22
|
-
* @param
|
|
22
|
+
* @param filename - The filename to get the path for
|
|
23
|
+
* @param mediaBaseUrl - The base URL for the media
|
|
23
24
|
* @returns The normalized path relative to the gallery root directory
|
|
24
25
|
*/
|
|
25
|
-
export const getPhotoPath = (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return mediaBaseUrl ? `${mediaBaseUrl}/${resourceBasename}` : path.join('.', resourceBasename);
|
|
26
|
+
export const getPhotoPath = (filename: string, mediaBaseUrl?: string) => {
|
|
27
|
+
return mediaBaseUrl ? `${mediaBaseUrl}/${filename}` : filename;
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
/**
|