summit
May 23, 2026

My husband twisted my arm until it popped, so I gave the signal: three taps on the wall. 020

My husband twisted my arm until it popped, so I gave the signal: three taps on the wall. 020

Posted June 4, 2026

PART 1:

"My husband twisted my arm until it popped, so I gave the signal: three taps on the wall. My 5-year-old made the call. “Mrs. Chen, help! Mom can’t move!” What he forgot was that our neighbor was a retired detective. When my husband twisted my arm behind my back until it popped, I made the signal. Three taps on the wall. Not loud. Not dramatic. Just three quick knocks with the side of my fist against the hallway paneling, exactly the way I had taught my son, Leo, in the calmest voice I could manage two months earlier. If you ever hear three taps in a row, baby, you take the phone from the kitchen drawer, hit redial, and say: Mrs. Chen, help. Mom can’t move. At the time, it had felt paranoid. Something I told myself I would never need. My husband, Aaron, had never left marks anyone else could see for long. He preferred pressure, restraint, fear, apologies afterward. He had a thousand ways to make me question what had happened. That night, he stopped pretending. It was December in Columbus, Ohio, the kind of bitter cold that made the windows breathe frost around the edges. Leo was in the living room in dinosaur pajamas, building a block tower on the rug. I was at the sink rinsing spaghetti bowls when Aaron came in from the garage already angry. I knew the signs immediately: the silence first, then the clipped movements, then the question delivered like an accusation. “Who were you talking to this afternoon?” I turned off the faucet. “My sister.” He took two steps closer. “Don’t lie to me.” I should have stopped answering. I knew that. But fear makes fools of us in repetitive ways. “I’m not lying.” He grabbed my wrist. Hard. “Aaron, let go.” Instead, he twisted my arm up behind me so fast I didn’t even have time to brace. There was a sharp, ugly pop in my shoulder and a bolt of pain so bright it wiped the kitchen out for a second. I cried out and hit the wall with my free hand. Three times. Tap. Tap. Tap. Aaron shoved me against the counter. “Stop being dramatic.” I could barely breathe. My right arm hung useless, hot and numb all at once. In the living room, I heard the blocks stop clattering. Then Leo’s small feet running. Aaron heard it too. “Stay in there!” he shouted. Too late. My son already knew the sound. I slid down to the floor because I truly couldn’t stay standing. Aaron loomed above me, chest heaving, and for the first time in seven years of marriage, I saw panic under his rage. Not concern. Calculation. He knew he had gone too far. From the living room came the scrape of the drawer opening. Then silence. Then Leo’s clear little voice, trembling but determined: “Mrs. Chen, help! Mom can’t move!” Aaron spun toward the doorway. I will never forget his face in that instant. Because he understood exactly what those words meant. Not just that Leo had called someone. That he had called her. Mrs. Evelyn Chen, sixty-eight, widow, retired homicide detective, our next-door neighbor for four years, the woman Aaron had always called “nosy” because she noticed everything and forgot nothing. He lunged toward the living room."

PAR NEXT

The phone cord snapped tight before he reached Leo.

My little boy had backed himself into the corner beside the end table, both hands wrapped around the receiver, eyes huge above the dinosaurs on his pajamas. His lips were still parted around Mrs. Chen’s name when Aaron crossed the rug.

“Give me that,” Aaron hissed.

Leo shook his head once.

It was the smallest no I had ever seen.

Aaron reached for him.

Then the front doorbell rang.

Not once.

Not politely.

It rang in three hard bursts, followed by a fist against the wood.

“Aaron Miller,” Mrs. Chen’s voice called through the door, calm and sharp enough to cut glass. “Step away from the child. I have already called 911.”

Aaron froze.

For half a second, the house held its breath.

The dishwasher hummed. The kitchen faucet dripped into the sink. The spaghetti bowls sat half-rinsed, red sauce drying along the edges. I was still on the floor, my shoulder pulsing with pain so deep it seemed to have a heartbeat of its own.

Leo looked toward the door.

“Mrs. Chen?” he cried.

“I’m here, sweetheart,” she said. “You keep holding that phone.”

Aaron turned back toward me.

The look in his eyes changed.

It was not rage now.

It was blame.

“You did this,” he whispered.

I pressed my good hand against the cabinet and tried to push myself up, but white pain flashed through my arm and I sank back down with a sound I could not swallow.

