تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Fixing Post Timestamp0:07

Now that we have our post form working properly, we can switch back to the post component itself and make sure that it's functioning the way we'd expect. So real quick to be sure we're on the same page, when I say post component, this is what we are referring to. Alright? So immediately the first thing that jumps out at me, of course, is the long timestamp. Let's fix that post resource and yeah, right here for createdAt, let's just say diffForHumans.

and yeah, right here for created_at, let's just say diffForHumans. This is a Carbon instance. So I wanna know, well, how long ago was this created? Now I can see 46 minutes ago, an hour four days ago. Much better. Okay, next up, I believe the likes, comments and reposts are set to zero no matter what. And that's surely not right, based on our C data. Alright, so let's do this. Let's go into PostController and instantly

Correcting Engagement Counts0:52

Alright, so let's do this. Let's go into PostController and instantly after Jeremy's query, we're just going to return, uh, all of that data is JSON, so that I can have a look. So I can see here that he has some counts, like repliesCount. So if I were to search for that, they're not all zero, right? Yeah. This one is set to one and this one has a legsCount of two.

Yeah. This one is set to one and this one has a legs count of two. But let's copy that, remove that line, switch back. And now if we search for that, yeah, this Post is not rendering properly. Alright, so here's what I think. I think at the point we convert the query into the Resource, we're losing some data. So if we go into PostResource, we can see it's loading the likes relationship.

So if we go into PostResource, we can see it's loading the likes relationship if the likes relationship was included in the query. But notice that we do expect to count if nothing else, and we can confirm this. If I go into, if timeline query, um, yeah, do we have a width count? Yes, we do. There it is. So he's loading the replies count, the likes count, and the repost count. However, in our PostResource,

the likes count, and the repost count. However, in our Post resource, we're not, we're not using it. So once again, we need to update this. Why don't we say, all right, repliesCount would be not just this, although that should work. Uh, why don't we load that only on the condition that the repliesCount was loaded using withCount. So once again, I could say, well, this when counted replies, yeah, I think that should do the trick.

So once again, I could say, well, this when counted replies, yeah, I think that should do the trick. And then we'll do the same thing for likesCount only when we've loaded the count for likes. And then finally, the same thing for repostCount. Only when we've loaded the reposts. All right, so remember on Post we are referring to relationships there. Have we loaded the likesCount? Have we loaded the repostCount?

Have we loaded the likes count? Have we loaded the repost count? Have we loaded the, um, what's the last one? The replies count. Okay, so now with any luck, if I return to PostController and we return post to resource collection, I bet we will see all of that, uh, data. So come back and yeah, there we go. So for this one, now on our resource, we know the replies count in.

So for this one, now on our resource, we know the replies count in. The likes count. Perfect. So if I come back with any, like, this will just work, scroll down and it does. So notice we have two comments and one or two likes and one comment for the one. After that, it looks like we have two, uh, likes. One comment and one repost. This is all working. Okay, awesome. But next, uh, none

Implementing Like Button3:29

One comment and one repost. This is all working. Okay, awesome. But next, uh, none of this is working yet. So for example, I should be able to click on this like button to like the status. Even if I created it, I'm allowed to like my own status. I'm one of those people. So, uh, we should make that work. I'm gonna go into our Post view component, and you'll remember that originally Jeremy created, uh, a like button Blade component,

and you'll remember that originally Jeremy created, uh, a like button Blade component, and then we extracted that to a like button view component. And if we open this up right now, he, he assumed we were going to implement JavaScript for this. So it's just a button, but I'm just gonna make this, um, a form, but not just any form, an Inertia form. So let's import that at the top. And this is going to go somewhere

So let's import that at the top. And this is going to go somewhere and the action is gonna be something. And yeah, we'll just wrap this. All right. So that's our next step. We gotta figure out like, uh, we're still learning here. How, how, how do we perform a, like, I don't even know. Let's go into the routes file. All right, so if you don't mind, let's switch to my two up layouts.

