So our Svelte Flicks app is looking in reasonably good shape.
We're just gonna add one final page before we call it a day, and that is
the individual movie page that we've been linking to all over over the place.
But haven't yet visited or implemented.
So, open source slash roots for the last time and
create a new root inside movies.
I'm gonna call it in square parameters id, that's gonna uniquely identify the movie.
And you'll notice that it's okay to have these two roots with dynamic parameters
in the same directory, because one of them has this matcher.
So the router knows that these two things are not going to conflict
it's going to try.
If we go to /movies/trending is going to try the view equals less parameter first.
And if that doesn't match, then it's gonna try the ID parameter.
Is one of the benefits of having a really sophisticated routing system.
So once more, we're gonna create
a page.ts not js and a page.svelte.
Inside our page.ts,
we're gonna add an async loading function.
We're gonna get the params object and we're gonna get fetch.
And we're gonna make, you guessed it an API call.
Const movie equals input array api helper.
Api.get, pass in our fetch.
The end point is gonna be, /movie
/params.id.
And we're gonna use that append to response trick that we used before to get
multiple request data in Mongo.
We're gonna get images,
videos and recommendations.
And just so that we can get the most value out of our client-side caching,
I'm gonna duplicate this Append to Response property on the homepage here.
This way if someone clicks from the hero image on the homepage,
then they're gonna get a cashout which is gonna be really nice.
This is a movie details object, so we'll add the as MovieDetails.
And on this page If we look at the one that's deployed online already,
I had JavaScript disable this whole time.
Okay, Reload that page.
So, on this page we have some information about the movie.
We also have a trailer which is being shown on the left there.
We wanna have that on the movie page that we're about to build.
In order to do that, we wanna get the trailer
object from the movie videos results.
And specifically, we want to have a video that is of type trailer and
is hosted at YouTube because we know how to embed those.
So we'll return, Video.official.
So it came from from the actual studio,
video.site = YouTube.
And the video.type is either
a trailer or A teaser.
And then, we're just gonna return all of that to our page load function.
From our page let function into our page.
So we will add a script tag.
Lang = ts export let data, and
it has the movie details in the trailer on that object.
The first thing we're gonna do is add another hero component,
Which is gonna take a movie object.
We'll create a div with a class of hero.
And we'll create a div class = backdrop for the for the backdrop image to go in.
And then below that, we'll have some info about the about the movie.
Right? We're gonna have the movie title first of
all.
Then we're gonna have a movie overview.
And let's add that component to our page,
pass in the movie object.
And take a look and see if it's appearing.
It's giving us a not found error.
And I think I know why, it's because this URL here is
saying /movie, instead of /movies.
So we need to figure out where that's coming from and fix it.
See this link here has /movie, just fix that.
We got another one here.
We'll fix that too.
And try that once more.
And it's giving us some information about
the movie 65 with Adam Driver.
As before, we can use the media helper to create this image.
Give it an alt attribute first.
That's gonna be the movie title.
And the source is media.
I'm gonna pass in the movie backdrop.
Actually, we're gonna need to figure out what backdrop to use first.
So like before, we're gonna grab
movie.images.backdrops.
Find the first backdrop that doesn't have a language, so
that we don't have any text.
Using this ISO 6391 property and if we can't find one of those
then we'll just fall back to whatever the first item in the array is.
All right, now that we've got that reference,
we can do backdrop file_path.
And we're gonna give it a width of 1280,
And you'll see it's rendering it,
although it's rendering it a little bit too large, so we'll add some styles.
This hero element, we're gonna give this a display of grid so
that we can have a mobile view and a desktop view.
Once we get above a certain
width we're gonna need to stop
that image from growing, so
we'll add a media query.
So we're gonna divide this into a grid that is stacked vertically on mobile and
horizontally on larger screens.
And this backdrop element, we're gonna put that in the right hand column.
At the moment because it's first in the Dom, it will be in the left hand column.
Which, if you look at the original is not the way that it works.
Over here it's positioned on the right.
So you can do the same thing by controlling
the rendering order distinct from the DOM order.
Display grid makes it really easy to do this sort of thing.
We can just add a grid column attribute, which positions it on the right hand side.
We need to put some maximum widths on these images.
Okay, and we can now see that it's behaving the way that we want it to.
It's not spilling out into the rest of the page beyond the window.
You have a question?
>> If two match functions have some similarities,
which one would take priority matching route params?
>> That's a really good question.
I'm actually not sure what happened in the situation where you have two dynamic
parameters with matches in the same route.
I think it would probably be alphabetical.
But I would have to go and check that.
I would guess alphabetical.
That's a great question.
All right, let's add some styles for the info block here.
I'm gonna move that window over so that we can see the page as we're editing it.
We'll begin by giving it some padding.
Looks a little bit nice already.
We'll make it a display flex element
with the flex direction of column.
And we're gonna give it a negative margin top.
This is gonna move the element over
the image which is gonna create a nice visual effect
And we're gonna get rid of the margin on the elements inside the info block.
And instead we're gonna have a gap in the flex element, it looks like this.
That happens to work out really nicely on this poster because it's dark
around the edges and the title of the movie is quite short.
But on some other posters like let's take Super Mario Brothers.
This is like super hard to read.
So, we're gonna add a little black gradient at the bottom
of the movie poster so that we can see that text.
The way that we're gonna do that is with a pseudo element.
We need to give it some content but this can just be the empty string.
I'm gonna fill the width and then give that a height of, let's say, 8 rems.
And we'll just do a black background for now,
check that we're doing things correctly.
We need to put that over to the left and
position it based on the bottom of the container element.
Okay, so we can now obviously read the textbook,
we're also obscuring a bunch of the poster.
So instead of having a black background,
we're gonna have a linear gradient that's gonna go to the top of the element.
It's gonna start black at the bottom and it's gonna end transparent at the top.
And now we have this nice fade so that we can see the poster,
but we can also read the information on top of it.
When we get bigger, we want to have the information on the left hand side instead.
So we're gonna add some more styles inside our media query.
Create a new Info Selector.
I'm gonna position it absolutely.
And we're gonna give it a width of 40 ems, which should be about right.
Gonna make it fill the available height.
And just like the backdrop has been moved to the right hand side with this
grid column rule, we're gonna do the same thing in reverse for
the info to move it onto the left hand side.
And we're gonna get rid of that negative margin that we were using before.
I wanna justify the content In the sensor.
So now when we look at this we can see that the headline and
the outline are going where we want them to.
But again it's kind of hard to read this text because we need to add
one of those nice gradients.
We can see the gradient is still being applied at the bottom of the poster
where we don't want it.
So we're gonna get rid of that and replace it with a horizontal gradient instead.
So that backdrop after pseudo animun, we'll give it a,
I'm gonna just drop that breakpoint down a bit so that we can see it.
Give it a width that isn't 100%, we'll use 15 rems.
Gonna make it fill the available height.
Move it all the way to the left and the bottom.
And this time the background is gonna be a linear gradient that goes to the right.
Again, from black to transparent.
Still a little bit hard to read, so I'm just gonna shove a drop shadow on there.
Drop shadow is sort of a get out of jail free card when you're trying to build
these sorts of user interfaces.
And you can have as many of these in sequence as you like if you need to up
the power like that, okay?
So we can see the poster, but we can also read the text.