The doorbell rang again.

“Aaron,” Mrs. Chen said, louder now, “I can see through the side window. Move away from Leo.”

His head snapped toward the narrow glass beside the front door.

That was when I understood.

She had not come alone into danger blindly.

She had positioned herself where she could see.

Where she could testify.

Where Aaron could not rewrite the room.

He took one slow step back from Leo.

Then another.

But his eyes stayed on me.

“You tell them I slipped,” he said.

His voice was low, almost tender.

That was the voice that had fooled me for years.

The one he used after apologies. The one he used at church breakfasts. The one he used when he put his hand at the small of my back in public and everyone thought it meant affection.

“You tell them,” he repeated, “or I swear—”

Red and blue light flashed across the frosted windows.

Aaron stopped speaking.

The siren was not loud at first. It was muffled by the snow, by the thick winter night, by the walls of the house where so many quiet things had happened. Then it grew closer, filling the street, washing the living room in pulses of color.

Leo began to cry silently.

Not sobbing.

Just tears slipping down his cheeks while he still held the receiver.

The first knock from the officers shook the door.

“Columbus Police. Open the door.”

Aaron stood in the middle of the living room, barefoot on the rug, breathing hard.

For one terrifying second, I thought he might refuse.

Then Mrs. Chen’s voice came again.

“Open it, Aaron. They already know.”

Something in him collapsed.

Not guilt.

Not surrender.

The collapse of a man realizing the story no longer belonged only to him.

He opened the door.

Cold air rushed in, carrying snowflakes and the smell of wet pavement. Two officers stepped inside. Mrs. Chen stood behind them in a gray coat over her pajamas, silver hair pinned badly, face pale but steady. Her eyes swept the room in one motion: Aaron, Leo, the phone, me on the kitchen floor.

Then her jaw tightened.

“Emily,” she said softly.

That was my name.

I had almost forgotten what it sounded like when someone said it like I mattered.

The officers separated us quickly. One guided Aaron toward the entryway. The other came to me and crouched carefully.

“Ma’am, can you tell me what happened?”

Aaron spoke before I could.

“She fell. She gets anxious. She panicked.”

Mrs. Chen did not raise her voice.

“She did not fall.”

Aaron glared at her.

“You weren’t inside.”

“No,” she said. “But I heard the child say his mother couldn’t move. I heard you shouting. I saw you reaching for him. And I have two months of dated notes.”

Aaron’s face went still.

My breath caught.

Mrs. Chen looked at me, and something passed between us.

A memory.

Two months earlier, she had found me standing beside the mailbox with sunglasses on a cloudy morning. She had not asked why. She had only said, “If you ever need a plan, plans are quieter than panic.” I had almost denied everything. Instead, I cried in her kitchen while tea went cold between us.

She had helped me create the three taps.

But I did not know she had been writing things down.

The officer beside Aaron turned toward her.

“What kind of notes?”

Mrs. Chen kept her eyes on him.

“Dates. Times. Sounds through the shared side yard. Visible bruising on Mrs. Miller. Statements she made to me. Statements the child made while playing in my garden. License plate numbers for Aaron’s vehicle when he left after incidents. Photographs of damage to the fence gate after he slammed it in October.”

Aaron’s mouth opened.

Nothing came out.

For seven years, he had counted on my silence.

He had not counted on Mrs. Chen’s memory.

The paramedics arrived with a stretcher and warm blankets. When they tried to move me, pain tore through my shoulder so fiercely I gripped the officer’s sleeve with my good hand.

Leo screamed, “Don’t hurt Mommy!”

Mrs. Chen crossed the room and knelt in front of him.

“No one is hurting her now,” she said. “They are helping her.”

He looked at me for permission.

I forced myself to smile.

It must have looked terrible.

“It’s okay, baby,” I whispered.

Aaron twisted against the officer’s hold.

“Leo, come here.”

Leo hid behind Mrs. Chen.

That was the first verdict.

Before police reports.

Before doctors.

Before courtrooms.

My five-year-old son chose the person who made him feel safe.

Aaron saw it.

His face hardened into something I had no name for.

The officers took him outside in handcuffs. He did not shout. That was almost worse. He walked through the snow with his head lowered, already preparing the version of himself he would show the world.

Concerned husband.

Misunderstood father.