All right, so if you don't mind, let's switch to my two up layouts. And I'm gonna search for like, and yeah, it looks like I see two here. All right, so we have one endpoint called postOp, like that will like the post, it's a POST request. And then we have another one called postOp, unlike also POST request. Uh, that will hit a like, and an unlike method on PostController.

Uh, that will hit a like and an unlike method on PostController. So the like method grabs the authenticated user's profile and then Jeremy calls like create, okay. And then he is returning json here because he was assuming this would be made via a traditional Ajax call, but we're using Inertia, which means I can just return back here. I think that's fun. And then the same thing for unlike, all right,

I think that's fun. And then the same thing for unlike, all right, okay, so now let's switch back to our like button. And we know that the method is going to be post and the action is going to be the route at least to start post, like, and now I need to send through the profile. So I believe a Post belongs to a Profile, right? Many of you know this code base better than I do at this point.

Many of you know this code base better than I do at this point. Do we have a Profile? If you watch the whole series? Yeah. So can I just say Post, but we don't have access to the Post. Hmm. So within, yeah, within this endpoint we don't have access to the Post. But you know what I'm thinking? This component is almost like locked to the Post itself. So in those situations,

This component is almost like locked to the Post itself. So in those situations, I don't mind just giving it the full payload. So for example, notice it needs to know is it active? What is the count and what is the id? All of this is connected to the Post itself. Uh, that can be useful by the way, but sometimes it's also just maybe easier to give it the Post itself and then let it grab and be responsible for what it needs.

to give it the post itself and then let it grab and be responsible for what it needs. So if we took that approach, we could do something like this return to like button. Now we just say, look, gimme a post and then I will take it from here. Alright, so now, uh, that should work postProfile and just post. I think this would be active if post and I believe it's hasLiked.

I think this would be active if Post and I believe it's hasLiked. Yeah, actually, real quick, let me show you something. Uh, while we're working on this, on Jeremy's timeline query, he's including these, uh, exists. Um, Boolean, uh, and this is pretty helpful actually. It lets us know, uh, information about what the current user has done. So for every Post, did the user like the Post? If so, there will be a, hasLiked property,

So for every Post, did the User like the Post? If so, there will be a hasLiked property, and you can see as part of the query it's saying on the relationship called likes for Post. Let's add a subquery of, um, likes where the profileId matches up with the current User's profile. Let's do another one. Did the User, um, repost this particular Post?

Let's do another one. Did the User, um, repost this particular Post? Once again, repost will refer to the relationship on Post. That's what that string is. And then the, the qualifier will be once again, do the profile IDs matchup. Okay? So that is pretty useful because now I can say, uh, it's active if the Post has been linked, and we can do the same thing here.

it's active if the Post has been linked, and we can do the same thing here or we can turn this into a computed property if it's more helpful. And then finally the count will be, let's put this on its own line. Uh, postLikesCount, right? We loaded the count relationship there. Is this all correct? I think so let's switch back and black screen to death. All right, let's fix the error.

I think so let's switch back and black screen to death. All right, let's fix the error. Cannot read properties of undefined like button. Okay, so what it's saying is right here, we're trying to access profile off of the post, but that's not working. Okay. So I think that's correct, which means we must be loading it incorrectly post. Alrighty, I can tell that's wrong. Zoom in. Ah, ;. Tricky, tricky, tricky, tricky. All right, so one more time. There we go. And are we seeing some likes counts?

Tricky, tricky, tricky, tricky. All right, so one more time. There we go. And are we seeing some likes counts? Yeah, this seems to be working. Cool. All right, so let's give it a shot. Let's just find one we haven't liked a lot of these have likes about maybe this one right here. Click it and it just works. And notice, because we're using Inertia by the way, it preserves um, the page scroll. So you don't have that jump back to the top.

preserves um, the page scroll. So you don't have that jump back to the top of the page the way you normally would with a traditional forum. It's all handled via Ajax. This is great. I like it. Alright, but now of course I need to provide a little more feedback. Like it's not clear, did Joe like this post or did I like this post? And then second, uh, presumably if I click on this,

