improve performance of market news page

This commit is contained in:
MuslemRahimi 2024-12-17 16:24:43 +01:00
parent 6b7fd0f679
commit f758411703
3 changed files with 190 additions and 149 deletions

View File

@ -5,7 +5,7 @@
export let data;
let rawData = data?.getData;
let news = rawData.slice(0, 15) ?? [];
let news = rawData.slice(0, 10) ?? [];
const formatDate = (dateString) => {
// Create a date object for the input dateString
@ -51,7 +51,6 @@
};
});
let videoId = null;
function checkIfYoutubeVideo(link) {
const url = new URL(link);
@ -67,6 +66,12 @@
return null;
}
}
// Track whether each video should be shown
let showVideo = {};
function handlePlayClick(index: number) {
showVideo = { ...showVideo, [index]: true };
}
</script>
<svelte:head>
@ -106,88 +111,97 @@
<main>
<div class="w-full m-auto">
<div class="grid grid-cols-1 gap-y-3">
{#if news.length !== 0}
{#each news as item}
<div class="w-full flex flex-col bg-[#09090B] m-auto">
{#if (videoId = checkIfYoutubeVideo(item?.url))}
<div class="w-full mb-4">
<h3 class="text-sm text-white/80 mb-2">
{formatDate(item?.publishedDate)} ago · {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
{#if news?.length !== 0}
{#each news as item, index}
<div class="w-full flex flex-col bg-[#09090B] rounded-md m-auto">
{#if checkIfYoutubeVideo(item.url)}
{#if showVideo[index]}
<!-- Show the YouTube iframe when the user clicks play -->
<div class="w-full aspect-video mb-4">
<iframe
class="w-full h-full rounded-md border border-gray-800"
src={`https://www.youtube.com/embed/${checkIfYoutubeVideo(item.url)}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<!-- Show the image placeholder with a play button -->
<div class="w-full aspect-video">
<div class="mb-3 sm:order-3 lg:pr-2">
<div
class="group relative block cursor-pointer bg-black bg-cover bg-[center_50%] object-contain after:block after:pb-[56.25%] after:content-[''] rounded-sm focus:outline-none focus:ring-2 focus:ring-blue-brand_light focus:ring-offset-2"
style="background-image: url({item?.image});"
tabindex="0"
on:click={() => handlePlayClick(index)}
>
{item?.title}
<p class="text-white text-sm font-normal">
{item?.text}
</p>
</a>
</div>
<div class="w-full aspect-video">
<iframe
class="w-full h-full"
src={`https://www.youtube.com/embed/${videoId}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-full w-full object-cover rounded"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} ago · {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
<div class=" mt-2 text-white">
<span>Stocks:</span>
<a
href={"/stocks/" + item?.symbol}
class="px-2.5 text-sm py-0.5 rounded-md bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-1"
>
{item?.symbol}
</a>
</div>
<div
class="absolute left-[50%] top-[50%] z-10 h-[46px] w-[70px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-[#212121] opacity-80 transition-all before:absolute before:left-[50%] before:top-[50%] before:-translate-x-1/2 before:-translate-y-1/2 before:border-y-[11px] before:border-l-[19px] before:border-r-0 before:border-transparent before:border-l-white before:content-[''] group-hover:bg-[#ff0000] group-hover:opacity-100"
></div>
</div>
</div>
{/if}
</div>
{/if}
<div class="mt-3 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
<hr class="border-gray-600 w-full m-auto mt-3 mb-5" />
{/each}
{:else}
<!-- Default news article display -->
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3 border border-gray-800 rounded-md"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-auto w-full rounded-md"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="mt-3 sm:mt-0 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
</div>
{/if}
</div>
<hr class="border-gray-600 w-full m-auto mt-5 mb-5" />
{/each}
{/if}
</div>
</div>

View File

@ -5,7 +5,7 @@
export let data;
let rawData = data?.getData;
let news = rawData.slice(0, 15) ?? [];
let news = rawData.slice(0, 10) ?? [];
const formatDate = (dateString) => {
// Create a date object for the input dateString
@ -51,7 +51,6 @@
};
});
let videoId = null;
function checkIfYoutubeVideo(link) {
const url = new URL(link);
@ -66,6 +65,12 @@
} else {
return null;
}
}
// Track whether each video should be shown
let showVideo = {};
function handlePlayClick(index: number) {
showVideo = { ...showVideo, [index]: true };
}
</script>
@ -112,76 +117,97 @@
<main>
<div class="w-full m-auto">
<div class="grid grid-cols-1 gap-y-3">
{#if news.length !== 0}
{#each news as item}
<div class="w-full flex flex-col bg-[#09090B] m-auto">
{#if (videoId = checkIfYoutubeVideo(item?.url))}
<div class="w-full mb-4">
<h3 class="text-sm text-white/80 mb-2">
{formatDate(item?.publishedDate)} ago · {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
{#if news?.length !== 0}
{#each news as item, index}
<div class="w-full flex flex-col bg-[#09090B] rounded-md m-auto">
{#if checkIfYoutubeVideo(item.url)}
{#if showVideo[index]}
<!-- Show the YouTube iframe when the user clicks play -->
<div class="w-full aspect-video mb-4">
<iframe
class="w-full h-full rounded-md border border-gray-800"
src={`https://www.youtube.com/embed/${checkIfYoutubeVideo(item.url)}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<!-- Show the image placeholder with a play button -->
<div class="w-full aspect-video">
<div class="mb-3 sm:order-3 lg:pr-2">
<div
class="group relative block cursor-pointer bg-black bg-cover bg-[center_50%] object-contain after:block after:pb-[56.25%] after:content-[''] rounded-sm focus:outline-none focus:ring-2 focus:ring-blue-brand_light focus:ring-offset-2"
style="background-image: url({item?.image});"
tabindex="0"
on:click={() => handlePlayClick(index)}
>
{item?.title}
<p class="text-white text-sm font-normal">
{item?.text}
</p>
</a>
</div>
<div class="w-full aspect-video">
<iframe
class="w-full h-full"
src={`https://www.youtube.com/embed/${videoId}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-auto w-full"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="w-full">
<h3 class="text-sm text-white/80 truncate mb-2 mt-3">
{formatDate(item?.publishedDate)} ago · {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
<div
class="absolute left-[50%] top-[50%] z-10 h-[46px] w-[70px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-[#212121] opacity-80 transition-all before:absolute before:left-[50%] before:top-[50%] before:-translate-x-1/2 before:-translate-y-1/2 before:border-y-[11px] before:border-l-[19px] before:border-r-0 before:border-transparent before:border-l-white before:content-[''] group-hover:bg-[#ff0000] group-hover:opacity-100"
></div>
</div>
</div>
{/if}
</div>
{/if}
<div class="mt-3 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
<hr class="border-gray-600 w-full m-auto mt-5 mb-5" />
{/each}
{:else}
<!-- Default news article display -->
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3 border border-gray-800 rounded-md"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-auto w-full rounded-md"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="mt-3 sm:mt-0 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
</div>
{/if}
</div>
<hr class="border-gray-600 w-full m-auto mt-5 mb-5" />
{/each}
{/if}
</div>
</div>
@ -189,3 +215,4 @@
</div>
</div>
</section>

View File

@ -5,7 +5,7 @@
export let data;
let rawData = data?.getData;
let news = rawData.slice(0, 15) ?? [];
let news = rawData.slice(0, 10) ?? [];
const formatDate = (dateString) => {
// Create a date object for the input dateString