Handling Party End0:00
One last thing that we need to do is make sure that we handle the case when a podcast ends when we're in a listening party. For example, if I'm in this listening party and it were to end, the podcast should then have the end state, or in this case at least be set to an end and we can figure out what to do with that end state in a little bit. But currently what it does is it just stops and then we have no way of showing to the user that this podcast or this listening room, this listening party has ended. So what can we do about this? The first step is we could add some Alpine state. We can say that we need to check to make sure that this is still live or that it hasn't ended, for example. So maybe we want to have a startTimestamp and an endTimestamp as well. And perhaps we would have that be the listening party endTimestamp. But we also do have to double check before we initialize this. Remember, we don't have endTime set right out the gate.
But we also do have to double check before we initialize this. Remember, we don't have endTime set right out the gate. So perhaps we'll do endTime. And if that exists, then we'll set the timestamp. And if that doesn't exist, then we'll just set it to null. Then why don't we also set up like a finishListeningParty function or event? Perhaps here, this would be finishListeningParty. And we could go ahead and initialize this. What we could say is this is where we can link to specific variables or specific parameters within our Livewire component. We could set up a new public isFinished variable and set it to false.
Tracking Finished State1:43
What we could say is this is where we can link to specific variables or specific parameters within our Livewire component. We could set up a new public isFinished variable and set it to false. That way we can initialize it in our code here. Since we have this isFinished variable and we are initializing that in our Livewire component, we could also initialize this on mount. Because if a PodcastListeningParty has finished, then the isActive variable that we have set in our database should be false. So if listeningParty is active, or in this case, if it is not active, then we can set this isFinished to true. And this we don't have to worry about initializing because the endTime in our listeningParty,
then we can set isFinished to true. And this we don't have to worry about initializing because the endTime in our listeningParty, that's the only one that we're waiting on the job to complete. So for this one, if listeningParty is active, is not active, then we can set isFinished to true. Then we can listen for a couple more updates and update our addEventListener timeUpdate to say, we're setting the current time to this audio.currentTime. But then we can also do if this.endTimeStamp exists, and this.currentTime is less than or equal to this.endTimeStamp minus this.startTimeStamp. Then what we could do is say let's run the this.finishListeningParty. There we go.
Then what we could do is say let's run the this.finishListeningParty. There we go. If the endTimestamp exists and the currentTime exists, then we'll run the this.finishListeningParty. This is probably redundant because we also have the ability to have a this.audio.addEventListener ended event. So maybe it's good to leave it in because we're just saying when those times are greater than the endTimestamp, subtracted by the this.startTimestamp, then we'll just run the this.finishListeningParty. And here's where we can link to the variable that we have set in our Livewire. And we have it up here because that way we can set it when we're mounting this component on the server side. So that way people who are joining late or who found a link in the podcastListeningParty has already ended, we can show them, hey, this has already ended.
Syncing Alpine to Livewire4:21
So that way people who are joining late or who found a link in the podcast listening party has already ended, we can show them, hey, this has already ended. So here what we can do is we can link to Livewire with $wire. And then we can say the method or in this case the variable is finished equals to true. And again, this is great because Livewire 3 gives you the ability to have this intermingling happen within Livewire and AlpineJS. So $wire.finished. So $wire.finished links to this. So we can send it to true by running this. Then what we can do is call wire.refresh. And what this is going to do is remount the component.
Then what we can do is call wire:refresh. And what this is going to do is remount the component. So in our Blade, we probably want to have a if $isFinished is true. Then we can show, hey, this has already been finished. We can set $this->isPlaying to false. And we can say if $this->audio, basically, if it's still playing, why don't we pause the audio? Okay, and here in playAudio, we might as well have a check here to say if !$this->audio, then we might as well return $this here just in case we have any issues down the road. And we can probably do the same with join and beReady because now we're checking if this is live. But also if we have actually audio set up and $this->isFinished is false.
And we can probably do the same with join and be ready because now we're checking if this is live. But also if we have actually audio set up and this isFinished is false. And now that we did this check, why don't we also add this to the check and update function here? So if this is live, actually, if this audio and this isPlaying and this is not finished, then we just want to play the audio. And again, this is probably redundant because we're already calling it there. I've gone ahead and updated these styles for this creating your own listening party placeholder. And just to show what that would look like, we have here is a ping animation with Intel and CSS. And then we're just bringing in the listeningPartyName for this room. Just for time's sake, I've also added a very basic style change for the isFinished variable.
Preventing UI Flicker6:59
And then we're just bringing in the listening party name for this room. Just for time's sake, I've also added a very basic style change for the isFinished variable. Now that we are accepting that and linking it to our Livewire component. What that is doing here is just saying that when a listening party is tried to be accessed after that's already been finished, then we just show this has already been finished. Lastly, one element within Alpine.js that we can use is the x-cloak command. You can see here if we click into this, we get a little flicker of our existing state. And that's going to be the waiting party state that we created. But what if we could hide that? And we can with the x-cloak command. So in our app.css, what we can do here is add this x-cloak { display: none !important; }
But what if we could hide that? And we can with the x-cloak command. So in our app.css, what we can do here is add this x-cloak display: none !important;. So that way in our PartiesShow component for the x-show of is not live, aka the waiting room component, we can add this x-dash-cloak initiative. So that when we're loading the component, it's basically just saying this is hidden until it's actually initiated or needed. So we can add this x-dash-cloak pretty liberally to our components. We'll add a Sarah font to this end party. So when we visit a finished party, it's a little bit more on brand. So lastly, I've went and updated just some minor changes in the NotIsLive component view. In this case, this is just like the waiting room for the listening party.
Improving Waiting Room UI8:28
So lastly, I've went and updated just some minor changes in the Livewire component view. In this case, this is just like the waiting room for the listening party. I've made some changes to the styles as well as added this copyToClipboard component that we have initialized right here. This is something that I grabbed from PinesUI copyToClipboard, and that's what we'll do here as well. So when this is loaded, we have this joinBeReady button still. But now we have a little bit more of a fancier countdown as well as the button to be able to share the listening party URL. Now, another thing that I made a change to is this init function. One of the things I noticed when creating a new listening party is if I was to specify startTime in the future, of course, and then create the new listening party, we're automatically initializing that, but it didn't start the countdown right away. In this case, I had to refresh the page.
Previewing Audio Player Styling9:24
we're automatically initializing that, but it didn't start the countdown right away. In this case, I had to refresh the page. This is just a way to say, hey, I want to run this startCountdown, which is going to run this startCountdown function down here to run the check and update every single second. So when we initialize this Alpine component, we're running the init function instead of this initializedAudioPlayer. Again, just a very small thing, but I want to show that's what we did behind the scenes. Okay, now that is looking a little bit better for this pre-game waiting room. Why don't we actually get started into how the audio player looks? Because if you remember, while it's live, everything works properly. We have the ability to see the podcast and hear the podcast is at the specific state that we want it to be, but it does not look pretty at all. So how can we make that better?
We have the ability to see the podcast and hear the podcast is at the specific state that we want it to be, but it does not look pretty at all. So how can we make that better? So now in the next episode, why don't we make some style changes to this page so that we don't just have this blank text. And now that we have the initialization of the ListeningParty when we're creating it, when we have the viewing party, in this case, the waiting room to wait until the ListeningParty goes live, why don't we make this look a little bit prettier as well?
