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