Man pushed too far by an anxious wife.

But this time, the house had witnesses.

At the hospital, the lights were too bright. The air smelled of antiseptic and coffee. A nurse cut my sleeve because moving my arm made me gasp. My shoulder was dislocated. There were bruises on my wrist shaped like fingers.

The doctor spoke gently, but I could see his face change when Leo told him, “Daddy made Mommy’s arm pop.”

Children do not understand strategy.

That is why they are dangerous to liars.

Mrs. Chen stayed beside us until my sister arrived from Dayton just after midnight. Rachel came through the emergency room doors in boots and a winter coat thrown over pajamas, hair wild, eyes red.

When she saw me, she stopped.

Her hand flew to her mouth.

“Emily.”

I looked away.

Not because I did not want her.

Because I could not bear the grief on her face.

She crossed the space and touched my hair like we were children again.

“You told me you were okay,” she whispered.

I closed my eyes.

“I thought if I said it enough, maybe I would be.”

Rachel bent over me, careful of the sling, and pressed her forehead to mine.

“You don’t have to say it anymore.”

That sentence broke something open.

I cried without sound at first. Then with sound. Then in a way that made the nurse pull the curtain around us, not to hide me in shame, but to give my pain a room of its own.

Leo slept later in a chair between Rachel and Mrs. Chen, wrapped in a hospital blanket, one hand still clutching the little toy dinosaur the paramedic had found under the couch and brought for him.

Mrs. Chen stood by the window.

Snow fell beyond the glass, orange under the parking lot lights.

“I should have called sooner,” she said.

Her voice was so quiet I almost missed it.

I turned my head.

“No.”

She did not look at me.

“I knew enough to suspect. I waited for you to ask.”

“You gave me a plan.”

“I should have given you more.”

Rachel looked at her.

“You saved them tonight.”

Mrs. Chen’s eyes remained on the snow.

“I was a detective for thirty-one years. I know saving and arriving late can feel too much alike.”

Her hand tightened around the paper cup of hospital coffee.

That was when I first saw that she carried ghosts too.

The next morning, an advocate came. Then a detective. Then a woman from child services whose voice was careful and kind but whose questions made me feel like I was being unstitched.

Did Aaron ever threaten you?

Did he ever block exits?

Did he ever control money?

Did Leo witness violence?

Each answer felt like handing over a piece of the life I had hidden.

Yes.

Yes.

Yes.

Yes.

Rachel sat beside me, one hand on my ankle because my good hand was busy signing forms.

An emergency protection order was filed before noon.

Aaron was released after arraignment the following day, but he was forbidden to contact me or come to the house. That should have felt like safety.

Instead, I shook so hard when I heard the news that Rachel had to take the phone from my hand.

“He can’t come near you,” she said.

I stared at the wall.

“He never cared what he was allowed to do.”

Mrs. Chen, who had come to the hospital with clean clothes and Leo’s favorite stuffed stegosaurus, said, “Then we behave as if he will try anyway.”

She said it plainly.

Not to frighten me.

To return me to reality.

That afternoon, we made another plan.

Rachel drove Leo and me to her house in Dayton. Mrs. Chen followed us for the first twenty miles, then pulled alongside at a red light before the highway. She looked small behind the wheel of her old Subaru, but when she lowered her window, her face was fierce.

“You are not disappearing,” she said.

I nodded, tears rising again.

“I know.”

“No,” she said. “Listen to me. Isolation is his favorite room. Do not go back into it.”

Leo waved from the backseat.

“Bye, Mrs. Chen.”

She smiled at him, and the smile softened her whole face.

“You were very brave, Detective Leo.”

He sat a little taller.

When the light changed, she turned back toward Columbus.

I watched her car in the mirror until it vanished into the gray afternoon.

For the first week at Rachel’s house, I moved like a guest in my own body. My shoulder was strapped and aching. My sleep came in broken pieces. Every time a car slowed outside, Leo ran to the hallway closet and hid behind the coats.

Rachel never forced him out.

She sat on the floor outside the closet and read books aloud until he crawled into her lap.

One night, I stood in the bathroom staring at the purple marks around my wrist. Fingerprints. Real. Visible. Undeniable.

I touched them with my left hand.

Then I whispered, “He did this.”

I said it again.

“He did this.”

The mirror fogged from the shower steam. My face blurred. For years, Aaron had made every injury into confusion. I had slipped. I had startled. I had overreacted. I had bruised easily. I had remembered wrong.

But bruises do not gaslight themselves.

Court came in January.

The morning was bitterly cold, the sky white and low over downtown Columbus. Rachel drove. Mrs. Chen met us on the courthouse steps, wearing a navy coat and carrying a folder so thick it looked like a weapon.

“You don’t have to be brave every minute,” she told me.

My mouth was dry.

“What if I fall apart?”

“Then we pick up the pieces in order.”

Inside, the hallway smelled of wet wool and floor polish. Aaron stood near the courtroom doors with his lawyer. He wore a gray suit. His hair was neatly combed. His left hand was bandaged from where he had punched the garage wall after the police removed him from the house.

When he saw me, his face changed.

Not much.

Just enough.

The old pull began in my chest.

The need to explain.

To soothe.

To survive by making him less angry.

Then Leo squeezed my hand.

I looked down.

He was not with us for the hearing, but he had given me his plastic dinosaur to keep in my coat pocket.

I wrapped my fingers around it.

Aaron’s lawyer tried to make it sound like a marital misunderstanding. Stress. Unemployment rumors. Miscommunication. A mother teaching a five-year-old a panic signal instead of communicating with her husband.

Then Mrs. Chen took the stand.

She placed her folder in front of her.

Aaron looked bored at first.

Then she began.

Dates.

Times.

Descriptions.

Photographs.

Copies of texts I had sent and deleted from my own phone, but not before she had told me to screenshot them to an email Aaron could not access.

A recording of Leo in her kitchen two weeks before December, saying, “Daddy gets loud when Mommy talks to Aunt Rachel.”

Aaron’s face slowly lost its confidence.

Then the prosecutor asked Mrs. Chen how she knew what to document.

Mrs. Chen’s fingers paused on the folder.

The courtroom became very still.

“My daughter,” she said, “was killed by her husband twenty-two years ago.”

A small sound escaped me.

Mrs. Chen did not look at anyone.

“She called me three weeks before it happened. She said things were bad. I told her to come over when she was ready. I thought giving her control was kindness. I have lived with that sentence for twenty-two years.”

Her voice trembled once, then steadied.

“So when Emily stood by her mailbox with sunglasses on and the same look my daughter had, I did not wait for ready. I offered a plan.”

The hidden truth landed in that courtroom with the weight of a life.

I understood then why she had watched.

Why she had written.

Why she had answered on the second ring.

Why she had said saving and arriving late felt too much alike.

Aaron stared at the table.

For the first time, he looked small.

Not harmless.

Never harmless.

But exposed.

The judge granted a long-term protection order. Aaron was ordered out of the home, barred from contacting me, and allowed only supervised visitation pending the criminal case and custody evaluation.

The criminal case took longer.

Aaron’s downfall did not come all at once. It came in pieces, each one created by his own hands.

The hospital report.

Leo’s recorded statement.

Mrs. Chen’s notes.

A neighbor’s doorbell camera catching Aaron throwing my phone into the trash bin in November.

Bank records showing he had moved money from our joint account after the arrest.

And finally, the worst thing, revealed at the worst possible moment.

At a custody hearing in March, Aaron’s lawyer argued that he was a stable parent and I was emotionally fragile. I sat at the table with my sling gone but my shoulder still stiff, my fingers pressed together under the table.

Then the guardian ad litem presented a drawing Leo had made.

Three people in a house.

Me on the floor.

Aaron very tall.

Leo beside a phone.

Above Aaron’s head, in shaky letters, Leo had written:

Daddy said if I tell, Mommy goes away.

The room went silent.

Aaron’s lawyer stopped shuffling papers.

The judge looked at Aaron.

Aaron’s face turned red.

“That’s not—he misunderstood.”

The judge’s voice was cold.

“Mr. Miller, your son is five.”

Aaron leaned forward.

“Emily coached him.”

I stood before I realized I was moving.

The courtroom turned toward me.

My lawyer touched my sleeve, but I shook my head.

For seven years, Aaron had spoken over me. Around me. For me.

Not now.

“My son learned the word help before he learned the word custody,” I said. “He learned to hide in closets before he learned to tie his shoes. He learned three taps because I was afraid he would watch me die and think silence was what good boys do.”

Aaron’s chair scraped back.

“That’s a lie.”

I looked at him.

Really looked.

At the man I had loved when he was charming. The man I had married when he made me feel chosen. The man who had turned our home into a place where a child needed emergency instructions hidden inside bedtime calm.

“No,” I said. “That is the first true thing I have said in front of you without asking permission.”

The judge ordered him to sit down.

Aaron did.

And something in me did not.

By summer, he accepted a plea deal that included jail time, probation, mandatory intervention, and continued restrictions. His employer let him go after the conviction. His friends faded when the court documents became harder to explain than his version of events. His parents, who had called me dramatic in January, sent one stiff apology letter in July.

I did not answer.

Not every door deserves reopening just because someone finally knocks politely.

Leo and I moved back into the house in August.

The first night, I stood in the kitchen staring at the hallway paneling where my three taps had landed. The marks were invisible, of course. Just wood. Just paint.

Leo came in barefoot, holding his dinosaur.

“Mommy?”

“Yes, baby?”

“Can we make the wall happy?”

I knelt slowly.

“What do you mean?”

He touched the panel with one tiny finger.

“This wall helped.”

So the next Saturday, Mrs. Chen came over with paint samples. Rachel brought sandwiches. Leo chose a warm yellow called Morning Butter, because he said it sounded like pancakes.

We painted the hallway together.

Mrs. Chen taped the edges with detective precision. Rachel got paint in her hair. Leo made one handprint low on the wall, and instead of wiping it away, I outlined it with a thin white frame.

Under it, I wrote the date.

Not the date Aaron hurt me.

The date we came home.

In September, Leo started kindergarten. On the first morning, he stood on the porch in a red backpack, looking far too small for the world.

“What if I need help?” he asked.

I crouched in front of him.

“Then you ask.”

“What if my voice is little?”

“Little voices still count.”

He thought about that.

“Mrs. Chen says mine counted.”

I smiled.

“She’s right.”

He stepped onto the bus, then turned back.

“Mommy?”

“Yes?”

“You count too.”

The bus doors closed before I could answer.

I stood on the curb long after it pulled away, crying into the sleeve of my sweater while Mrs. Chen pretended to inspect her mailbox.

Healing did not arrive like a sunrise.

It came like learning a room in the dark.

Some days, I could cook dinner and laugh with Leo over spilled milk.

Some days, the sound of a garage door down the street made me drop a glass.

Some nights, Leo slept in his own bed.

Some nights, he padded into mine and pressed his cold feet against my legs without saying a word.

We both went to therapy.

His therapist had puppets.

Mine had tissues that felt too soft and questions that made me furious before they made me free.

Rachel came every Friday at first, then every other Friday, then whenever she wanted because the house no longer felt like a crime scene. She and Mrs. Chen became unlikely friends. They drank tea at my kitchen table and argued about true crime documentaries while Leo built towers on the rug.

One evening in October, Mrs. Chen came over carrying a small wooden box.

“I have something for you,” she said.

Inside was a silver whistle on a blue cord.

I laughed softly.

“I already have you.”

Her eyes grew shiny.

“And I will not always be next door.”

The words frightened me.

She saw it.

“I’m not leaving yet,” she said. “But safety cannot be one person. It has to become a life.”

So we made another plan.

Not because fear ruled us.

Because preparation returned power.

By December, one year after the night of the three taps, snow came early. It frosted the windows the same way it had before, but the house felt different now. Softer. Lighter. Mine.

On the anniversary, Leo and I invited Rachel and Mrs. Chen for spaghetti.

I almost changed the menu.

Then I decided not to.

Aaron did not get to own spaghetti bowls.

The sauce simmered on the stove. Garlic warmed the air. Leo set the table with mismatched napkins. Mrs. Chen arrived with almond cookies. Rachel brought flowers, then cried because she said she did not know whether flowers were appropriate.

“They’re perfect,” I told her.

During dinner, Leo lifted his juice cup.

“To Mrs. Chen,” he said.

Mrs. Chen blinked quickly.

Rachel lifted her glass.

“To Leo.”

I lifted mine last.

“To coming home.”

We ate. We laughed. We did the dishes together.

Later, when Leo fell asleep on the couch, Mrs. Chen stood in the hallway looking at his framed handprint.

“I wish my daughter had had a wall like this,” she whispered.

I stood beside her.

“What was her name?”

Mrs. Chen’s mouth trembled.

“Mei.”

I reached for her hand.

She let me take it.

For a long time, we stood in the yellow hallway, two mothers holding the names of the living and the dead between us.

Then Leo stirred on the couch and murmured, still half asleep, “Detective Chen?”

She wiped her cheek and turned.

“Yes, sweetheart?”

“You can put Mei’s name on the wall too.”

Mrs. Chen covered her mouth.

I looked at the handprint, then at the blank space beside it.

The next day, we painted a small white flower there and wrote:

Mei — your mother helped us live.

That was the beautiful twist I did not see coming.

The signal had saved me.

But it had also given Mrs. Chen a place to put the love she had been carrying with nowhere to set it down.

Spring returned slowly.

On the first warm day, Leo rode his bike in the driveway while Mrs. Chen timed him with an old stopwatch. Rachel sat on the porch steps beside me, sunglasses on, two lemonades sweating between us.

The house behind us had new locks, new paint, and old ghosts that no longer got to choose where we stood.

A moving truck pulled into Mrs. Chen’s driveway that afternoon.

For one wild second, fear hit me.

Then Mrs. Chen came out with a clipboard and shouted, “Don’t panic. I’m getting a roommate.”

Her niece, Grace, moved in with three suitcases, two cats, and a laugh loud enough to scare birds from the maple tree. Mrs. Chen said she was tired of quiet. Grace said Mrs. Chen was bossy. Leo adored her immediately.

Life widened.

That was the part nobody tells you.

Leaving danger does not only remove terror.

It creates space.

For bike helmets on the porch.

For therapy drawings on the fridge.

For Rachel sleeping over on Christmas Eve.

For Mrs. Chen teaching Leo how to notice details without being afraid of them.

For me learning that peace is not emptiness.

Peace is a room where nobody listens for footsteps with dread.

On Christmas morning, Leo woke before sunrise and ran into my room with his dinosaur pajamas twisted around one ankle.

“Mommy! Snow!”

I opened my eyes to pale light and his warm little body bouncing beside me.

Snow covered the yard.

Soft.

Clean.

Quiet.

But not the old kind of quiet.

Not the silence of fear.

The quiet of a world resting.

We made pancakes. Morning Butter yellow glowed in the hallway. Rachel arrived wearing reindeer antlers. Mrs. Chen and Grace came over with cookies and two badly wrapped presents. Leo gave Mrs. Chen a drawing of herself wearing a detective badge and angel wings.

She stared at it for so long he got nervous.

“Do you like it?”

She pulled him into her arms.

“I love it more than evidence,” she said.

He laughed because he did not understand how enormous that was.

Later, I stepped into the hallway alone.

My handprint was not there.

Leo’s was.

Mei’s flower was.

The wall had become something I never could have imagined on the night I hit it in pain.

Not a witness to terror.

A witness to survival.

I placed my good hand against the paneling.

Once.

Twice.

Three times.

Not a signal.

A farewell.

Then I walked back into the living room, where Leo was showing Rachel how to build the tallest block tower in the world, Mrs. Chen was correcting Grace’s cookie arrangement, and sunlight spilled across the rug like a promise.

My shoulder would always ache when the weather turned.

Leo would always remember more than I wished he had to.

Mrs. Chen would always carry Mei.

And I would always know that one night in December, my five-year-old son held a phone with trembling hands and saved us both.

But the story did not end on the kitchen floor.

It ended here.

With pancakes cooling on plates.

With snow melting on boots by the door.

With laughter loud enough to fill every room Aaron had tried to make small.

With my son safe.

With my own voice steady.

With three taps no longer meaning danger.

Only proof that when I finally asked for help, someone heard me.

And this time, no one made me take it back.

Report this article

Select a reason for reporting:

May you like

