core-maugli 1.2.23 → 1.2.25
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
CHANGED
@@ -137,17 +137,17 @@ let defaultAuthorName = defaultAuthor.data.name;
|
|
137
137
|
<meta http-equiv="x-ua-compatible" content="ie=edge" />
|
138
138
|
|
139
139
|
<!-- Font Loading Strategy - Non-blocking -->
|
140
|
-
<link
|
141
|
-
rel="preload"
|
142
|
-
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
|
143
|
-
as="style"
|
144
|
-
onload="this.onload=null;this.rel='stylesheet'"
|
140
|
+
<link
|
141
|
+
rel="preload"
|
142
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
|
143
|
+
as="style"
|
144
|
+
onload="this.onload=null;this.rel='stylesheet'"
|
145
145
|
/>
|
146
|
-
<link
|
147
|
-
rel="preload"
|
148
|
-
href="https://fonts.googleapis.com/css2?family=Geologica:wght@400;500;600&display=swap"
|
149
|
-
as="style"
|
150
|
-
onload="this.onload=null;this.rel='stylesheet'"
|
146
|
+
<link
|
147
|
+
rel="preload"
|
148
|
+
href="https://fonts.googleapis.com/css2?family=Geologica:wght@400;500;600&display=swap"
|
149
|
+
as="style"
|
150
|
+
onload="this.onload=null;this.rel='stylesheet'"
|
151
151
|
/>
|
152
152
|
<noscript>
|
153
153
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" />
|
@@ -1,7 +1,6 @@
|
|
1
1
|
---
|
2
2
|
import { maugliConfig } from '../config/maugli.config';
|
3
3
|
import FormattedDate from './FormattedDate.astro';
|
4
|
-
import ResponsiveImage from './ResponsiveImage.astro';
|
5
4
|
|
6
5
|
type Props = {
|
7
6
|
href: string;
|
@@ -21,10 +20,20 @@ const { href, title, image, seo, publishDate, excerpt, description, headingLevel
|
|
21
20
|
|
22
21
|
const TitleTag = headingLevel;
|
23
22
|
|
23
|
+
// Отладка: проверяем, что именно приходит в image
|
24
|
+
console.log('Card.astro DEBUG:', {
|
25
|
+
type: typeof image,
|
26
|
+
value: image,
|
27
|
+
src: image?.src,
|
28
|
+
isObject: typeof image === 'object',
|
29
|
+
isString: typeof image === 'string'
|
30
|
+
});
|
31
|
+
|
24
32
|
// Определяем базовое изображение для карточки
|
25
|
-
|
33
|
+
// Убеждаемся, что получаем только строку пути, а не объект asset
|
34
|
+
let baseImage =
|
26
35
|
seo?.image?.src ||
|
27
|
-
(image && typeof image
|
36
|
+
(image && typeof image === 'object' && image.src ? image.src : image && typeof image === 'string' ? image : undefined) ||
|
28
37
|
(type === 'blog'
|
29
38
|
? maugliConfig.defaultBlogImage
|
30
39
|
: type === 'project'
|
@@ -33,7 +42,19 @@ const baseImage =
|
|
33
42
|
? maugliConfig.defaultProductImage
|
34
43
|
: maugliConfig.seo.defaultImage);
|
35
44
|
|
36
|
-
|
45
|
+
// Убеждаемся, что baseImage - это строка, а не asset объект
|
46
|
+
if (baseImage && typeof baseImage === 'object' && baseImage.src) {
|
47
|
+
baseImage = baseImage.src;
|
48
|
+
}
|
49
|
+
|
50
|
+
// Убираем ведущий слэш, чтобы избежать обработки через asset pipeline
|
51
|
+
if (baseImage && baseImage.startsWith('/')) {
|
52
|
+
baseImage = baseImage.substring(1);
|
53
|
+
}
|
54
|
+
|
55
|
+
console.log('Card.astro baseImage:', baseImage);
|
56
|
+
|
57
|
+
const cardImageAlt = seo?.image?.alt || (image && typeof image === 'object' ? image.alt : undefined) || title || 'Изображение';
|
37
58
|
|
38
59
|
// Определяем контент для отображения
|
39
60
|
const content = excerpt || description;
|
@@ -49,16 +70,13 @@ const content = excerpt || description;
|
|
49
70
|
<a href={href} class="block w-full h-full">
|
50
71
|
<!-- Изображение -->
|
51
72
|
<div class="w-full aspect-[1200/630] bg-[var(--bg-muted)] overflow-hidden relative">
|
52
|
-
<
|
73
|
+
<img
|
53
74
|
src={baseImage}
|
54
75
|
alt={cardImageAlt}
|
55
|
-
width={1200}
|
56
|
-
height={630}
|
57
76
|
loading="lazy"
|
77
|
+
width="1200"
|
78
|
+
height="630"
|
58
79
|
class="w-full h-full object-cover rounded-custom transition-transform duration-300 group-hover:scale-105"
|
59
|
-
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 400px"
|
60
|
-
quality={75}
|
61
|
-
format="webp"
|
62
80
|
/>
|
63
81
|
|
64
82
|
<!-- Звездочка featured в правом верхнем углу -->
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import { maugliConfig } from '../config/maugli.config';
|
3
3
|
import { LANGUAGES } from '../i18n/languages';
|
4
4
|
import AuthorLinksGroup from './AuthorLinksGroup.astro';
|
5
|
-
import OptimizedImage from './OptimizedImage.astro';
|
6
5
|
// Универсальный импорт словарей по доступным языкам
|
7
6
|
const dicts: Record<string, any> = {};
|
8
7
|
for (const lang of LANGUAGES) {
|
@@ -12,34 +12,20 @@ export interface Props {
|
|
12
12
|
quality?: number;
|
13
13
|
}
|
14
14
|
|
15
|
-
const {
|
16
|
-
src,
|
17
|
-
alt,
|
18
|
-
width,
|
19
|
-
height,
|
20
|
-
class: className = '',
|
21
|
-
loading = 'lazy',
|
22
|
-
decoding = 'async',
|
23
|
-
sizes,
|
24
|
-
priority = false,
|
25
|
-
quality = 75,
|
26
|
-
...rest
|
27
|
-
} = Astro.props;
|
15
|
+
const { src, alt, width, height, class: className = '', loading = 'lazy', decoding = 'async', sizes, priority = false, quality = 75, ...rest } = Astro.props;
|
28
16
|
|
29
17
|
// Generate responsive image variations with quality optimization
|
30
18
|
const generateSrcSet = (baseSrc: string) => {
|
31
19
|
const baseUrl = baseSrc.replace(/\.[^.]+$/, '');
|
32
20
|
const ext = 'webp'; // Always use WebP for better compression
|
33
|
-
|
21
|
+
|
34
22
|
const variations = [
|
35
23
|
{ width: 400, suffix: '-400' },
|
36
24
|
{ width: 800, suffix: '-800' },
|
37
25
|
{ width: 1200, suffix: '-1200' }
|
38
26
|
];
|
39
|
-
|
40
|
-
return variations
|
41
|
-
.map(({ width, suffix }) => `${baseUrl}${suffix}.${ext} ${width}w`)
|
42
|
-
.join(', ');
|
27
|
+
|
28
|
+
return variations.map(({ width, suffix }) => `${baseUrl}${suffix}.${ext} ${width}w`).join(', ');
|
43
29
|
};
|
44
30
|
|
45
31
|
const srcSet = generateSrcSet(src);
|
@@ -62,6 +48,4 @@ const shouldPreload = priority && loading === 'eager';
|
|
62
48
|
{...rest}
|
63
49
|
/>
|
64
50
|
|
65
|
-
{priority &&
|
66
|
-
<link rel="preload" as="image" href={src} type="image/webp" />
|
67
|
-
)}
|
51
|
+
{priority && <link rel="preload" as="image" href={src} type="image/webp" />}
|
@@ -26,59 +26,21 @@ const {
|
|
26
26
|
...rest
|
27
27
|
} = Astro.props;
|
28
28
|
|
29
|
-
//
|
30
|
-
const
|
31
|
-
// Если это внешний URL, возвращаем как есть
|
32
|
-
if (baseSrc.startsWith('http')) {
|
33
|
-
return baseSrc;
|
34
|
-
}
|
35
|
-
|
36
|
-
// Для карточек проверяем наличие preview версии
|
37
|
-
const previewSrc = baseSrc.replace(/\/([^\/]+)$/, '/previews/$1');
|
38
|
-
|
39
|
-
// Возвращаем базовое изображение (preview будет проверен в build time)
|
40
|
-
return baseSrc;
|
41
|
-
};
|
42
|
-
|
43
|
-
const optimizedSrc = generateImageURL(src, width, quality, format);
|
29
|
+
// Простая стратегия - используем базовое изображение и не генерируем srcset для несуществующих файлов
|
30
|
+
const optimizedSrc = src;
|
44
31
|
|
45
|
-
// Генерируем srcset
|
32
|
+
// Генерируем srcset только если есть базовое изображение
|
46
33
|
const generateSrcSet = (baseSrc: string) => {
|
47
34
|
if (baseSrc.startsWith('http')) {
|
48
35
|
return baseSrc;
|
49
36
|
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
// Используем существующие responsive варианты
|
55
|
-
const variants = [
|
56
|
-
{ width: 400, suffix: '-400' },
|
57
|
-
{ width: 800, suffix: '-800' },
|
58
|
-
{ width: 1200, suffix: '-1200' }
|
59
|
-
];
|
60
|
-
|
61
|
-
const srcsetItems = variants
|
62
|
-
.map(({ width, suffix }) => `${baseUrl}${suffix}${ext} ${width}w`);
|
63
|
-
|
64
|
-
// Добавляем оригинал как fallback
|
65
|
-
srcsetItems.push(`${baseSrc} 1200w`);
|
66
|
-
|
67
|
-
return srcsetItems.join(', ');
|
37
|
+
|
38
|
+
// Возвращаем только базовое изображение без попыток создания srcset
|
39
|
+
// Responsive варианты будут обработаны build процессом
|
40
|
+
return baseSrc;
|
68
41
|
};
|
69
42
|
|
70
43
|
const srcSet = generateSrcSet(src);
|
71
44
|
---
|
72
45
|
|
73
|
-
<img
|
74
|
-
src={optimizedSrc}
|
75
|
-
srcset={srcSet}
|
76
|
-
alt={alt}
|
77
|
-
width={width}
|
78
|
-
height={height}
|
79
|
-
class={className}
|
80
|
-
loading={loading}
|
81
|
-
decoding={decoding}
|
82
|
-
sizes={sizes}
|
83
|
-
{...rest}
|
84
|
-
/>
|
46
|
+
<img src={optimizedSrc} alt={alt} width={width} height={height} class={className} loading={loading} decoding={decoding} sizes={sizes} {...rest} />
|