* Fix NoMethodError in Web::PushSubscription ``` undefined method `site_contact_email' for #<Class:0x00005976d13c40> /usr/local/bundle/gems/activerecord-5.1.3/lib/active_record/dynamic_matchers.rb:22:in `method_missing' /usr/local/bundle/gems/attr_encrypted-3.0.3/lib/attr_encrypted.rb:295:in `method_missing' /usr/local/bundle/gems/attr_encrypted-3.0.3/lib/attr_encrypted/adapters/active_record.rb:129:in `method_missing_with_attr_encrypted' /mastodon/app/models/web/push_subscription.rb:53:in `push_payload' ``` * Specify serializer in Web::NotificationSerializer
		
			
				
	
	
		
			170 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # 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
 |