update potus tracker

This commit is contained in:
MuslemRahimi 2025-02-27 00:07:09 +01:00
parent b3e96b68b2
commit 4c558fa4ac
2 changed files with 299 additions and 4 deletions

View File

@ -0,0 +1,131 @@
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import { browser } from "$app/environment";
import { v4 as uuidv4 } from "uuid";
let id = uuidv4();
export let src;
export let hideProgressbar = false;
let container; // container div reference
let video; // video element reference
let observer;
let progress = -1;
let isPlaying = false;
onMount(() => {
// Set up IntersectionObserver to auto-play/pause when in/out of view
if (browser) {
const handleIntersect = (entries) => {
entries.forEach((entry) => {
if (!entry?.isIntersecting) {
pauseVideo();
}
});
};
const options = { threshold: 0.4, rootMargin: "0px" };
observer = new IntersectionObserver(handleIntersect, options);
if (container) {
observer.observe(container);
}
}
});
function updateProgress() {
if (video && video.duration && !video.paused) {
progress = (video.currentTime / video.duration) * 100;
progress = parseFloat(progress.toFixed(2));
}
}
// Update progress on time update
$: {
if (video) {
video.ontimeupdate = updateProgress;
}
}
onDestroy(() => {
if (observer) {
observer.disconnect();
}
});
function playVideo() {
if (video) {
video.play();
video.muted = false;
isPlaying = true;
}
}
function pauseVideo() {
if (video) {
video.pause();
video.muted = true;
isPlaying = false;
}
}
function togglePlayback(event) {
// Prevent click event from bubbling to the container if needed
event.stopPropagation();
if (video.paused) {
playVideo();
} else {
pauseVideo();
}
}
</script>
<div class="video-container" bind:this={container} on:click={togglePlayback}>
<video
{id}
playsinline
loop
class="w-full max-w-96 rounded"
{src}
bind:this={video}
on:loadedmetadata={updateProgress}
></video>
<div class="play-pause-icon" on:click|stopPropagation={togglePlayback}>
{#if isPlaying}
<!-- Pause icon: two vertical bars -->
<svg viewBox="0 0 24 24">
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
</svg>
{:else}
<!-- Play icon: triangle -->
<svg viewBox="0 0 24 24">
<path d="M8 5v14l11-7z" />
</svg>
{/if}
</div>
</div>
<style>
.video-container {
position: relative;
display: inline-block;
}
.play-pause-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
z-index: 10;
/* Optional: style the icon's background and appearance */
background: rgba(0, 0, 0, 0.4);
border-radius: 50%;
padding: 0.5rem;
}
.play-pause-icon svg {
fill: white;
width: 50px;
height: 50px;
}
</style>

View File

