DEV Community

Cover image for Why Let Users Choose Between Being Nice and Being Paranoid? πŸ”„
Rolan Lobo
Rolan Lobo

Posted on

Why Let Users Choose Between Being Nice and Being Paranoid? πŸ”„

The Problem: My App Had Commitment Issues πŸ’”

So I built this file-sharing web-app called BAR Web that lets you send files that self-destruct after being viewed (think Mission Impossible but for PDFs). Cool, right?

But here's where things got weird: I added two features to control how page refreshes work:

  1. View Refresh Threshold - "Hey, if the same person refreshes within 5 minutes, don't count it as a new view"
  2. Auto-Refresh Interval - "Force the page to reload every 30 seconds so the file disappears"

And like a fool, I let users enable both at the same time. πŸ€¦β€β™‚οΈ

What Could Go Wrong?

Imagine this conversation:

User: "I want to be nice! Let people refresh without wasting views!"

Also User: "But also force them to reload every 30 seconds!"

Me: "...that's like wearing a belt AND suspenders, my friend."

It made zero sense. If you're auto-reloading the page, why care about refresh thresholds? If you're being forgiving with refreshes, why force reloads?

It was like trying to be both chill and paranoid at the same time. Pick a lane, buddy!

The Solution: Couples Therapy for UI Elements πŸ’‘

I made them mutually exclusive using radio buttons. Now users have to choose ONE:

Option 1: View Refresh Threshold (The Nice One)

"I trust you not to spam refresh. Take your time!"
Enter fullscreen mode Exit fullscreen mode

Perfect for:

  • Recipients who might have slow internet πŸ“Ά
  • People who need to scroll through long documents
  • When you're feeling generous

Options:

  • 0 minutes (every refresh counts - default)
  • 5 minutes (recommended)
  • Up to 1 hour (very forgiving)

Example:

User refreshes 3 times in 4 minutes β†’ Still counts as 1 view 🎯


Option 2: Auto-Refresh Interval (The Paranoid One)

"You have 30 seconds. Make them count. ⏱️"
Enter fullscreen mode Exit fullscreen mode

Perfect for:

  • Super sensitive stuff
  • Time-limited access codes
  • Maximum security theater

Options:

  • 10 seconds (ruthless)
  • 30 seconds (recommended)
  • Up to 5 minutes (generous for paranoia mode)

Example:

User opens file β†’ Has 30 seconds to read β†’ Page reloads β†’ File might be gone πŸ’¨

The Implementation (For the Nerds) πŸ€“

Frontend Magic

I used radio buttons styled like cards (same pattern as my storage mode selector):

// When "View Refresh Threshold" is selected
onChange={() => onRulesChange({
  ...rules,
  viewRefreshMinutes: 5,        // Enable this one
  autoRefreshSeconds: 0          // Disable the other
})}

// When "Auto-Refresh Interval" is selected  
onChange={() => onRulesChange({
  ...rules,
  viewRefreshMinutes: 0,         // Disable this one
  autoRefreshSeconds: 30         // Enable the other
})}
Enter fullscreen mode Exit fullscreen mode

Then I show the dropdown settings only for the selected option. One choice, one settings panel. Clean and simple.

Backend Wisdom

The backend was already handling both features separately. I just had to make sure only one value is non-zero at a time:

# In the database
view_refresh_minutes: int = 0
auto_refresh_seconds: int = 0

# Only one should be > 0
Enter fullscreen mode Exit fullscreen mode

The fingerprinting logic checks if enough time has passed, and the auto-refresh header tells the browser when to reload. Easy peasy.

Lessons Learned πŸŽ“

  1. Don't give users contradictory choices - It's our job to prevent foot-shooting
  2. UI should reflect reality - If two options fight each other, make them exclusive
  3. Good UX is about constraints - Sometimes the best feature is the one you don't include
  4. Radio buttons > Checkboxes for mutually exclusive stuff (duh)

The Result πŸŽ‰

Now my app has a clear UI that says:

"Pick your personality: Nice or Paranoid. You can't be both, Karen."

Users love it. No more confusion. No more contradictory settings. Just clean, simple choices.

Try It Yourself!

The feature is live at bar-rnr.vercel.app

And if you want to see the code or contribute:

πŸ‘‰ GitHub: BAR_RYY


Fun fact: I committed this in 4 separate commits with increasingly silly commit messages. Because if you're not having fun while coding, what's the point? πŸ˜„

The last commit was literally:

"Docs got the memo! πŸ“ README and FEATURES.md now explain the new Smart Refresh Control with examples, emojis, and a healthy reminder that you can't enable both options because that'd be like wearing a belt AND suspenders πŸ‘–"


Have you ever built conflicting features into your app? Share your "oops" moments in the comments! πŸ‘‡

Top comments (0)