Inaccurate information Copyright violation Spam / advertisement Offensive content Other '; footer.hidden = true; overlay.hidden = false; document.body.style.overflow = 'hidden'; } function hideSection() { if (section) section.hidden = true; } function openModal() { if (alreadyReported) { showSuccess(); return; } overlay.hidden = false; document.body.style.overflow = 'hidden'; } function closeModal() { overlay.hidden = true; document.body.style.overflow = ''; footer.hidden = false; overlay.querySelectorAll('input[name="report_reason"]').forEach(function(r) { r.checked = false; }); document.getElementById('reportMessage').value = ''; errorBox.hidden = true; submitBtn.disabled = false; submitBtn.textContent = 'Submit report'; imageItems = []; imgGrid.innerHTML = ''; updateAttachBtn(); } btn.addEventListener('click', openModal); closeBtn.addEventListener('click', closeModal); cancelBtn.addEventListener('click', closeModal); overlay.addEventListener('click', function(e) { if (e.target === overlay) closeModal(); }); document.addEventListener('keydown', function(e) { if (!overlay.hidden && e.key === 'Escape') closeModal(); }); // --- Error helper --- function showError(msg) { errorBox.textContent = msg; errorBox.hidden = false; } // --- Submit --- submitBtn.addEventListener('click', function() { var selected = overlay.querySelector('input[name="report_reason"]:checked'); if (!selected) { showError('Please select a reason.'); return; } errorBox.hidden = true; submitBtn.disabled = true; var itemsToUpload = imageItems.filter(function(it) { return !it.uploadedUrl; }); if (itemsToUpload.length === 0) { doSubmit(selected.value); return; } submitBtn.textContent = 'Uploading…'; var done = 0, failed = 0; itemsToUpload.forEach(function(entry) { entry.statusEl.textContent = '…'; entry.statusEl.className = 'report-img-item__status'; entry.statusEl.hidden = false; resizeImage(entry.file, MAX_LONG_PX, function(resized) { uploadFile(resized, currentSlug, function(err, url) { done++; if (err) { failed++; entry.statusEl.textContent = 'Failed'; entry.statusEl.className = 'report-img-item__status err'; } else { entry.uploadedUrl = url; entry.statusEl.textContent = '✓'; entry.statusEl.className = 'report-img-item__status done'; } if (done === itemsToUpload.length) { if (failed > 0) { showError('Could not upload ' + failed + ' image(s). Remove the failed ones (red) or submit without them.' ); submitBtn.disabled = false; submitBtn.textContent = 'Submit report'; } else { doSubmit(selected.value); } } }); }); }); }); function doSubmit(reason) { submitBtn.textContent = 'Sending…'; var uploadedUrls = imageItems .map(function(it) { return it.uploadedUrl; }) .filter(Boolean); var payload = { reason: reason, message: document.getElementById('reportMessage').value.trim(), post_slug: currentSlug, post_url: window.location.href }; if (uploadedUrls.length) payload.image_urls = uploadedUrls; fetch('/api/post-report', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }, body: JSON.stringify(payload) }) .then(function(r) { return r.json(); }) .then(function(data) { if (data && data.ok) { markReported(currentSlug); alreadyReported = true; bodyEl.innerHTML = '✓ Thank you for your report.'; footer.hidden = true; setTimeout(function() { closeModal(); footer.hidden = false; hideSection(); }, 2000); } else { showError((data && data.message) ? data.message : 'Something went wrong. Please try again.'); submitBtn.disabled = false; submitBtn.textContent = 'Submit report'; } }) .catch(function() { showError('Connection failed. Please try again.'); submitBtn.disabled = false; submitBtn.textContent = 'Submit report'; }); } })();

Comments 0

Posting as Guest '; } return; } var normalizedItems = items.slice().reverse(); var html = normalizedItems.map(function(comment) { var replies = Array.isArray(comment.replies) ? comment.replies : []; var repliesHtml = replies.map(function(reply) { return '' + '' + '' + '' + '' + escapeHtml(reply.author_name) + '' + escapeHtml(reply.time) + '' + '

' + escapeHtml(reply.content) + '

' + '' + '' + '' + ''; }).join(''); return '' + '' + '' + '' + '' + escapeHtml(comment.author_name) + '' + escapeHtml(comment.time) + '' + '

' + escapeHtml(comment.content) + '

' + '' + '' + '' + '' + (repliesHtml ? '' + repliesHtml + '' : '') + ''; }).join(''); if (mode === 'prepend') { listEl.insertAdjacentHTML('afterbegin', html); return; } listEl.insertAdjacentHTML('beforeend', html); } async function loadComments(page, mode) { var query = new URLSearchParams({ post_slug: postSlug, page: String(page), per_page: String(perPage), }); var response = await fetch('/api/post-comments?' + query.toString(), { method: 'GET', headers: { 'Accept': 'application/json' } }); var data = await response.json().catch(function() { return {}; }); if (!response.ok || data.ok === false) { throw new Error((data && data.message) || 'Cannot load comments.'); } var pagination = data.pagination || {}; currentPage = Number(pagination.current_page || 1); lastPage = Number(pagination.last_page || 1); totalCountEl.textContent = String((data.post && data.post.comment_count) || pagination.total || 0); loadMoreBtn.classList.toggle('comment-box__hidden', currentPage >= lastPage); renderComments(data.comments || [], mode); } async function postComment(content, parentId, feedbackTarget, submitTarget) { var authorName = ensureName(false); if (!authorName) { var forced = ensureName(true); if (!forced) { throw new Error('Please enter your name first.'); } authorName = forced; } var payload = { post_slug: postSlug, post_url: window.location.href, author_name: authorName, content: content, }; if (parentId > 0) { payload.parent_id = parentId; } if (submitTarget) submitTarget.disabled = true; if (feedbackTarget) { feedbackTarget.textContent = 'Submitting...'; feedbackTarget.style.color = ''; } try { var response = await fetch('/api/post-comments', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(payload) }); var data = await response.json().catch(function() { return {}; }); if (!response.ok || data.ok === false) { throw new Error((data && data.message) || 'Cannot submit comment.'); } await loadComments(1, 'replace'); return true; } finally { if (submitTarget) submitTarget.disabled = false; } } form.addEventListener('submit', async function(event) { event.preventDefault(); var content = String(contentEl.value || '').trim(); if (!content) { setFeedback('Please enter comment content.', true); return; } submitBtn.disabled = true; setFeedback('Submitting...'); try { await postComment(content, 0); contentEl.value = ''; setFeedback('Comment submitted.'); } catch (error) { setFeedback(error.message || 'Cannot submit comment.', true); } finally { submitBtn.disabled = false; } }); listEl.addEventListener('click', function(event) { var replyBtn = event.target.closest('.comment-item__reply-btn'); if (replyBtn) { var row = replyBtn.closest('.comment-item'); if (!row) return; var formEl = row.querySelector('.comment-item__reply-form'); if (!formEl) return; listEl.querySelectorAll('.comment-item__reply-form').forEach(function(f) { if (f !== formEl) f.classList.add('comment-box__hidden'); }); formEl.classList.remove('comment-box__hidden'); var input = formEl.querySelector('textarea'); if (input) input.focus(); return; } var cancelBtn = event.target.closest('.comment-item__reply-cancel'); if (cancelBtn) { var rf = cancelBtn.closest('.comment-item__reply-form'); if (!rf) return; rf.classList.add('comment-box__hidden'); var rInput = rf.querySelector('textarea'); var rFeedback = rf.querySelector('.comment-item__reply-feedback'); if (rInput) rInput.value = ''; if (rFeedback) rFeedback.textContent = ''; } }); listEl.addEventListener('submit', async function(event) { var replyForm = event.target.closest('.comment-item__reply-form'); if (!replyForm) return; event.preventDefault(); var row = replyForm.closest('.comment-item'); if (!row) return; var parentId = Number(row.getAttribute('data-comment-id') || 0); var input = replyForm.querySelector('textarea'); var submit = replyForm.querySelector('.comment-item__reply-submit'); var feedback = replyForm.querySelector('.comment-item__reply-feedback'); var replyText = String((input && input.value) || '').trim(); if (!replyText) { if (feedback) { feedback.textContent = 'Please enter reply content.'; feedback.style.color = '#dc2626'; } return; } try { await postComment(replyText, parentId, feedback, submit); // setFeedback('Reply submitted.'); } catch (error) { if (feedback) { feedback.textContent = error.message || 'Cannot submit reply.'; feedback.style.color = '#dc2626'; } } }); changeNameBtn.addEventListener('click', function() { ensureName(true); }); loadMoreBtn.addEventListener('click', async function() { if (currentPage >= lastPage) return; loadMoreBtn.disabled = true; try { await loadComments(currentPage + 1, 'prepend'); } catch (error) { setFeedback(error.message || 'Cannot load more comments.', true); } finally { loadMoreBtn.disabled = false; } }); ensureName(false); loadComments(1, 'replace').catch(function(error) { setFeedback(error.message || 'Cannot load comments.', true); }); })();

Other posts