Подсветка свежих или недавно обновлённых постов
This commit is contained in:
parent
3c55a37ed8
commit
2e99b04261
2 changed files with 59 additions and 15 deletions
|
|
@ -7,13 +7,21 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Icon from '@iconify/svelte';
|
import { BLOG_POST_FRESHNESS_MILLIS } from '$lib/util/Blogs';
|
||||||
|
import DateWidget from '$lib/components/DateWidget.svelte';
|
||||||
|
|
||||||
export let post: App.BlogPost;
|
export let post: App.BlogPost;
|
||||||
export let size: BlogCardSize = BlogCardSize.Both;
|
export let size: BlogCardSize = BlogCardSize.Both;
|
||||||
|
|
||||||
|
const dateNow = new Date().valueOf();
|
||||||
|
const isPostNew = dateNow - new Date(post.date!).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
|
||||||
|
const isPostUpdated =
|
||||||
|
post.dateChanged != null &&
|
||||||
|
dateNow - new Date(post.dateChanged).valueOf() <= BLOG_POST_FRESHNESS_MILLIS;
|
||||||
|
const isPostFresh = isPostNew || isPostUpdated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rndtrash: пришлось дублировать классы с модификатором и без, потому что Tailwind ОЧЕНЬ не любит,
|
* rndtrash: пришлось дублировать классы с модификатором и без, потому что Tailwind просто не понимает,
|
||||||
* когда его классы склеивают из нескольких частей
|
* когда его классы склеивают из нескольких частей
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -34,15 +42,18 @@
|
||||||
*
|
*
|
||||||
* Возвращает пустую строку, если плашка может быть только полноразмерной
|
* Возвращает пустую строку, если плашка может быть только полноразмерной
|
||||||
* @param classes
|
* @param classes
|
||||||
|
* @param modClasses
|
||||||
*/
|
*/
|
||||||
function shortClass(classes: string): string {
|
function shortClass(classes: string, modClasses?: string): string {
|
||||||
return size === BlogCardSize.Long ? '' : classes;
|
if (size === BlogCardSize.Long) return '';
|
||||||
|
return size === BlogCardSize.Both && modClasses ? modClasses : classes;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/blog/{post.slug}"
|
href="/blog/{post.slug}"
|
||||||
class="blog-card
|
class="blog-card
|
||||||
|
{isPostUpdated ? 'updated' : isPostNew ? 'new' : ''}
|
||||||
{shortClass('flex-col justify-baseline')}
|
{shortClass('flex-col justify-baseline')}
|
||||||
{fullClass('flex-row justify-stretch', 'sm:flex-row sm:justify-stretch')}"
|
{fullClass('flex-row justify-stretch', 'sm:flex-row sm:justify-stretch')}"
|
||||||
>
|
>
|
||||||
|
|
@ -58,19 +69,31 @@
|
||||||
alt={post.thumbnailAlt ?? 'Миниатюра поста'}
|
alt={post.thumbnailAlt ?? 'Миниатюра поста'}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if isPostFresh}
|
||||||
|
<div class="toast {fullClass('hidden', 'sm:hidden')}">
|
||||||
|
{#if isPostUpdated}
|
||||||
|
ОБНОВЛЕНО
|
||||||
|
{:else}
|
||||||
|
НОВОЕ
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full flex-col justify-center p-4 break-words md:p-8">
|
<div class="flex w-full flex-col justify-center p-4 break-words md:p-8">
|
||||||
<div class="flex flex-row flex-wrap justify-between gap-4 pb-4">
|
<div class="flex flex-row flex-wrap justify-start gap-4 pb-2">
|
||||||
<div class="flex items-center text-lg font-bold">
|
<DateWidget
|
||||||
<Icon icon="material-symbols:calendar-today" class="mr-3" width={24} height={24} />
|
class={post.dateChanged ? shortClass('hidden', 'not-sm:hidden') : ''}
|
||||||
<p>
|
dateString={post.date}
|
||||||
{new Date(post.date!).toLocaleString('default', {
|
type="published"
|
||||||
month: 'short',
|
highlight={isPostNew && !isPostUpdated}
|
||||||
day: 'numeric',
|
/>
|
||||||
year: 'numeric'
|
{#if post.dateChanged}
|
||||||
})}
|
<DateWidget
|
||||||
</p>
|
dateString={post.dateChanged}
|
||||||
</div>
|
type="updated"
|
||||||
|
highlight={isPostUpdated}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="text-3xl font-bold">{post.title}</h2>
|
<h2 class="text-3xl font-bold">{post.title}</h2>
|
||||||
|
|
@ -87,6 +110,26 @@
|
||||||
.blog-card {
|
.blog-card {
|
||||||
@apply flex w-full max-w-5xl overflow-hidden rounded-lg bg-slate-100 text-slate-950 drop-shadow-xl transition-all hover:drop-shadow-2xl;
|
@apply flex w-full max-w-5xl overflow-hidden rounded-lg bg-slate-100 text-slate-950 drop-shadow-xl transition-all hover:drop-shadow-2xl;
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
@apply absolute top-0 right-0 rounded-bl-lg p-2 font-bold text-slate-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.updated {
|
||||||
|
box-shadow: 0 0 0 4px var(--color-purple-600);
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
@apply bg-purple-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.new {
|
||||||
|
box-shadow: 0 0 0 4px var(--color-amber-600);
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
@apply bg-amber-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img.thumbnail {
|
img.thumbnail {
|
||||||
@apply absolute h-full w-full object-cover transition-transform;
|
@apply absolute h-full w-full object-cover transition-transform;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
||||||
|
export const BLOG_POST_FRESHNESS_MILLIS = 3 * 24 * 60 * 60 * 1000; // 3 дня
|
||||||
|
|
||||||
export type PostComparer = (a: App.BlogPost, b: App.BlogPost) => number;
|
export type PostComparer = (a: App.BlogPost, b: App.BlogPost) => number;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue