Skip to content

Commit 3887d4e

Browse files
committed
issue #2: video playback sorted but audio playback's a headache
1 parent 3858a9a commit 3887d4e

File tree

2 files changed

+78
-15
lines changed

2 files changed

+78
-15
lines changed

nasa-lookup-cc/src/components/AssetDetail.css

+18-4
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,27 @@
2525

2626

2727
.asset-media {
28-
width: 100%; /* full width */
28+
width: 100%; /* full width */
29+
max-width: 600px;
2930
max-height: 500px; /* maintain aspect ratio */
3031
object-fit: cover;
3132
border-radius: 10px;
3233
margin-bottom: 20px;
3334
}
3435

36+
.asset-video {
37+
width: 100%;
38+
max-width: 600px;
39+
border-radius: 10px;
40+
}
41+
42+
.asset-audio {
43+
width: 100%;
44+
max-width: 400px;
45+
display: block;
46+
margin-top: 10px;
47+
}
48+
3549

3650
.back-button {
3751
display: inline-block;
@@ -48,7 +62,7 @@
4862
}
4963

5064
.back-button:hover {
51-
background-color: white;
52-
color: #007bff;
53-
border: 1px solid #007bff;
65+
background-color: white;
66+
color: #007bff;
67+
border: 1px solid #007bff;
5468
}

nasa-lookup-cc/src/components/AssetDetail.js

+60-11
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import "./AssetDetail.css";
55

66

77
// component to display details of a selected NASA asset
8-
// fetching asset dynamically, no need for {asset}
8+
// fetching asset dynamically via useParams
99
const AssetDetail = () => {
10-
// get asset ID from URL (url parameter)
10+
// get asset id from URL (url parameter - nasa_id: /asset/nasa_id)
1111
const { id } = useParams();
1212
const [asset, setAsset] = useState(null);
1313
const navigate = useNavigate();
1414
const location = useLocation();
15+
const [mediaUrl, setMediaUrl] = useState(""); // store media url
1516

1617
useEffect(() => {
1718
const fetchAsset = async () => {
@@ -20,6 +21,20 @@ const AssetDetail = () => {
2021
// set the first item found
2122
setAsset(response.data.collection.items[0]);
2223

24+
// fetch video/audio file URL
25+
const mediaResponse = await axios.get(`https://images-api.nasa.gov/asset/${id}`);
26+
const mediaItems = mediaResponse.data.collection.items;
27+
//console.log("Media Items:", mediaItems);
28+
29+
// find the first available MP4 (video) or MP3, m4a (audio) file
30+
const playback = mediaItems.find(item =>
31+
item.href.endsWith(".mp4") || item.href.endsWith(".mp3") || item.href.endsWith(".m4a")
32+
);
33+
34+
if (playback) {
35+
setMediaUrl(playback.href);
36+
}
37+
2338
} catch (error) {
2439
console.error("Error fetching asset details", error);
2540
}
@@ -32,26 +47,55 @@ const AssetDetail = () => {
3247
const queryParams = new URLSearchParams(location.search);
3348
const storedPage = queryParams.get("page") || localStorage.getItem("currentPage") || "1";
3449

35-
// debug storedPage
36-
//console.log(`Navigating back to page: ${storedPage}`);
37-
3850
const handleBack = () => {
3951
navigate(`/?page=${storedPage}`); // ,{replace: true}
4052
};
53+
// debug storedPage
54+
//console.log(`Navigating back to page: ${storedPage}`);
4155

4256
if (!asset) return <div className="asset-detail-container">Loading...</div>;
57+
const mediaType = asset.data?.[0]?.media_type || "unknown";
58+
59+
// limit description text
60+
const limTxt = (text, maxLength) => {
61+
if (!text) return "";
62+
return text.length > maxLength ? text.slice(0, maxLength) + " ..." : text;
63+
};
64+
4365

4466
return (
4567
<div className="asset-detail-container">
4668
{/* back button */}
4769
<button className="back-button" onClick={handleBack}> Back </button>
48-
<h3 className="asset-title">{asset.data[0].title}</h3> {/* display asset title */}
49-
<p className="asset-description">{asset.data[0].description}</p> {/* display asset description */}
70+
{/* display asset title, description */}
71+
<h3 className="asset-title">{asset.data[0].title}</h3>
72+
<p className="asset-description">{limTxt(asset.data[0].description, 1250)}</p>
5073

51-
{/* render image if asset contains media links */}
52-
{asset.links && (
53-
// image URL from API response & Alt text for accessibility
54-
<img src={asset.links[0].href} alt={asset.data[0].title} className="asset-media" />
74+
{/* render media based on type */}
75+
{asset.links && asset.links[0] && (
76+
<>
77+
{ mediaType === "image" && (
78+
<img src={asset.links[0].href} alt={asset.data[0].title} className="asset-media" />
79+
)}
80+
81+
{ mediaType === "video" && mediaUrl && (
82+
<video controls className="asset-video">
83+
<source src={mediaUrl} type="video/mp4" />
84+
It seems your browser does not support video elements
85+
</video>
86+
)}
87+
88+
{ mediaType === "audio" && mediaUrl && (
89+
<audio controls className="asset-audio">
90+
<source src={mediaUrl} type={mediaUrl.endsWith(".mp3") ? "audio/mpeg" : "audio/mp4"} />
91+
It seems your browser does not support audio elements
92+
</audio>
93+
)}
94+
95+
{!mediaUrl && (mediaType === "video" || mediaType === "audio") && (
96+
<p>Media file not available.</p>
97+
)}
98+
</>
5599
)}
56100
</div>
57101
);
@@ -63,6 +107,11 @@ export default AssetDetail;
63107

64108

65109

110+
// const {id} = useParams;
111+
/*
112+
extract url params from react router
113+
example URL /asset/56789 → id = "56789"
114+
*/
66115

67116

68117

0 commit comments

Comments
 (0)