Review Profile View0:00
It's been a long time coming, but we can finally start to implementing our ProfileController. Before we do anything, I think it's important to look at the profile view and just make some mental notes because now that we have data, you know, it shouldn't change things, but it does. Now that we have data, we need to think in terms of how are we going to display this data, which we already have that done, we have extracted the view.
how are we going to display this data, which we already have that done, we have extracted the view. We of course will need to make some modifications, but the first thing that sticks out in my mind is that we didn't take into account the coverUrl or the coverImage. I say we, it's me. Uh, so we need to add that to our migration. We also need to modify our factory to take that into account.
We also need to modify our factory to take that into account. So that's going to be fine. Uh, so for whenever we load the profile, we need the counts for the followings and the followers and then we want to display our posts. But you know, looking at this, if we go to any social media platform and you look at the profile itself, you are just going
to any social media platform and you look at the profile itself, you are just going to see the top level posts. You're not gonna see replies, you will see reposts and you will see quote reposts. But, but that's it. So I'm gonna make a, an executive decision that we are going to modify the profile so that it will, you know, work like any other platform so that we see the top level posts
Add Cover URL Data1:32
work like any other platform so that we see the top level Posts and we won't see any reply forms or replies or anything like that. So let's get started. The first thing we need is of course the createProfile migration because we need to include the cover URL here. So let's do that. But we also want to modify the ProfileFactory
So let's do that. But we also want to modify the ProfileFactory because not only do we need to add the coverUrl here, but we also need to change this because I wasn't aware primarily because I haven't used it in a long time. But the URL that faker generates for these images no longer works. The domain hasn't been active well for at least two years as I'm recording this.
The domain hasn't been active well for at least two years as I'm recording this. So we need a different solution. And I have one, there is a website called dummyimage.com and all we have to do is supply the dimensions, which is the first segment of the URL. The second segment is the background color of the image. So this will be a little gray. And then finally we have the text color.
So this will be a little gray. And then finally we have the text color or the foreground color, which is gonna be black in the case of our avatar. But then we need the cover URL. And I would like the avatar URL to be a a little unique, but I don't really necessarily know how we can do that. But for the cover URL, we absolutely could. Now the dimensions are a little bit different. It's 1400 by 640.
Now the dimensions are a little bit different. It's 1400 by 640. And then for the background color we'll use a darker gray. And then for the foreground we will use the orange color that's used throughout the pixel application. But as I said, I want this to be a little unique and by setting the text query parameter to the handle, well you don't get really any more unique than that. So we are going to create our handle, which is of course going to be the username so that we can use
So we are going to create our handle, which is of course going to be the username so that we can use that handle variable wherever we need it. And that is going to give us our cover URL. So now we just need to change our database. So let's migrate fresh and seed. It's gonna wipe out the database, rerun our migrations and reseed the database. Everything should be fine because there weren't any syntax errors or anything there.
Create ProfileController Route3:52
Everything should be fine because there weren't any syntax errors or anything there. So sure enough, we are good to go as far as that is concerned. And really the first thing that I want to do now is to make a controller called ProfileController. And we need to uh, open up our routes/web.php file because we need to add a route for this new controller. And this is not gonna be a resource controller because there are some very specific things that well,
And this is not gonna be a resource controller because there are some very specific things that well, that we need to do with a Profile. It's not just a typical create read, update and delete. So our route is of course going to be a GET request and the first segment is gonna be for the profile. It's going to be the handle. And we want to map that to our ProfileController. And we are going to use the show method to show the profile.
And we are going to use the show method to show the profile. Let's give this name of profiles.show and that's gonna be that as far as our route is concerned, let's open up the ProfileController and let's do this. The first thing I want to do is just return a view, but I want to think about this because if we look at our views, let's go down to our resources.
because if we look at our views, let's go down to our resources. Okay, so we have our views, we have our components, and then we have partials. And then of course we have the feed and the profile and the things that we extracted before. But now that we have data to work with, I want to start organizing this into well real organization. And why don't we have two profile views. Oh no, it doesn't matter. So what we are going
And why don't we have two profile views. Oh no, it doesn't matter. So what we are going to do is add another folder for the profile stuff. So let's create a new file inside of profiles and we'll call this show.blade.php. And it's going to start with the profile view that we created many, many episodes ago. And all we are going to do for now is return profiles.show. And this isn't going to work.
And all we are going to do for now is return profiles.show. And this isn't going to work because that's wrong to begin with. public function show where we get the profile and the profile and then we can return something. Uh, we of course need to include profile there. Let's go ahead and let's also include post, because we are going to need to pull our posts to pass to our view. But for right now we need a profile
to pass to our view. But for right now we need a profile that we can actually look at. And this camera 54, that's easy enough so that inside of the browser, well I broke something, but let's duplicate that so that we can go to /tamara54, we get an error saying that undefined variable feedItems. So that's good. We want to see this because that means that the route is correctly being hit.
So that's good. We want to see this because that means that the route is correctly being hit and we are returning the view without providing any feed items. So we're good there. But why did profile break? So the only thing I can think of is I did something inside of our routes file, but we have profile there. So let's take that routes definition, let's place it at the bottom and then that should fix that so that
let's place it at the bottom and then that should fix that so that whenever we go to profile, yes, because I want to be able to go back to this and refer to it as we need it. And still, Tamara 54 doesn't work because we don't have feed items, okay? So we need to supply two things. We need the profile because we need to supply all of the profile things as well.
Load Profile Posts7:29
We need the profile because we need to supply all of the profile things as well as the following and follower counts. And then the posts. So we have two things that we need to supply in our ProfileController, but before we do that, let's go to the AppServiceProvider because inside of the boot method, I want to call model automatically eager load relationships. That's gonna save us a little bit of typing.
to call model automatically eager load relationships. That's gonna save us a little bit of typing. So first thing, we want to load our count for the followings and the followers. That way we can actually display that information. But then we want our posts. And our posts is going to be where the profile_id is this profiles. But we only want the top level posts. We don't want any replies, so
But we only want the top level Posts. We don't want any replies, so where null parentId. But we do want the reposts and not only do we want the reposts, we also want the counts for those reposts, meaning the likes, the replies, the reposts, things like that. So we will have our repost of, then we will have a closure to where we work with the query builder so that we will load with count
a closure to where we work with the query builder so that we will load with count and we want the likes, the reposts, and then finally what the replies. But that's just for the reposts, that isn't for all of our other posts. So we, we kind of need to do that again with count, let's just copy paste. And if we keep having to do that, we might come up with a an easier and
And if we keep having to do that, we might come up with a an easier and and more descriptive way of doing that just so that we don't have to type that a lot. Then we want the latest Posts and then we just want to get them so that we have our posts, we have our profile and we are going to supply those to our view. Now I know that inside of the view we used the terminology of feed items, but that was
Now I know that inside of the view we used the terminology of feed items, but that was before we had our models and things like that. So let's change the vernacular. We are not working with feed items, we are working with posts. So we're going to supply the profile and posts and that's gonna be an easy enough thing to change. So with that in place, we should be able to go to our show view.
So with that in place, we should be able to go to our show view. And right here where we had the feed items, let's go ahead and change that to posts that should make it so that we can actually see something inside of the browser. We do great, we and we even see our posts, but of course there are the reply forms, which I want to get rid of one thing at a time. Let's start at the very top. Let's get this profile stuff done first so
Render Profile Details10:10
Let's start at the very top. Let's get this profile stuff done first so that at the very top, uh, let's see, where do we have the cover image right there? So we are going to output the profileCoverUrl, and let's just copy this because we are going to need to do that in several places, like for right here, but not the cover. We want the avatar, but then we need the displayName here.
We want the avatar, but then we need the displayName here. So let's use that. And we're gonna need the displayName in a couple of other places like right here. And then we also want to output the handle. So let's do this to where we will output not the displayName but the handle. And then we just need to output the counts. So if we scroll on down, here's the following.
And then we just need to output the following count. So if we scroll on down, here's the following count and then we want the followers count. So that should get the top stuff done. And sure enough we can see our cover art. We have our avatar, we have the name or the display name of the profile as well as the handle. Oh, we do need the bio though, but we can see that the following
Oh, we do need the bio though, but we can see that the following and the followers are being, I'm not gonna say that they're accurate because we have to go to the database to actually check if they're accurate, but I'm pretty sure they're accurate. So, uh, as far as the bio, we need to output the bio and that is that. So that now we just need to focus on outputting the individual posts, which you know,
Build Profile Post Partial11:42
So that now we just need to focus on outputting the individual Posts, which you know, if we take a look at that, we are using this partials.feedItem. Now the feedItem was made to be not as generic as possible, but I wanted to avoid duplication because Posts are something that are going to be used throughout the application. And you know, the less times that we have to duplicate Posts and that markup, then the less times we
And you know, the less times that we have to duplicate posts and that markup, then the less times we have to go back and make changes. You know, but there is that saying that, you know, premature optimization is the root of all evil. And you know, what do we do? Do we duplicate or do we pre optimize? So I guess let's duplicate for now so that what what we will do is have something like this so that we can start to expand our partials
what we will do is have something like this so that we can start to expand our partials and we'll have our partials, but then we will have partials specifically for the profile and we could just have a partial that's called post for the profile right now. I think that's the best to do. So let's create a new file inside of partials. The folder is going to be profile and it will be post.blade.php.
The folder is going to be profile and it will be post.blade.php. And it is essentially going to be the feed item partial that we created. But we are going to make some changes specific for the profile. And that is to one, uh, get rid of the threaded replies because we don't want to see any replies. The next thing is to get rid of the reply form. And there it is right there.
The next thing is to get rid of the reply form. And there it is right there. I just blew past it. Uh, let's collapse this so that I know I am deleting the correct opening and closing div elements. There we go. So now if we take a look that that's a lot cleaner, we don't have all of those reply forms and we aren't going to see any replies, but now there are some weird looking things, at least they look weird. But if we think about it, we know what the problem is.
at least they look weird. But if we think about it, we know what the problem is. Like this right here, there is no content and that's because this is just a normal repost. We aren't showing a normal repost. So that's one thing that we need to be concerned with. And then here we have just content of great post and we know that that is a quote repost. So we need to display the quoted repost here. So, and of course we have the, the counts that we have
So we need to display the quoted repost here. So, and of course we have the, the counts that we have to display for the likes and the comments and things like that. So let's start with the latter with the counts because I think that's gonna be the easiest thing to get implemented. So the hard part now is to find where those dadgum things are. And here it is right here. item.reposts_count.
where those dadgum things are. And here it is right here. itemRepostsCount. It is plural. Alright, so with that in place, we should be able to just scroll on up until we find the replyCount, which this will be repliesCount. Then to scroll on up a little bit more. And this is the likesCount. So let's see. Sure enough, we see those and, and of course we aren't going
Sure enough, we see those and, and of course we aren't going to worry about the functionality for actually liking and commenting and things just yet. We will get to that point. For right now, I just wanna get this basic profile page done. So we have the counts. Now we just need to focus on the reposts. So let's think about this.
Now we just need to focus on the reposts. So let's think about this. We are iterating over all of our posts and we are passing them in. But one thing we can do, thankfully, because a repost is nothing more than a post, we could check to see if this item is a repost. And if it is, then we can just pass the repost to this partial view and then that will display the repost. Seems easy enough. So let's do this.
this partial view and then that will display the repost. Seems easy enough. So let's do this. We will have item, and this is gonna look a little ugly and we can make it look pretty later, but we'll check to see if the item is a repost. But we need a little bit more than that. We also need to check if it doesn't have any content, because if it doesn't have content, then it's just a normal repost, in which case we want to pass in the item repost of.
then it's just a normal repost, in which case we want to pass in the item repost of. But if it's a quote post or a normal post, we want to pass that on our partial view. So as I said, it's not the prettiest thing, but uh, this will at least make it work and if we want to come back and make this prettier than we can. But if we check on this, now we of course have an error because isRepost doesn't exist.
But if we check on this, now we of course have an error because isRepost doesn't exist. So let's open up the Post model and we'll just add that method. Uh, let's do it before the statics. So we'll have public function isReposts, which will return bool in value. And all we need to do is check if repost of id is not null. 'cause if it's not null, it's a repost.
ID is not null. 'cause if it's not null, it's a repost and that will fix that. So now if we take a look, sure enough, now we do need to include the avatars and things like that, but we can see that at least the handles are being displayed here and we also have the counts. But for the quote posts, we haven't gotten that far yet. So I think that is good. And I think for the most part we're done.
So I think that is good. And I think for the most part we're done with this show view. So we can close that. Everything else is going to be inside of this post blade view because we need to find the content. Where is the content? Because really that is where we will include the quoted post. So we could do something like this to where if the item is a repost, but again, that's not enough.
So we could do something like this to where if the item is a repost, but again, that's not enough. We need to check to see if it has content in this case. So if content is not null, then we know that we have a quoted post, in which case we want to output that. But what is a quoted post? It's just another post. And one of the really cool things about this is that each one of these posts is contained within a list item element.
that each one of these Post items is contained within a li element. So if we could do something like this, we could nest another list. That's probably the easiest thing to do. So that then we can include partials.profilePost. And then for the item we pass in, the item repost off. Yeah, that, that should work.
the item post off. Yeah, that, that should work. So that if we take a look, sure enough you have our quotePost right here because we have our additional content and then the content of that quoted post. So now we just need to get all the avatar stuff and, and all the other profile stuff done. So let's see, this is the item profileAvatar, URL, this is the displayName,
So let's see, this is the item profile avatar, URL, this is the display name, and we have the display name right here. Then we need the created_at, and then we have the handle. I think that's it. Uh, we do need links though. So instead of just /profile, we want to go to the /handle that is the URL for that given profile. And if we take a look, sure enough, we have our avatars, we have our display names, we have our handles.
And if we take a look, sure enough, we have our avatars, we have our display names, we have our handles. And the great thing about this is now we can navigate to these individual profiles and we can see that everything should be working. I, I don't necessarily like the way that this looks by nesting these quoted posts. Uh, you know, we don't need the likes and the things like that, but I'm not gonna screw up the markup because if there's anyone
and the things like that, but I'm not gonna screw up the markup because if there's anyone that's gonna screw up the markup, so, uh, that might be something that we just throw to Simon to take care of because he would do a much better job than that if Adrian needs to be involved than, than there's that as well. The same thing is going to be for the edit profile because we don't have a form for editing the profile. So that's something else that will need to be done.
because we don't have a form for editing the profile. So that's something else that will need to be done. But you know, for the most part, we have the basics of the profile page done. We are showing all of the top level Post so that in the next episode we can start focusing on including the replies.
