Skip to content
Snippets Groups Projects
Commit e46abc71 authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Fix notifications in UI, added new API for fetching account relationships

parent 4bec6138
No related branches found
No related tags found
No related merge requests found
export const NOTIFICATION_DISMISS = 'NOTIFICATION_DISMISS';
export const NOTIFICATION_CLEAR = 'NOTIFICATION_CLEAR';
export function dismissNotification(notification) {
return {
......@@ -6,3 +7,9 @@ export function dismissNotification(notification) {
notification: notification
};
};
export function clearNotifications() {
return {
type: NOTIFICATION_CLEAR
};
};
import { connect } from 'react-redux';
import { NotificationStack } from 'react-notification';
import { dismissNotification } from '../../../actions/notifications';
import {
dismissNotification,
clearNotifications
} from '../../../actions/notifications';
const mapStateToProps = (state, props) => {
return {
notifications: state.get('notifications').map((item, i) => ({
message: item.get('message'),
title: item.get('title'),
key: i,
action: 'Dismiss',
dismissAfter: 5000
})).toJS()
};
};
const mapStateToProps = (state, props) => ({
notifications: state.get('notifications').map((item, i) => ({
message: item.get('message'),
title: item.get('title'),
key: item.get('key'),
dismissAfter: 5000
})).toJS()
});
const mapDispatchToProps = (dispatch) => {
return {
......
......@@ -2,13 +2,14 @@ import { COMPOSE_SUBMIT_FAIL, COMPOSE_UPLOAD_FAIL } from '../actions/compose';
import { FOLLOW_SUBMIT_FAIL } from '../actions/follow';
import { REBLOG_FAIL, FAVOURITE_FAIL } from '../actions/interactions';
import { TIMELINE_REFRESH_FAIL } from '../actions/timelines';
import { NOTIFICATION_DISMISS } from '../actions/notifications';
import { NOTIFICATION_DISMISS, NOTIFICATION_CLEAR } from '../actions/notifications';
import Immutable from 'immutable';
const initialState = Immutable.List();
function notificationFromError(state, error) {
let n = Immutable.Map({
key: state.size > 0 ? state.last().get('key') + 1 : 0,
message: ''
});
......@@ -34,6 +35,8 @@ export default function notifications(state = initialState, action) {
case TIMELINE_REFRESH_FAIL:
return notificationFromError(state, action.error);
case NOTIFICATION_DISMISS:
return state.filterNot(item => item.get('key') === action.notification.key);
case NOTIFICATION_CLEAR:
return state.clear();
default:
return state;
......
......@@ -28,6 +28,14 @@ class Api::AccountsController < ApiController
render action: :show
end
def relationships
ids = params[:id].is_a?(Enumerable) ? params[:id].map { |id| id.to_i } : [params[:id].to_i]
@accounts = Account.find(ids)
@following = Account.following_map(ids, current_user.account_id)
@followed_by = Account.followed_by_map(ids, current_user.account_id)
@blocking = {}
end
private
def set_account
......
......@@ -127,6 +127,14 @@ class Account < ApplicationRecord
nil
end
def self.following_map(target_account_ids, account_id)
Follow.where(target_account_id: target_account_ids).where(account_id: account_id).map { |f| [f.target_account_id, true] }.to_h
end
def self.followed_by_map(target_account_ids, account_id)
Follow.where(account_id: target_account_ids).where(target_account_id: account_id).map { |f| [f.account_id, true] }.to_h
end
before_create do
if local?
keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 1024 : 2048)
......
collection @accounts
extends('api/accounts/show')
collection @accounts
attribute :id
node(:following) { |account| @following[account.id] || false }
node(:followed_by) { |account| @followed_by[account.id] || false }
node(:blocking) { |account| @blocking[account.id] || false }
......@@ -8,4 +8,3 @@ node(:header) { |account| full_asset_url(account.header.url(:medium, fa
node(:followers_count) { |account| account.followers.count }
node(:following_count) { |account| account.following.count }
node(:statuses_count) { |account| account.statuses.count }
node(:following) { |account| current_account.following?(account) }
......@@ -59,6 +59,10 @@ Rails.application.routes.draw do
resources :media, only: [:create]
resources :accounts, only: [:show] do
collection do
get :relationships
end
member do
get :statuses
get :followers
......
......@@ -71,4 +71,46 @@ RSpec.describe Api::AccountsController, type: :controller do
expect(user.account.following?(other_account)).to be false
end
end
describe 'GET #relationships' do
let(:simon) { Fabricate(:user, email: 'simon@example.com', account: Fabricate(:account, username: 'simon')).account }
let(:lewis) { Fabricate(:user, email: 'lewis@example.com', account: Fabricate(:account, username: 'lewis')).account }
before do
user.account.follow!(simon)
lewis.follow!(user.account)
end
context 'provided only one ID' do
before do
get :relationships, params: { id: simon.id }
end
it 'returns http success' do
expect(response).to have_http_status(:success)
end
it 'returns JSON with correct data' do
json = body_as_json
expect(json).to be_a Enumerable
expect(json.first[:following]).to be true
expect(json.first[:followed_by]).to be false
end
end
context 'provided multiple IDs' do
before do
get :relationships, params: { id: [simon.id, lewis.id] }
end
it 'returns http success' do
expect(response).to have_http_status(:success)
end
xit 'returns JSON with correct data' do
# todo
end
end
end
end
......@@ -23,5 +23,5 @@ def body_as_json
end
def json_str_to_hash(str)
JSON.parse(str).with_indifferent_access
JSON.parse(str, symbolize_names: true)
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment