discourse/plugins/discourse-rewind/app/services/discourse_rewind/dismiss.rb
Régis Hanol 7955a472bc
FEATURE: Store rewind dismiss state in database instead of localStorage (#36625)
Users were seeing repeated rewind notifications across different devices
and browsers because the dismiss state was stored in localStorage, which
is per-browser and easily cleared.

Move the dismiss state to a new `discourse_rewind_dismissed_at` column
in the `user_options` table. This allows the dismiss to sync across all
devices and persist through browser data clears.

The timestamp is compared using "rewind year" logic - dismissing in
January 2025 (for rewind 2024) won't block the notification for rewind
2025 in December 2025.

- Add `discourse_rewind_dismissed_at` datetime column to user_options
- Add POST /rewinds/dismiss endpoint
- Add `discourse_rewind_dismissed` to user_option serializers
- Extract `DiscourseRewind.rewind_year` helper for year calculation
- Update frontend service to read from server state instead of
localStorage

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2025-12-12 15:16:22 +10:00

24 lines
511 B
Ruby

# frozen_string_literal: true
module DiscourseRewind
# Service responsible for dismissing Rewind for the user.
#
# @example
# ::DiscourseRewind::Dismiss.call(guardian: guardian)
#
class Dismiss
include Service::Base
# @!method self.call(guardian:)
# @param [Guardian] guardian
# @return [Service::Base::Context]
step :dismiss
private
def dismiss(guardian:)
guardian.user.user_option.update!(discourse_rewind_dismissed_at: Time.zone.now)
end
end
end