about summary refs log tree commit diff
path: root/app/serializers/web/notification_serializer.rb
blob: e5524fe7a7b9da5547cb015be4899548f3a2e9d0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# frozen_string_literal: true

class Web::NotificationSerializer < ActiveModel::Serializer
  include RoutingHelper
  include StreamEntriesHelper

  class DataSerializer < ActiveModel::Serializer
    include RoutingHelper
    include StreamEntriesHelper
    include ActionView::Helpers::SanitizeHelper

    attributes :content, :nsfw, :url, :actions,
               :access_token, :message, :dir

    def content
      decoder.decode(strip_tags(body))
    end

    def dir
      rtl?(body) ? 'rtl' : 'ltr'
    end

    def nsfw
      return if object.target_status.nil?
      object.target_status.spoiler_text.presence
    end

    def url
      case object.type
      when :mention
        web_url("statuses/#{object.target_status.id}")
      when :follow
        web_url("accounts/#{object.from_account.id}")
      when :favourite
        web_url("statuses/#{object.target_status.id}")
      when :reblog
        web_url("statuses/#{object.target_status.id}")
      end
    end

    def actions
      return @actions if defined?(@actions)

      @actions = []

      if object.type == :mention
        @actions << expand_action if collapsed?
        @actions << favourite_action
        @actions << reblog_action if rebloggable?
      end

      @actions
    end

    def access_token
      return if actions.empty?
      current_push_subscription.access_token
    end

    def message
      I18n.t('push_notifications.group.title')
    end

    private

    def body
      case object.type
      when :mention
        object.target_status.text
      when :follow
        object.from_account.note
      when :favourite
        object.target_status.text
      when :reblog
        object.target_status.text
      end
    end

    def decoder
      @decoder ||= HTMLEntities.new
    end

    def expand_action
      {
        title: I18n.t('push_notifications.mention.action_expand'),
        icon: full_asset_url('web-push-icon_expand.png', skip_pipeline: true),
        todo: 'expand',
        action: 'expand',
      }
    end

    def favourite_action
      {
        title: I18n.t('push_notifications.mention.action_favourite'),
        icon: full_asset_url('web-push-icon_favourite.png', skip_pipeline: true),
        todo: 'request',
        method: 'POST',
        action: "/api/v1/statuses/#{object.target_status.id}/favourite",
      }
    end

    def reblog_action
      {
        title: I18n.t('push_notifications.mention.action_boost'),
        icon: full_asset_url('web-push-icon_reblog.png', skip_pipeline: true),
        todo: 'request',
        method: 'POST',
        action: "/api/v1/statuses/#{object.target_status.id}/reblog",
      }
    end

    def collapsed?
      !object.target_status.nil? && (object.target_status.sensitive? || object.target_status.spoiler_text.present?)
    end

    def rebloggable?
      !object.target_status.nil? && !object.target_status.hidden?
    end
  end

  attributes :title, :image, :badge, :tag,
             :timestamp, :icon

  has_one :data, serializer: DataSerializer

  def title
    case object.type
    when :mention
      I18n.t('push_notifications.mention.title', name: name)
    when :follow
      I18n.t('push_notifications.follow.title', name: name)
    when :favourite
      I18n.t('push_notifications.favourite.title', name: name)
    when :reblog
      I18n.t('push_notifications.reblog.title', name: name)
    end
  end

  def image
    return if object.target_status.nil? || object.target_status.media_attachments.empty?
    full_asset_url(object.target_status.media_attachments.first.file.url(:small))
  end

  def badge
    full_asset_url('badge.png', skip_pipeline: true)
  end

  def tag
    object.id
  end

  def timestamp
    object.created_at
  end

  def icon
    object.from_account.avatar_static_url
  end

  def data
    object
  end

  private

  def name
    display_name(object.from_account)
  end
end