The Last of Us (Season 1)

The Last of Us wants to be a lot more than what it is.
68/1001419268
Starring
Pedro Pascal, Bella Ramsey, Gabriel Luna, Jeffrey Pierce, Merle Dandridge, Anna Torv
Creator
Jacob Minkoff
Rating
TV-MA
Genre
Action, Adventure, Drama, Horror, Thriller
Release date
January 15, 2023
Where to watch
HBO Max
Overall Score
Rating Overview
Story/Plot/Script
Performance
Visuals/Cinematography
Direction
Non-Wokeness
Rating Summary
The Last of Us has high production value, nice visuals, and usually good pacing. However, its episodes vary significantly in storytelling quality and relevance, and it ultimately is a forgettable piece of pop culture that I'm happy to have in the rearview mirror.

Based on a video game of the same name, episode one of The Last of Us is a pretty boilerplate intro into a Zombie-ridden post-apocalyptic world. After a brief teaser prologue, the show begins in 2003 and follows Joel Miller, played by Pedro Pascal (The Mandalorian, Game of Thrones), a middle-class contractor and single father as he is suddenly confronted with the total breakdown of civilization as a fungal infection sweeps the nation, turning much of the populous into defacto blood-thirsty zombies.

The Last of Us (Episode 1. When You’re Lost in the Darkness)

Fast forward 20 years, and Joel lives on the other side of the country in a quarantine zone. We quickly learn that his brother is in some unnamed trouble and that Joel is mounting an unsanctioned and illegal rescue operation.

The first episode of The Last of Us isn’t revolutionary in any way but it is a competently shot and generally well-acted thriller that does a perfectly adequate job of introducing us to the post-apocalyptic world of an alternate 2023. The sets are wonderfully detailed, and there are sufficient interesting unanswered, yet teased-at, questions to engage the audience and keep them plugged in for a second episode. Although having watched several Zombie movies and multiple seasons of The Walking Dead, I feel like I more or less already know the “big twist/secret” that seems as though it has been relatively clumsily shoehorned into this episode.

What mostly keeps the audience engaged is the strong, if muted, performances of Pascal and Anna Torv (Fringe), who plays Joel’s love interest, Tess. I say “muted” because they are soft-spoken brooding characters, which fits perfectly with the craphole world of the show. Inside the quarantine zone is a fascist police state that resembles text-book pictures of Nazi ghettos, and outside of the quarantine zone, there are Zombies, slavers, and “worse.” It’s not exactly a world that would foster bubbly personalities. The two leads have an easy chemistry and make believable choices throughout the episode, helping to make them likable in spite of their personalities. Also, Pascal’s Joel is a strong, stoic, and capable man, which is a refreshing change of pace from most programs nowadays.

 the last of us quarantine signsOne minor issue with Episode 1 is the use of signs as an expositional tool. It’s something that can easily be overdone and obvious, but in the director’s desire to not fall into this trap, he cuts away too quickly from signs that he seems to want us to read. It wouldn’t matter, but why focus on them at all if we aren’t supposed to read them? Just pan across them so we know that they are there. It’s a bit jarring, but it’s also a total nitpick.

There are some other logical inconsistencies with the program (how is it that no scientist has figured out an anti-fungal agent in 20 years- how is it possible that jet fuel for helicopters is abundant enough for nightly patrols), but it’s early. So, perhaps they will be answered later on.

Episode 1 of The Last of Us doesn’t introduce anything new to Zombie-lore, but if post-apocalyptic Zombie shows are your jam, this will give you a nice little fix.

The Last of Us (Episode 2. Infected)

Episode 2 of The Last of Us significantly improved over Episode 1. It’s essentially a survival episode, so it is much more focused and streamlined and avoids the political-correct baggage of its predecessor. It shows us much more of the world outside of the walls of the quarantine zone and manages to make the fungus rather ominous and frightening.

In the previous episode, I found myself smirking at the idea of fungus zombies, but those responsible for the make-up and prosthetics did an outstanding job, as did the set designers. Even in the open air, the omnipresent vegetation and fungal remains make the world feel claustrophobic.

Finally, Director Neil Druckman (The Last of Us video game franchise) did an outstanding job of building tension and delivering some truly stressful and harrowing scares.

I’m thoroughly looking forward to episode 3.

X Marks the Spot - Follow us Today!!

The Last of Us (Episode 3. Long, Long Time)

Episode 3 is a well-written (if cliched) and exquisitely shot piece that adds nothing to the series’s overall narrative and/or lore and only incidentally occurs within its universe. It follows two gay men who find one another shortly after the apocalypse, they fall in love, live together for some years, and that’s about it.

Hopefully, the most emotionally engaging episode so far, being completely tangential and virtually irrelevant, isn’t a potent of things to come. Sooner rather than later, Joel is going to have to show us some emotions other than rage and connect with Ellie.

Nick Offerman The Last of Us terrible trigger discipline and ridiculous grip.
Someone’s never held a handgun before.

Also, there is some really bad and unbelievable trigger discipline and teacup grip on display by an otherwise anal-retentive/borderline OCD survivalist. It was among the most unbelievable moments of the episode in a series featuring mushroom zombies. The second most unbelievable moment also involves guns. Early in the episode, Joel, who is escorting a young teenage girl through a wilderness filled with literal monsters, gets rid of his semi-automatic rifle because “there’s not a lot of ammo out there for it, makes it mostly useless.” Um…what? First of all, a rifle with any ammo in it is FARRRRRRR more useful in virtually every situation than a handgun, it’s ridiculous to claim anything else. Secondly, if one used all of its ammo and it became too much of a burden to carry, one could always drop it, but at least you would have it up to that point. An experienced smuggler who has traversed the wilds for decades like Joel would know that or would be dead. Finally, by the time he discarded the weapon, he knew that he was headed to a survivalist’s home with a huge arsenal. You’re telling me that the thought of trading something for more ammo, or trading this very valuable gun for a different gun, or trading it for any other type of supply for his JOURNEY ACROSS THE FRIGGIN NATION would never cross his mind? If he keeps making stupid choices like this, Joel is going to get the two of them killed by the next episode.

The Last of Us (Episode 4. Hold My Hand)

It’s back, baby! Episode 4 has righted the ship and is back on track. It continues Joel and Ellie’s trek across the U.S. and is a tightly written piece of tension-building fiction. The duo has made it to Kansas City unscathed, only to be set upon by a group of shoot-first ask-questions-later types, and now they have to find their way out of the city and away from the hunting parties within.

This episode shines because it sticks to the narrative, but mostly because it finally shows the two protagonists beginning to bond and show emotions other than rage and snark. For the first time since the series began, I found myself caring about the jump scares and the threats to the two. If the show can maintain this throughout the rest of the series, it will make it to the “Worth It” category. As it stands, it bumped our overall score pretty significantly after the irrelevant woke nothing-burger that was episode 3.

It’s not perfect, though. Joel continues to make decisions that don’t make sense, like needlessly leaving loaded shotguns and rifles lying around when his rifle is jammed, and it would cost him nothing to pick one or both up. That’s to say, nothing of not grabbing his pack before he makes a run for it. Also, the lead antagonist in this episode is completely unbelievable. She looks and sounds like a mousy mother from next door. The actress is completely out of her depth, and I find it unlikely that the show will make me believe that a group of heavily armed men would follow her. One of the first decisions that she makes is to murder a physician out of anger. It appears that he knows some information that she want,s and he is seemingly a traitor of some sort, but a schooled and skilled doctor would be worth their weight in gold in any post-apocalyptic world. The moment that it was found out that she offed him, her leadership would be challenged, and she’d be dead. Hopefully, Joel and Ellie won’t spend more than the next episode in Kansas City and will move on to an antagonist that we can love to hate.

The Last of Us (Episode 5. Endure and Survive)

Episode 5 of The Last of Us was a winner. It picks up immediately after Episode 4, and gives us the back story of why Kathleen is hellbent on finding Henry. I’ve got to admit that it’s a fairly good reason. Regrettably, thanks to the woke casting of Melanie Lynskey, every moment spent with the resistance will drag you out of the episode. She is completely unbelievable as a leader of men and most certainly a leader of armed insurrectionists with questionable ethics (as is demonstrated when they accept orders to murder a room full of unarmed collaborators without flinching). It’s more proof that the writers of this show don’t understand men at all and seem to only accidentally write Joel in a way that makes him identifiable as one. My fear is that once Joel gets some breathing room and no longer needs to be in “protector mode,” they’ll start screwing him up.

However, everything else about the episode is tight and on point. There’s a nice level of tension throughout, just enough emotional interplay to deepen Joel and Ellie’s relationship, serving to give the audience more to root for and a moment that will challenge you not to get misty. The episode also introduces Henry and his brother Sam, the two that Kathleen has been hunting since the previous episode. Sam gives Ellie a rare chance to remind us that she, too, is a child, and it makes her more likable than she’s been so far. At the same time, Henry is a mirror for Joel and gives us an inkling of the heart that he’s hidden away for the last 20 years.

This episode is absolutely Worth It. It has (mostly) interesting and engaging characters, great pacing, and real and relatable consequences.

The Last of Us (Episode 6. Kin)

There’s so little that actually happens in this episode that to mention any of it would be a spoiler. Suffice it to say that it wasn’t much of an entry. Many, especially those on the Left, will no doubt laude it as brave and poignant because Joel cries, but I disagree (more details in the WOKE REPORT section below). Â While it wasn’t terrible, it was rather boring. We’ve spent the entire season on a journey with these two, and the payoff was nothing. I’m in for a penny, in for a pound now that I’ve committed to reviewing the series, but knowing what I know now, I would have skipped the whole thing.

Also, the only thing dumber than people in their late 30s still wearing noserings is people in their late 30s still wearing noserings after the apocalyptics.

The Last of Us (Episode 7. Left Behind)

As the season progresses, it becomes increasingly apparent that the showrunners want Joel to play a secondary role in the series. He continues to wilt into the background, show weaknesses, and make boneheaded mistakes, while Ellie grows as a character, gets all of the good lines, and draws more focus with every episode.

Episode 7 is primarily one long flashback and, in what seems to be becoming a trend, is one that has more to do with showrunners’, Craig Mazin and Neil Druckmann’s desire to romanticize their sociopolitical beliefs and show that Ellie is gay rather than further their show’s narrative. Still, at least (unlike the series’s last divergence) it has to do with one of the two leads.

The episode begins not long after the events of the previous one, and Ellie manages to get Joel, who is critically injured, to the basement of an abandoned house. Soon after, she begins to think back to the night she was first bit.

ellie and riley kiss
Sure the actresses are in their twenties but the characters are teenage children.

Much like the Bill and Frank episode, this one is superbly acted, mostly by Bella Ramsey (Ellie), and is among the most emotionally fleshed-out episodes of the series. Also, like Bill and Frank’s, this entry has virtually nothing to do with the series’ overall narrative. The entire series is predicated on us knowing that she’s been bitten by a shroom, so showing us the details of it doesn’t do anything. It doesn’t show us why she’s so determined to keep going. It adds nothing to the character or the mythos. It is meaningless unless you think that finding out the origin of her puns book is super important.

Unlike the Bill and Frank episode, Episode 7 is riddled with small but distracting contrivances, conveniences, and a lackluster and careless attention to detail. First, why does no one in a show in which all of humanity’s survival relies on guns know how to handle guns? The actors constantly flag one another, hand-loaded weapons to one another when there’s no immediate danger, and exhibit painfully bad trigger discipline. Could HBO not hire an expert to train and teach the actors how to properly handle firearms?

Next, the uber-fascistic Fedra is not going to give Ellie, who is portrayed as a troublemaker on the verge of ruining her future with her lack of discipline, a functioning Walkman with tapes to use. If she already had it and was allowed to keep it, then she could not find batteries for it. Alkaline batteries have a maximum shelf life of 10 years. That would mean that Fedra is manufacturing and providing her with batteries for recreational use, which is not happening.

Then there’s the fact that Ellie, who’s been raised in Fedra care and has been groomed daily for the entirety of her life to become a soldier for Fedra, doesn’t know how to shoot or properly handle a weapon. I was a 10-and-a-half-year-old boy who’d belonged to the Boy Scouts for a week when I went to a function at which we were taught, among other things, how to shoot rifles. But sure, Fedra is going to wait at least 14.5 years before going over even the basics with one of their cadets.

Toward the beginning of the episode, Ellie and her friend sneak around in the middle of the night inside Ellie’s closely monitored room, and they are incredibly loud. Then they sneak out of her room, mention that they need to watch out for patrols, and proceed to nearly yell the entire time they stomp down alleyways.

The second episode, the first one to take place in the show’s present, makes a point to show the audience that surveillance helicopters fly over the QZ at all times of the day and night. Yet, now that these two need to be able to “sneak” over the tops of buildings and light up an entire glass-roofed mega-mall without being caught, there’s not one in the night sky.

There are several more of these examples, and they are stupid over sites that needlessly distract from an already meaningless episode.

When it’s all said and done, this episode was thoughtful, touching, and a complete waste of time.

The Last of Us (Episode 8. When We Are In Need)

There’s a lot to like in this episode. Joel is once again capable and dangerous, the season’s first frightening antagonist is introduced, and we get a single emotional moment expressed by Joel that is worth a damn.

Since the previous episode was almost entirely meaningless filler, this episode picks up within a matter of days after Joel was seriously injured. Ellie has patched him up the best that she could, but he is still weak and barely conscious. With the two of them starving, Ellie takes it upon herself to go hunting for game. Unfortunately for her, she finds more than deer.

This was easily the most intense and impactful episode of the season, and it actually took place within the main story arc. The antagonists were realistic and frightening, the danger was palpable, and the payoff was rewarding. It’s unfortunate that there’s only one episode left, as it finally felt like the show had begun.

With that being said, it was far from a perfect episode. The showrunners are either unwilling or incapable of handling anything to do with guns accurately. Twice in this episode, large animals were hunted and shot without being field-dressed. It wouldn’t be such a big oversite, except that the people who were hunting were also starving, and there’s no way that, after 20 years of having to hunt for food, they don’t know that by not field dressing the kills, they are putting the meat in danger. Furthermore, the first of these animals was a large male deer that weighed in at an average of 200 lbs, and the second was a horse that weighed upwards of 2,000 lbs. Each one of them had to be dragged four to five miles by hand over rough terrain. Dressing them would have reduced the load significantly.

Attention to details like the aforementioned hunting faux pas is peppered throughout the series, and in this episode, we are hit with another. On two occasions, we see the bloated and red wound on Joel’s abdomen, and each time, we can see the seam where the prosthetic meets his actual abdomen. Little things like that ruin the illusion and rip one out of the moment.

The Last of Us (Episode 9. Look for The Light)

The final episode of The Last of Us (season 1) has come and gone. Rather than a full episode that brings the rest of the series home, it feels like more of an epilogue. It’s not a particularly satisfying ending, and it didn’t leave me wanting more.

Virtually nothing happens in it. There was a very tense and exciting opening, which ended up being Ellie’s origin story. Joel exposits for a time, and a huge hammer is dropped. I really can’t talk about what happens in the episode’s final act without spoiling it. Suffice it to say, that the story that we spent 9 weeks watching comes to an end. If you’ve put the time in to watch the other episodes of the season, you won’t be disappointed with this one, but I doubt that you’ll be motivated to watch season 2.

FINAL THOUGHTS ON THE LAST OF US (season 1)

The Last of Us is a spiritual journey of one man, presented as a zombie apocalypse show. It features some wonderful set pieces and one or two touching moments. However, it is short on excitement and even shallower on narrative. Ultimately, the entire series could have made for an interesting feature-length film but was instead too little butter spread over too much toast.

Woke Report

WOKE REPORT

You're Only Getting Half the Picture.

This section is our site's secret sauce, and what truly separates us from the rest. If you don't read it, you haven't read our review.

Have the filmmakers chosenradical progressive messaging over story?
Unlock the insightsthat could change your viewing experience and protect your family.

James Carrick

James Carrick is a passionate film enthusiast with a degree in theater and philosophy. James approaches dramatic criticism from a philosophic foundation grounded in aesthetics and ethics, offering insight and analysis that reveals layers of cinematic narrative with a touch of irreverence and a dash of snark.

Leave a Review
  1. MNH May 11, 2023 at

    You forgot to include the fact that black actors are playing white characters from the game. That is WOKE.

    18
    2
    1. James Carrick May 11, 2023 at

      Thanks for the comment and observation. I didn’t play the video games and actively tried to avoid researching them while watching. I wanted to critique the show on its own merits and not have presuppositions based on the game.

      11
  2. Wesley May 11, 2023 at

    I think a better rating would be “by episode”. Episode 3 would be an instant skip for me with a hundred percent woke rating. You nailed it on the head, it would be statistically impossible. The episode did nothing to drive the narrative forward and it does nothing to offer any continuation to the story other than, “this is how they got a truck, this is how she got a gun”.

    I played both games. I loved the first one, and gagged through the second on all of the woke narrative. They make their agenda way too hard to swallow! How can you even begin to consider it when it is coated in glass, set on fire, and served encased in a huge freaking mass of dung?

    Hollywood is filled with professional circus animals and clowns, and I don’t go to a circus to be read a woke version of Shakespeare… I want to be entertained, so dance monkeys, dance!

    6
    2
  3. Timm May 17, 2023 at

    Every still I’ve seen of Offerman holding a firearm makes me so mad because he exercises zero trigger discipline with his index finger is resting firmly on the trigger instead of the frame of the gun. It’s 2023, man–it’s not the 90’s anymore when actors just picked up guns and started filming without any prior firearm safety training. There’s no excuse to not know how to properly and safely handle a firearm when training is available literally everywhere. I hope for your fellow actor’s sake there’s no live ammo on set (straight shot at you, Alec Baldwin)

    4
    2
  4. Hardly June 1, 2023 at

    The deaf kid and his brother were not in the game. They were out there to check more boxes, and the kid having a disability now makes this woke sermon eligible for an Oscar. Also more white liberal torture porn – watching a poor disabled black boy get shot by his brother, who then kills himself. Those evil white people. Saying this sarcastically as a mixed raced Hispanic.

    7
    2
    1. Zeerin June 11, 2023 at

      That’s not quite true. Sam and Henry *were* in the game. The difference is just that Sam wasn’t deaf in the game. A minor difference that could be argued to be in part meritocracy since the actual actor was deaf too.

  5. Tina Mallory June 5, 2023 at

    I’m the target market for this show, I loved The Walking Dead. When I found out that the girl in it was a “they” and non-binary, I decided not to watch. Likewise, if a character is considered a minority and they want to shove their woke BS down my throat, I will also not be watching it. It’s funny, I went to a hippy camp, was completely anti-racist up until two years ago. I still am not a racist, but I can’t stand watching “the message” anymore because it isn’t true. Everything changes when you see white people being labeled falsely as racists by grifters, when a woke grifter wins millions of dollars from equinox and she’s in the wrong, etc. etc. I can’t watch them in shows, and I certainly can’t stand anymore of this woke BS. Enough with the “they’s” they are boring, perhaps this show is good, but I’m not watching it.

    15
    1
  6. Dreddmartyr June 20, 2023 at

    Ellie’s actress and acting choice is the worst I’ve ever seen. It’s not even a shadow of the source material in the interest of a world without fearful female roles with real world emotions of a child who’s spent her entire life in a confined community now facing a very real and terrifying world outside those walls.
    Her foul mouth, tough btch attitude is repellent that I can’t sympathise with her. EVER. I was a big fan of everything about the game’s story and characters. The show just takes everything good and puts it’s socio-politicial agenda flavour to it – ruining that which made the franchise a huge success.
    Will not be watching season 2.

    15
    2
  7. Liberalism is a Disease June 21, 2023 at

    It’s funny as I read this whole thing how much I noticed the same thing. The teacup grip by the conservative gay survivalist was comical, I even paused it to make sure I saw it right.

    The whole show is pretty woke-heavy, but I think it’s somewhat more tempered than most other shows are. What I do know, given that HBO is a woke-happy network, is that this will get hella-woke in future episodes because the far left video game coders that wrote this in a leftist manner weren’t left enough for HBO.

    On a side note: requiring CAPTCHA every time someone posts, while I get it, is super annoying with that whack-a-mole style verification. Allow people to create accounts or something, this is too annoying to comment frequently.

    6
    1
  8. Vikram Sharma August 27, 2023 at

    My husband and I are gay conservatives and we found each other. Glad you aren’t running reality, because I guess you’d rather we were all miserable and lonely. Your attitude is the reason why moderates will keep pushing back against you. Maybe stop making assumptions about what all gay people are like. And for the record, I despised that episode for romanticizing suicide and implying a nihilistic world view where suffering has no value. But you seem more angry at the mere existence of gay people. Again, maybe consider that we might not all be flag-waving activists, and want the same things you do: a home, a family and to be letf alone to live our lives.

    3
    28
    1. James Carrick August 28, 2023 at

      Nothing says, “I’m conservative” like wishing violence upon me and my family because it took longer than you would have liked for me to have seen and approved your nonsense and unsubstantiated comment.

      Excerpt from the unhinged email sent to me fewer than 20 minutes after his original comment was submitted.

      violence wished upon me and my family

      P.S. I was at my little girl’s birthday party at the time.

      P.P.S. Troll

      P.P.P.S. Anyone who comes to my house looking to do harm to my family or to me should be prepared to enjoy the lead fruits of many hours spent at the gun range. If you get past the 115lbs dog.

      14
      1
      1. Vikram Sharma August 28, 2023 at

        Yeah, I definitely deserve to be on the wall of shame for that. It can serve as an object lesson to A) don’t overreact and B) exercise some patience. I’m the one who probably deserves a brick through my window. Sorry again for my stupidity.

        2
        5
        1. James Carrick August 28, 2023 at

          Water under the bridge.

          God bless

          8
          1
  9. not a retard April 14, 2024 at

    lmfao this is stupid. ellie is absolutely not a “hindrance” to joel in the game. dont speak on shit when you havent played it my god.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

