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