or did I like this post? And then second, uh, presumably if I click on this, we should do the opposite, right? We should unlike the post. All right, let's do that part first. So right here, if you think about it, the endpoint is virtually the same. We just need to swap out the named route. So just to show you like if I were to manually change this to unlike, uh, let's see,

So just to show you like if I were to manually change this to unlike, uh, let's see, I think I liked this one right here, right? So if I click on it, it should just work and it does, it goes back to zero. Okay? So now, yeah, think about it. We can say, well, if the User has liked the Post, then they should unlike it. Otherwise they should like it. But now something just occurred to me.

Exposing hasLiked Data9:35

Otherwise they should like it. But now something just occurred to me. Um, Post thought has liked, I don't think we are including that within our resource, right? Let's go into PostResource. Yeah, we have a likesCount, but not hasLiked, so hmm. Let's go to TimelineQuery. Yeah, right here, uh, Jeremy's including these, uh, once again these Booleans hasLiked, hasReposted,

Yeah, right here, uh, Jeremy's including these, uh, once again these booleans hasLight, hasReposted, looks like we need those. Um, so my rule for resource classes is only include the data when you're sure that they are needed everywhere. Um, so I'm going to skip this section 'cause I haven't needed those yet. When we do, we will return and add them in, but I do need, hasLiked and hasReposted. Okay? So we'll go to PostResource

but I do need, hasLiked and hasReposted. Okay? So we'll go to PostResource and I'll add it right here. hasLiked will be, uh, this hasLiked, and then this one is what hasReposted. Okay, so now let's test this really quick just to make sure I didn't screw anything up, which is pretty common to be honest. Let's go to ResourceCollection. All right, come refresh hasLiked. Yeah, so look true.

Let's go to resource collection. All right, come refresh hasLiked. Yeah, so look true, false. That's good. hasReposted, do we have any that we have reposted? Yes, but we also have some that we have not. Okay, that makes me feel better. Yeah, as I was working on that, I was thinking, wait a minute, we don't even have access to that. Uh, so if we go on the likes button, this should do the trick.

Uh, so if we go on the likes button, this should do the trick. So we give it a shot and there we go. Ladies and gentlemen, this is the thing we've been working towards. Okay? So now I can clearly see that I, uh, have personally liked this post and this one, but I can disable that. I can turn it back on refresh. It'll remember the page scroll.

I can turn it back on refresh. It'll remember the page scroll. Unlike these, this is what we want. This is great. Okay, so now let's just work on the rest and I promise it's gonna be way quicker because we understand the entire flow. So for example, comments, presumably that's gonna open up a comment form, and I think Jeremy worked on that. So we'll, we'll dedicate a special video to that.

Building Repost Feature11:36

and I think Jeremy worked on that. So we'll, we'll dedicate a special video to that. But next I do wanna see if I have the ability to repost. So I will go to post view. We have a repost button, and once again, ooh, we got a, a lingering SVG that we didn't clear out. All right? I thought we did that in the SVG episode, but I guess we missed one. Let's create a new file repost-icon.view.

but I guess we missed one. Let's create a new file repost.blade.php view. And if I switch back, I'm just gonna grab all of this and loop it in. All right, I don't think there's anything dynamic here. Okay, so now this can be our repost icon. And then next, once again, we're gonna follow that same flow. We're just going to accept the post itself, uh, which is fine.

We're just going to accept the Post itself, uh, which is fine. We could do it either way, but we're gonna do it like this. Alright, so now, yeah, active, we can replace those with what post has reposted. Yep. And then the count would be the repostCount, right? So post.repostCount. I think that's correct. All right, so back to post view. We can swap all of this out and just send through the post. All right, let's switch back and let's scan.

We can swap all of this out and just send through the post. All right, let's switch back and let's scan to see if there are any that we have personally reposted. Maybe. Oh yeah, here we go. So this one right here, we gave it a repost. Okay, so now let's implement the form functionality. Once again, this is gonna be a form that gets imported. Uh, I believe Jeremy's mostly doing a post system here. The action will be, uh, repost. I guess it's this one here. So I hit post repost.

