From 4174b5080931ee19008a011f4114972c8a677507 Mon Sep 17 00:00:00 2001 From: Adi Primanda Ginting Date: Sun, 14 Dec 2025 08:49:38 +0700 Subject: [PATCH 1/2] fix: improve stream --- app/components/sections/streaming/streaming.tsx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/components/sections/streaming/streaming.tsx b/app/components/sections/streaming/streaming.tsx index 97a8f91..068cde9 100644 --- a/app/components/sections/streaming/streaming.tsx +++ b/app/components/sections/streaming/streaming.tsx @@ -2,7 +2,7 @@ import type { Route } from ".react-router/types/app/routes/+types/streaming"; import MuxPlayer from "@mux/mux-player-react"; import { BadgeCheck } from "lucide-react"; import { useState } from "react"; -import { cn } from "~/lib/utils"; +import { cn, parseSpeakerImage } from "~/lib/utils"; export const StreamingSection = ({ componentProps, @@ -25,10 +25,6 @@ export const StreamingSection = ({ scheduleDetail.speaker?.user.facebook_username || scheduleDetail.speaker?.user.email; - console.log("Instagram ", scheduleDetail.speaker?.user.instagram_username); - console.log("Facebook ", scheduleDetail.speaker?.user.facebook_username); - console.log("Email ", scheduleDetail.speaker?.user.email); - return (
@@ -46,7 +42,7 @@ export const StreamingSection = ({ />
-

+

{scheduleDetail.title}

@@ -58,7 +54,7 @@ export const StreamingSection = ({ {scheduleDetail.speaker?.user ? (

placeholder @@ -86,14 +82,14 @@ export const StreamingSection = ({
-

+

{scheduleDetail.title}

{scheduleDetail.description ? (

100 && talkExpansion ? "line-clamp-3" : "", @@ -132,7 +128,7 @@ export const StreamingSection = ({ {scheduleDetail.speaker?.user ? (

placeholder From 1f3d7518c4e9b921a286b1c58df8d6c25d32d748 Mon Sep 17 00:00:00 2001 From: Adi Primanda Ginting Date: Sun, 14 Dec 2025 12:21:10 +0700 Subject: [PATCH 2/2] fix: improve stream --- .../sections/streaming/streaming.tsx | 68 +++++++++++++------ app/lib/utils.ts | 7 +- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/app/components/sections/streaming/streaming.tsx b/app/components/sections/streaming/streaming.tsx index 068cde9..1e8491f 100644 --- a/app/components/sections/streaming/streaming.tsx +++ b/app/components/sections/streaming/streaming.tsx @@ -1,7 +1,7 @@ import type { Route } from ".react-router/types/app/routes/+types/streaming"; import MuxPlayer from "@mux/mux-player-react"; import { BadgeCheck } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { cn, parseSpeakerImage } from "~/lib/utils"; export const StreamingSection = ({ @@ -11,6 +11,9 @@ export const StreamingSection = ({ }) => { const [talkExpansion, setTalkExpansion] = useState(true); const [speakerBioExpansion, setSpeakerBioExpansion] = useState(true); + const [speakerImageSrc, setSpeakerImageSrc] = useState( + "/images/default-avatar.webp", + ); const scheduleDetail = componentProps.loaderData.scheduleDetail; const scheduleStream = componentProps.loaderData.scheduleStream; @@ -25,6 +28,27 @@ export const StreamingSection = ({ scheduleDetail.speaker?.user.facebook_username || scheduleDetail.speaker?.user.email; + const first_name = scheduleDetail.speaker?.user.first_name; + const last_name = scheduleDetail.speaker?.user.last_name; + + useEffect(() => { + if (scheduleDetail.speaker?.id) { + const imageUrl = parseSpeakerImage({ id: scheduleDetail.speaker.id }); + const img = new Image(); + + img.onload = () => { + setSpeakerImageSrc(imageUrl); + }; + + img.onerror = () => { + console.log("Failed to load speaker image, using default avatar"); + setSpeakerImageSrc("/images/default-avatar.webp"); + }; + + img.src = imageUrl; + } + }, [scheduleDetail.speaker?.id]); + return (
@@ -54,16 +78,18 @@ export const StreamingSection = ({ {scheduleDetail.speaker?.user ? (
placeholder + />
-

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

-
- -
+

+ {`${first_name} ${last_name}`}{" "} + + + +

{scheduleDetail.speaker?.user.job_title && (

@@ -91,7 +117,7 @@ export const StreamingSection = ({ className={cn( "font-sans text-sm md:text-base leading-loose", scheduleDetail.description.length > 100 && talkExpansion - ? "line-clamp-3" + ? "line-clamp-2" : "", )} > @@ -109,13 +135,13 @@ export const StreamingSection = ({ ? "...show more" : "show less..."} -

- {talkExpansion && scheduleDetail.slide_link ? ( +

+ {!talkExpansion && scheduleDetail.slide_link ? ( - Access Presentation File + Access presentation file ) : null}

@@ -126,14 +152,14 @@ export const StreamingSection = ({
{scheduleDetail.speaker?.user ? ( -
+
placeholder + />
-

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

+

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

{scheduleDetail.speaker?.user.job_title ? (

{scheduleDetail.speaker?.user.job_title} at{" "} @@ -143,13 +169,15 @@ export const StreamingSection = ({ {speakerBio ? (

-

Bio

+

+ Bio +

100 && speakerBioExpansion - ? "line-clamp-3" + ? "line-clamp-2" : "", )} > diff --git a/app/lib/utils.ts b/app/lib/utils.ts index 1416b71..dfd7162 100644 --- a/app/lib/utils.ts +++ b/app/lib/utils.ts @@ -35,7 +35,12 @@ export const onAvatarError = ( evt: React.SyntheticEvent, ) => { const element = evt.target as HTMLImageElement; - element.onerror = () => null; + console.log("🔴 Image load failed:", element.src); + console.log("🔄 Setting fallback to:", "/images/default-avatar.webp"); + element.onerror = () => { + console.log("❌ Fallback image ALSO failed to load!"); + return null; + }; element.src = "/images/default-avatar.webp"; element.srcset = "/images/default-avatar.webp"; };