No audience reviews yet. Be the first to leave one.

 

X Marks the Spot - Follow us Today!!

 

 

'; win.document.open(); win.document.write(html); win.document.close(); return true; } function escapeHtml(str){ return String(str || '').replace(/[&<>"']/g, function(ch){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[ch] || ch; }); } function renderShareOptionsWindow(win, landscapeUrl, squareUrl, shareUrl, heading){ if (!win || win.closed) return false; var safeHeading = escapeHtml(heading || 'Share options'); var safeLandscape = escapeHtml(landscapeUrl || ''); var safeSquare = escapeHtml(squareUrl || ''); var safeUrl = escapeHtml(shareUrl || ''); // Keep this HTML script-free. A nested script tag inside this inline footer script can break under Cloudflare Rocket Loader. var html = '' + safeHeading + '' + '' + '

' + safeHeading + '

'; win.document.open(); win.document.write(html); win.document.close(); try { var doc = win.document; var btn = doc.getElementById('copyLinkBtn'); var status = doc.getElementById('shareStatus'); var field = doc.getElementById('shareUrlField'); var urlToCopy = String(shareUrl || ''); function setCopied(){ if (status) status.textContent = 'Link copied.'; if (btn) { btn.textContent = 'Copied!'; win.setTimeout(function(){ btn.textContent = 'Copy link'; }, 1500); } } function focusField(){ if (!field) return; field.removeAttribute('readonly'); field.focus(); field.select(); field.setSelectionRange(0, field.value.length); field.setAttribute('readonly','readonly'); } function legacyCopy(text){ var ta = doc.createElement('textarea'); ta.value = text; ta.setAttribute('readonly','readonly'); ta.style.position='fixed'; ta.style.top='0'; ta.style.left='0'; ta.style.opacity='0.01'; ta.style.pointerEvents='none'; doc.body.appendChild(ta); ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); var ok=false; try{ ok=!!doc.execCommand('copy'); }catch(err){} doc.body.removeChild(ta); return ok; } win.__wiowCopyShareLink = async function(){ if (!urlToCopy) { if (status) status.textContent='No share URL available.'; return false; } focusField(); try { if (win.navigator && win.navigator.clipboard && typeof win.navigator.clipboard.writeText === 'function') { await win.navigator.clipboard.writeText(urlToCopy); setCopied(); return false; } } catch(err) {} if (legacyCopy(urlToCopy)) { setCopied(); return false; } if (status) status.textContent='Press Ctrl+C or Cmd+C to copy the selected link.'; focusField(); return false; }; if (btn) btn.addEventListener('click', function(e){ e.preventDefault(); win.__wiowCopyShareLink(); }); var nextBtn = doc.getElementById('nextComboBtn'); if (nextBtn) nextBtn.addEventListener('click', function(e){ e.preventDefault(); if (win.opener && win.opener.__wiowRefreshShareOptions) win.opener.__wiowRefreshShareOptions(win); }); var mainBtn = doc.getElementById('mainComboBtn'); if (mainBtn) mainBtn.addEventListener('click', function(e){ e.preventDefault(); if (win.opener && win.opener.__wiowResetShareOptions) win.opener.__wiowResetShareOptions(win); }); Array.prototype.slice.call(doc.querySelectorAll('.preview-frame img')).forEach(function(img){ img.addEventListener('click', function(){ var overlay=doc.createElement('div'); overlay.className='overlay'; var full=doc.createElement('img'); full.src=img.getAttribute('data-full') || img.src; full.alt='Preview'; overlay.appendChild(full); overlay.addEventListener('click', function(){ overlay.remove(); }); doc.body.appendChild(overlay); }); }); } catch(err) {} return true; } async function buildShareImage(container, options){ options = options || {}; var postId = container.getAttribute('data-post-id'); var sharePage = container.getAttribute('data-share-page'); var kind = (container.getAttribute('data-share-kind') || 'critics').toLowerCase(); var posterUrl = container.getAttribute('data-poster-url') || findPosterUrl(); if (!posterUrl){ posterUrl = ''; } var isRatings = (kind === 'ratings' || kind === 'ratings-admin' || kind === 'ratings-question'); var isAudience = (kind === 'audience' || kind === 'audience-teaser' || kind === 'audience-question'); var action = isRatings ? 'wiow_build_ratings_share_image' : (isAudience ? 'wiow_build_audience_share_image' : 'wiow_build_share_image'); var payload = new URLSearchParams(); payload.append('action', action); payload.append('post_id', String(postId)); payload.append('poster_url', posterUrl); payload.append('share_context', kind); if (options.force) { payload.append('force', '1'); } if (options.reset) { payload.append('reset_combo', '1'); } if (kind === 'ratings-admin') { payload.append('admin', '1'); } if (kind === 'ratings-question' || kind === 'audience-question' || kind === 'critics-question') { payload.append('questions', '1'); payload.append('mode', 'questions'); } if (kind === 'audience-teaser' || kind === 'critics-teaser') { payload.append('mode', 'teaser'); } var res = await fetch('https://worthitorwoke.com/wp-admin/admin-ajax.php', { method: 'POST', credentials: 'same-origin', headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}, body: payload.toString() }); var data = await res.json(); if (!data || !data.success || !data.data){ throw new Error((data && data.data && data.data.message) ? data.data.message : 'Share build failed.'); } return { image_url: data.data.image_url, share_url: data.data.share_url || sharePage, cycle_image_url: data.data.cycle_image_url || '', poster_url: data.data.poster_url || posterUrl || '' }; } async function buildShareSquareImage(container, cycleImageUrl, posterUrl, options){ options = options || {}; var postId = container.getAttribute('data-post-id'); var sharePage = container.getAttribute('data-share-page'); var kind = (container.getAttribute('data-share-kind') || 'critics').toLowerCase(); var isRatings = (kind === 'ratings' || kind === 'ratings-admin' || kind === 'ratings-question'); var isAudience = (kind === 'audience' || kind === 'audience-teaser' || kind === 'audience-question'); var action = isRatings ? 'wiow_build_ratings_share_image_square' : (isAudience ? 'wiow_build_audience_share_image_square' : 'wiow_build_share_image_square'); var payload = new URLSearchParams(); payload.append('action', action); payload.append('post_id', String(postId)); payload.append('share_context', kind); if (kind === 'ratings-admin') { payload.append('admin', '1'); } if (kind === 'ratings-question' || kind === 'audience-question' || kind === 'critics-question') { payload.append('questions', '1'); payload.append('mode', 'questions'); } if (kind === 'audience-teaser' || kind === 'critics-teaser') { payload.append('mode', 'teaser'); } if (cycleImageUrl) { payload.append('cycle_image_url', cycleImageUrl); } if (posterUrl) { payload.append('poster_url', posterUrl); } if (options.force) { payload.append('force', '1'); } if (options.reset) { payload.append('reset_combo', '1'); } var res = await fetch('https://worthitorwoke.com/wp-admin/admin-ajax.php', { method: 'POST', credentials: 'same-origin', headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}, body: payload.toString() }); var data = await res.json(); if (!data || !data.success || !data.data){ throw new Error((data && data.data && data.data.message) ? data.data.message : 'Square share build failed.'); } return { image_url: data.data.image_url, share_url: data.data.share_url || sharePage, cycle_image_url: data.data.cycle_image_url || cycleImageUrl || '', poster_url: data.data.poster_url || posterUrl || '' }; } window.__wiowRefreshShareOptions = async function(win){ if (!wiowCanAdminNext || !window.__wiowLastShareOptionsContext || !window.__wiowLastShareOptionsContext.row) return false; var ctx = window.__wiowLastShareOptionsContext; var row = ctx.row; var heading = ctx.heading || 'Share options'; var targetWin = win || ctx.win; try { renderShareOptionsLoadingWindow(targetWin, heading); var built = await buildShareImage(row, { force:true }); var builtSquare = await buildShareSquareImage(row, built.cycle_image_url || '', built.poster_url || '', { force:true }); if (!built || !built.image_url || !builtSquare || !builtSquare.image_url) throw new Error('Share build failed.'); window.__wiowLastShareOptionsContext = { row: row, heading: heading, win: targetWin }; renderShareOptionsWindow(targetWin, built.image_url, builtSquare.image_url, built.share_url || row.getAttribute('data-share-page') || '', heading); } catch(err) { if (targetWin && !targetWin.closed) { var msg = (err && err.message) ? err.message : 'Could not build next combo.'; targetWin.document.open(); targetWin.document.write('

Could not build next combo

' + escapeHtml(msg) + '

'); targetWin.document.close(); } } return false; }; window.__wiowResetShareOptions = async function(win){ if (!wiowCanAdminNext || !window.__wiowLastShareOptionsContext || !window.__wiowLastShareOptionsContext.row) return false; var ctx = window.__wiowLastShareOptionsContext; var row = ctx.row; var heading = ctx.heading || 'Share options'; var targetWin = win || ctx.win; try { renderShareOptionsLoadingWindow(targetWin, heading); var built = await buildShareImage(row, { force:true, reset:true }); var builtSquare = await buildShareSquareImage(row, built.cycle_image_url || '', built.poster_url || '', { force:true, reset:true }); if (!built || !built.image_url || !builtSquare || !builtSquare.image_url) throw new Error('Share build failed.'); window.__wiowLastShareOptionsContext = { row: row, heading: heading, win: targetWin }; renderShareOptionsWindow(targetWin, built.image_url, builtSquare.image_url, built.share_url || row.getAttribute('data-share-page') || '', heading); } catch(err) { if (targetWin && !targetWin.closed) { var msg = (err && err.message) ? err.message : 'Could not build main combo.'; targetWin.document.open(); targetWin.document.write('

Could not build main combo

' + escapeHtml(msg) + '

'); targetWin.document.close(); } } return false; }; // Unified capture-phase share handler. Chrome incognito can allow the visual // pointer animation while another script prevents the later bubbling click // handler from ever running. Handle all top-level share buttons here first. document.addEventListener('click', async function(e){ var targetEl = e.target && e.target.nodeType === 1 ? e.target : (e.target && e.target.parentElement ? e.target.parentElement : null); var btn = targetEl && targetEl.closest ? targetEl.closest('.wiow-share-btn') : null; if (!btn) return; // Ignore the Audience modal "Rate" button (it also has wiow-share-btn class in your CSS usage) if (btn.hasAttribute('data-wiow-audience-open')) return; var row = btn.closest('[data-wiow-share="1"], .wiow-share-row'); if (!row) return; var platform = btn.getAttribute('data-platform'); // Public top-level controls must work even when AJAX generation or membership-gated data is unavailable. // Options still uses the full image-builder path below. if (platform === 'x' || platform === 'link') { e.preventDefault(); e.stopPropagation(); var quickStatus = row.querySelector('.wiow-share-status'); var quickUrl = btn.getAttribute('data-copy-url') || row.getAttribute('data-share-page') || row.getAttribute('data-post-url') || wiowShareFallbackUrl(row); if (!quickUrl) { if (quickStatus) quickStatus.textContent = 'No share URL available.'; return; } if (platform === 'x') { openPopup(btn.getAttribute('href') || btn.getAttribute('data-wiow-x-intent') || wiowShareXIntentUrl(row)); if (quickStatus) quickStatus.textContent = ''; return; } if (quickStatus) quickStatus.textContent = 'Copying link…'; var copiedQuick = await wiowCopyShareText(quickUrl); var quickLabel = btn.querySelector('.wiow-share-btn__label'); var quickOriginal = quickLabel ? quickLabel.textContent : 'Copy link'; if (copiedQuick) { if (quickStatus) quickStatus.textContent = 'Link copied.'; if (quickLabel) { quickLabel.textContent = 'Copied!'; window.setTimeout(function(){ quickLabel.textContent = quickOriginal || 'Copy link'; }, 1500); } } else { if (quickStatus) quickStatus.textContent = 'Could not copy link.'; } return; } e.preventDefault(); var previewWin = null; if (platform === 'copy') { previewWin = openShareOptionsWindow(); var preloadKind = (row.getAttribute('data-share-kind') || 'critics').trim().toLowerCase(); var preloadHeading = (preloadKind === 'audience' || preloadKind === 'audience-teaser' || preloadKind === 'audience-question') ? 'Audience share options' : ((preloadKind === 'ratings' || preloadKind === 'ratings-admin' || preloadKind === 'ratings-question') ? 'Ratings share options' : 'Critic share options'); renderShareOptionsLoadingWindow(previewWin, preloadHeading); } var statusEl = row.querySelector('.wiow-share-status'); if (statusEl) statusEl.textContent = (platform === 'link') ? 'Copying link…' : 'Preparing share…'; try { var publicShareUrl = wiowShareFallbackUrl(row); var publicPostTitle = (row.getAttribute('data-post-title') || '').trim(); if (!publicPostTitle) publicPostTitle = 'this'; var publicShareKind = (row.getAttribute('data-share-kind') || 'critics').trim().toLowerCase(); var publicUpperTitle = publicPostTitle.toUpperCase(); var publicLineTwo = (publicShareKind === 'audience' || publicShareKind === 'audience-teaser' || publicShareKind === 'audience-question') ? 'See what the audience is saying.' : ((publicShareKind === 'ratings' || publicShareKind === 'ratings-admin' || publicShareKind === 'ratings-question') ? 'See the Worth it or Woke score.' : 'See what sane critics say.'); var publicBaseText = 'Is ' + publicUpperTitle + ' Worth it or Woke?\n\n' + publicLineTwo + '\n\nFollow @worthitorwoke for more.'; // Public top-level X and Copy Link controls should not depend on AJAX image generation. // The share URL itself carries the OG/Twitter metadata; scrapers can generate/fetch the image from that URL. if ((platform === 'x' || platform === 'link') && publicShareUrl) { if (platform === 'link') { var copiedPublicLink = await wiowCopyShareText(publicShareUrl); var publicLabel = btn.querySelector('.wiow-share-btn__label'); var publicOriginalLabel = publicLabel ? publicLabel.textContent : ''; if (copiedPublicLink) { if (statusEl) statusEl.textContent = 'Link copied.'; if (publicLabel) { publicLabel.textContent = 'Copied!'; window.setTimeout(function(){ publicLabel.textContent = publicOriginalLabel || 'Copy link'; }, 1500); } } else { if (statusEl) statusEl.textContent = 'Could not copy link.'; } return; } openPopup('https://twitter.com/intent/tweet?text=' + encodeURIComponent(publicBaseText) + '&url=' + encodeURIComponent(publicShareUrl)); if (statusEl) statusEl.textContent = ''; return; } var built; var builtSquare = null; if (platform === 'copy') { // Build the landscape first so it chooses exactly one featured/gallery cycle image, // then pass that same image to the square builder. This prevents two square // outputs or mismatched gallery states in the Share Options window. built = await buildShareImage(row, { force:true }); builtSquare = await buildShareSquareImage(row, built.cycle_image_url || '', built.poster_url || '', { force:true }); if (!built || !built.image_url) { throw new Error('Landscape share build failed.'); } if (!builtSquare || !builtSquare.image_url) { throw new Error('Square share build failed.'); } } else { built = await buildShareImage(row); } var shareUrl = built.share_url; var postUrl = (row.getAttribute('data-post-url') || '').trim() || shareUrl; var postTitle = (row.getAttribute('data-post-title') || '').trim(); if (!postTitle) postTitle = 'this'; var shareKind = (row.getAttribute('data-share-kind') || 'critics').trim().toLowerCase(); var upperTitle = postTitle.toUpperCase(); var lineTwo = (shareKind === 'audience' || shareKind === 'audience-teaser' || shareKind === 'audience-question') ? 'See what the audience is saying.' : ((shareKind === 'ratings' || shareKind === 'ratings-admin' || shareKind === 'ratings-question') ? 'See the Worth it or Woke score.' : 'See what sane critics say.'); var baseText = 'Is ' + upperTitle + ' Worth it or Woke?\n\n' + lineTwo + '\n\nFollow @worthitorwoke for more.'; var textWithUrl = baseText + '\n\n' + shareUrl; var postTextWithUrl = baseText + '\n\n' + postUrl; var encodedUrl = encodeURIComponent(shareUrl); var encodedBaseText = encodeURIComponent(baseText); var encodedTextWithUrl = encodeURIComponent(textWithUrl); if (platform === 'link') { var copiedLink = await wiowCopyShareText(shareUrl); var label = btn.querySelector('.wiow-share-btn__label'); var originalLabel = label ? label.textContent : ''; if (copiedLink) { if (statusEl) statusEl.textContent = 'Link copied.'; if (label) { label.textContent = 'Copied!'; window.setTimeout(function(){ label.textContent = originalLabel || 'Copy link'; }, 1500); } } else { if (statusEl) statusEl.textContent = 'Could not copy link.'; } return; } if (platform === 'x'){ // X gets the URL through the intent URL parameter, so do not also duplicate it in the tweet text. openPopup('https://twitter.com/intent/tweet?text=' + encodedBaseText + '&url=' + encodedUrl); } else if (platform === 'facebook'){ // Facebook sharing has been intentionally removed from this plugin flow. if (statusEl) statusEl.textContent = 'Facebook sharing is currently disabled.'; } else if (platform === 'copy'){ var heading = (shareKind === 'audience' || shareKind === 'audience-teaser' || shareKind === 'audience-question') ? 'Audience share options' : ((shareKind === 'ratings' || shareKind === 'ratings-admin' || shareKind === 'ratings-question') ? 'Ratings share options' : 'Critic share options'); window.__wiowLastShareOptionsContext = { row: row, heading: heading, win: previewWin }; var shown = renderShareOptionsWindow(previewWin, built.image_url, (builtSquare ? builtSquare.image_url : ''), shareUrl, heading); if (!shown) { var copied = false; if (navigator.clipboard && window.isSecureContext && navigator.clipboard.writeText){ try { await navigator.clipboard.writeText(shareUrl); copied = true; } catch (copyErr) {} } if (!copied) { var ta = document.createElement('textarea'); ta.value = shareUrl; ta.setAttribute('readonly', 'readonly'); ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); copied = !!document.execCommand('copy'); ta.remove(); } } } if (statusEl) statusEl.textContent = (platform === 'copy') ? 'Ready.' : ''; } catch(err){ if (previewWin && !previewWin.closed) { previewWin.close(); } if (statusEl) statusEl.textContent = (err && err.message) ? err.message : 'Could not share.'; } }, true); })();