@ -12,6 +12,7 @@
const updatedSectorList = ["S&P500", ...sectorList];
let rawData = data?.getData?.history || [];
let posts = data?.getData?.posts || [];
let executiveOrders = data?.getData?.executiveOrders || [];
let selectedSector = "S&P500";
const sectorDict = {
@ -35,14 +36,14 @@
month: "short",
year: "numeric",
timeZone: "UTC",
}).format(new Date(item.date));
}).format(new Date(item?.date));
if (!acc[dateKey]) acc[dateKey] = [];
acc[dateKey].push(item);
return acc;
}, {});
let groupedOrders = executiveOrders.reduce((acc, item) => {
let groupedOrders = executiveOrders?.reduce((acc, item) => {
const dateKey = new Intl.DateTimeFormat("en-US", {
day: "2-digit",
month: "short",
@ -62,6 +63,9 @@
{
title: "Executive Orders",
},
{
title: "Truth Social Post",
},
];
let activeIdx = 0;
@ -424,7 +428,7 @@
{/each}
</div>
</div>
{:else}
{:else if activeIdx === 1}
<h3
class="text-white text-lg sm:text-xl font-semibold mb-2 mt-6 border-y border-gray-800 pt-2 pb-2"
>
@ -483,7 +487,7 @@
</div>
</div>
<span class="text-sm ml-14 pt-2">
<span class="text-md ml-14 pt-2">
{#if item.description.length > 150}
{expandedDescriptions[item.title]
? item.description
@ -592,6 +596,166 @@
{/each}
</div>
</div>
{:else if activeIdx === 2}
<div
class="flex flex-row items-center mb-2 mt-6 border-y border-gray-800 pt-2 pb-2"
>
<svg
class="w-7 h-7 rounded-full inline-block"
fill="none"
viewBox="0 0 92 92"
xmlns="http://www.w3.org/2000/svg"
><path d="m0 .438202h91.56v91.56h-91.56z" fill="#5448ee" /><g
fill="#fff"
><path d="m67.9385 54.0751h-11.5057v9.3631h11.5057z" /><path
d="m63.4377 37.8944v-9.4562h-23.4446v34.9084h11.9665v-25.4522z"
/><path d="m24 28.4382h11.4878v9.4539h-11.4878z" /></g
></svg
>
<h3 class="ml-2 text-white text-lg sm:text-xl font-semibold">
Truth Social Posts
</h3>
</div>
<div
class="max-h-[600px] overflow-y-auto border border-gray-800 rounded-md p-4 no-scrollbar"
>
<div class="space-y-4">
{#each posts as item}
<div class="my-4">
<div
class="flex flex-col items-start space-y-1 mb-6 border-b border-gray-800 pb-4"
>
<div class="flex items-start space-x-3">
<a
rel="noopener noreferrer"
target="_blank"
href="https://truthsocial.com/@realDonaldTrump"
class="avatar w-10 h-10 rounded-full flex-shrink-0"
>
<img
class="rounded-full"
src={avatar}
alt="Avatar"
loading="lazy"
/></a
>
<div class="flex flex-col items-start w-full">
<h3 class="text-white font-semibold">
<a
rel="noopener noreferrer"
target="_blank"
href="https://truthsocial.com/@realDonaldTrump"
class="sm:hover:text-blue-400"
>Donald J. Trump</a
>
</h3>
<h4 class="text-sm text-gray-400">
<a
rel="noopener noreferrer"
target="_blank"
href="https://truthsocial.com/@realDonaldTrump"
class="sm:hover:text-blue-400"
>@realDonaldTrump</a
>
&#183; {item?.date}
</h4>
</div>
</div>
<span class="text-md ml-12">
{item?.content}
</span>
<a
href={item?.source}
rel="noopener noreferrer"
target="_blank"
class="ml-12 pt-5 inline-block text-sm text-white sm:hover:underline"
>
Original Post
<svg
class="w-4 h-4 sm:w-5 sm:h-5 -mt-0.5 inline-block"
fill="#fff"
viewBox="0 0 64 64"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
xmlns:serif="http://www.serif.com/"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<rect
id="Icons"
x="-896"
y="0"
width="1280"
height="800"
style="fill:none;"
></rect>
<g id="Icons1" serif:id="Icons">
<g id="Strike"> </g> <g id="H1"> </g>
<g id="H2"> </g> <g id="H3"> </g>
<g id="list-ul"> </g>
<g id="hamburger-1"> </g>
<g id="hamburger-2"> </g>
<g id="list-ol"> </g>
<g id="list-task"> </g> <g id="trash"> </g>
<g id="vertical-menu"> </g>
<g id="horizontal-menu"> </g>
<g id="sidebar-2"> </g> <g id="Pen"> </g>
<g id="Pen1" serif:id="Pen"> </g>
<g id="clock"> </g>
<g id="external-link">
<path
d="M36.026,20.058l-21.092,0c-1.65,0 -2.989,1.339 -2.989,2.989l0,25.964c0,1.65 1.339,2.989 2.989,2.989l26.024,0c1.65,0 2.989,-1.339 2.989,-2.989l0,-20.953l3.999,0l0,21.948c0,3.308 -2.686,5.994 -5.995,5.995l-28.01,0c-3.309,0 -5.995,-2.687 -5.995,-5.995l0,-27.954c0,-3.309 2.686,-5.995 5.995,-5.995l22.085,0l0,4.001Z"
></path>
<path
d="M55.925,25.32l-4.005,0l0,-10.481l-27.894,27.893l-2.832,-2.832l27.895,-27.895l-10.484,0l0,-4.005l17.318,0l0.002,0.001l0,17.319Z"
></path>
</g> <g id="hr"> </g> <g id="info"> </g>
<g id="warning"> </g>
<g id="plus-circle"> </g>
<g id="minus-circle"> </g> <g id="vue"> </g>
<g id="cog"> </g> <g id="logo"> </g>
<g id="radio-check"> </g>
<g id="eye-slash"> </g> <g id="eye"> </g>
<g id="toggle-off"> </g>
<g id="shredder"> </g>
<g
id="spinner--loading--dots-"
serif:id="spinner [loading, dots]"
>
</g> <g id="react"> </g>
<g id="check-selected"> </g>
<g id="turn-off"> </g>
<g id="code-block"> </g>
<g id="user"> </g> <g id="coffee-bean"> </g>
<g id="coffee-beans">
<g id="coffee-bean1" serif:id="coffee-bean">
</g>
</g> <g id="coffee-bean-filled"> </g>
<g id="coffee-beans-filled">
<g id="coffee-bean2" serif:id="coffee-bean">
</g>
</g> <g id="clipboard"> </g>
<g id="clipboard-paste"> </g>
<g id="clipboard-copy"> </g>
<g id="Layer1"> </g>
</g>
</g></svg
>
</a>
</div>
</div>
{/each}
</div>
</div>
{/if}
</div>