parent
3838e6836d
commit
da2ef4d676
@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::NotificationsController < ApiController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@notifications = Notification.where(account: current_account).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id])
|
||||
|
||||
next_path = api_v1_notifications_url(max_id: @notifications.last.id) if @notifications.size == 20
|
||||
prev_path = api_v1_notifications_url(since_id: @notifications.first.id) unless @notifications.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
end
|
@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Notification < ApplicationRecord
|
||||
include Paginable
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :activity, polymorphic: true
|
||||
|
||||
belongs_to :mention, foreign_type: 'Mention', foreign_key: 'activity_id'
|
||||
belongs_to :status, foreign_type: 'Status', foreign_key: 'activity_id'
|
||||
belongs_to :follow, foreign_type: 'Follow', foreign_key: 'activity_id'
|
||||
belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id'
|
||||
|
||||
STATUS_INCLUDES = [:account, :media_attachments, mentions: :account, reblog: [:account, mentions: :account]].freeze
|
||||
|
||||
scope :with_includes, -> { includes(status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account) }
|
||||
|
||||
def type
|
||||
case activity_type
|
||||
when 'Status'
|
||||
:reblog
|
||||
else
|
||||
activity_type.downcase.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
def from_account
|
||||
case type
|
||||
when :mention
|
||||
activity.status.account
|
||||
when :follow, :favourite, :reblog
|
||||
activity.account
|
||||
end
|
||||
end
|
||||
|
||||
def target_status
|
||||
case type
|
||||
when :reblog
|
||||
activity.reblog
|
||||
when :favourite, :mention
|
||||
activity.status
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class NotifyService < BaseService
|
||||
def call(recipient, activity)
|
||||
@recipient = recipient
|
||||
@activity = activity
|
||||
@notification = Notification.new(account: @recipient, activity: @activity)
|
||||
|
||||
return if blocked?
|
||||
|
||||
create_notification
|
||||
send_email if email_enabled?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def blocked?
|
||||
blocked = false
|
||||
blocked ||= @recipient.id == @notification.from_account.id
|
||||
blocked ||= @recipient.blocking?(@notification.from_account)
|
||||
blocked
|
||||
end
|
||||
|
||||
def create_notification
|
||||
@notification.save!
|
||||
FeedManager.instance.broadcast(@recipient.id, type: 'notification', message: FeedManager.instance.inline_render(@recipient, 'api/v1/notifications/show', @notification))
|
||||
end
|
||||
|
||||
def send_email
|
||||
NotificationMailer.send(@notification.type, @recipient, @notification).deliver_later
|
||||
end
|
||||
|
||||
def email_enabled?
|
||||
@recipient.user.settings(:notification_emails).send(@notification.type)
|
||||
end
|
||||
end
|
@ -0,0 +1,2 @@
|
||||
collection @notifications
|
||||
extends 'api/v1/notifications/show'
|
@ -0,0 +1,11 @@
|
||||
object @notification
|
||||
|
||||
attributes :id, :type
|
||||
|
||||
child from_account: :account do
|
||||
extends 'api/v1/accounts/show'
|
||||
end
|
||||
|
||||
node(:status, if: lambda { |n| [:favourite, :reblog, :mention].include?(n.type) }) do |n|
|
||||
partial 'api/v1/statuses/show', object: n.target_status
|
||||
end
|
@ -0,0 +1,13 @@
|
||||
class CreateNotifications < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :notifications do |t|
|
||||
t.integer :account_id
|
||||
t.integer :activity_id
|
||||
t.string :activity_type
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :notifications, :account_id
|
||||
end
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
Fabricator(:notification) do
|
||||
activity_id 1
|
||||
activity_type "MyString"
|
||||
end
|
@ -0,0 +1,29 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Notification, type: :model do
|
||||
describe '#from_account' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#type' do
|
||||
it 'returns :reblog for a Status' do
|
||||
notification = Notification.new(activity: Status.new)
|
||||
expect(notification.type).to eq :reblog
|
||||
end
|
||||
|
||||
it 'returns :mention for a Mention' do
|
||||
notification = Notification.new(activity: Mention.new)
|
||||
expect(notification.type).to eq :mention
|
||||
end
|
||||
|
||||
it 'returns :favourite for a Favourite' do
|
||||
notification = Notification.new(activity: Favourite.new)
|
||||
expect(notification.type).to eq :favourite
|
||||
end
|
||||
|
||||
it 'returns :follow for a Follow' do
|
||||
notification = Notification.new(activity: Follow.new)
|
||||
expect(notification.type).to eq :follow
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in new issue