The action will be, uh, repost. I guess it's this one here. So I hit post repost. I need to provide, once again the profile and the post, and that hits a post action or a repost action on PostController real quick. Okay, that looks good. It redirects to a route. So this should be fairly standard. The route is post repost. We're gonna send through the post, profile, and the post. And with any luck, I think that just might work.

We're gonna send through the Post profile and the Post. And with any luck, I think that just might work. Alright, so now, yeah, let's just repost. How about this one right here? Give it a go. And it seems like that works, but um, oh no, this, this is weird at the very top. Oh, this hasn't, Hmm, this has Houston, we have a problem. So, all right, let's see what's going on here. I need to learn something. So this functionality is working.

Debugging Repost Rendering14:10

So, all right, let's see what's going on here. I need to learn something. So this functionality is working. If I give it a refresh, it works okay? So we can repost something, but as part of that, it's almost like it created a brand new Post with an empty content because a Post with empty content would be a repost, right? I'm trying to figure out how Jeremy implemented this. Uh, let's go to TablePlus.

I'm trying to figure out how Jeremy implemented this. Uh, let's go to table plus. And yeah, notice that we have a legs table, but not a repost table. A repost is still a post and he's doing this. Yeah. So look at this. We hit that repost button that creates a brand new post. It marks it as a repost of the post with an idea of 11, which was this one, and that matches up with the one that we liked.

which was this one, and that matches up with the one that we liked. Okay? So I'm thinking when we converted the Blade components to the view components, maybe we missed a check that determines how we render this. All right, let's do some debugging together. All right, so let's scroll down. Yeah, this is the section. So we show the content that then, okay, something's going on here.

So we show the content that then, okay, something's going on here. So if we're checking if this is true, is this Post a repost? Yes, in that case. And then this, it looks like we had a bad search and replace, I assume that's postContent, but this is confusing to me. Work through this with me. Help me understand this through the video.

Work through this with me. Help me understand this through the video. If the Post is a repost, okay? And the current Post has content, but a repost inherently doesn't have content, but it could have, it could be a quote tweet effectively, right? So if that's the case, only on that condition do we show the repost, but that doesn't make sense to me.

that condition do we show the repost, but that doesn't make sense to me because let's say you, you hit repost, but you don't include any, um, content like what we've done here. You should still see it. So maybe when I converted it, I did it wrong. Or maybe I just don't understand something here, but I feel like this is all we should check. And then also, should that even be an unordered list?

but I feel like this is all we should check. And then also, should that even be an unordered list? Can you repost more than one thing? I don't think so, but maybe there's a reason for that. All right, so let's switch back and that does fix it. Okay? Okay, that makes me feel better. So now if I scroll down, I can see, all right, you reposted this and as part of that, it's now kind of like a post on your behalf showing

and as part of that, it's now kind of like a Post on your behalf showing what the other person wrote. Okay? It's a little tricky, right? Uh, and now I'm starting to see, remember if we scroll back into Post, uh, where was it? Yeah, right here. Show engagement. I was trying to figure out why do we sometimes show engagement and sometimes we don't. It's for this reason, right here.

engagement and sometimes we don't. It's for this reason, right here you can engage the original post, but right here, I think he doesn't want you to duplicate this. So in that case, yeah, okay, here's what I see. You know what? We had a wonky search and replace that messed a few things up. Alright? Show engagement should be set to false there and I bet, okay.

Alright? Show engagement should be set to false there and I bet, okay. Alright, we're back on track, ladies and gentlemen. We know what we're doing here. That looks great. So now let's do another one. Let's say I wanna retweet or repost Hello world. All right, that increments it and it also gives us a post at the top. Perfect. All right, so now we made good progress again,

Perfect. All right, so now we made good progress again, and that's all we can ever hope for. Uh, but of course there's still more work to do. So as always, I will see you in the next video.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