diff --git a/app/assets/javascripts/api/accounts/lookup.coffee b/app/assets/javascripts/api/accounts/lookup.coffee new file mode 100644 index 000000000..24f83d18b --- /dev/null +++ b/app/assets/javascripts/api/accounts/lookup.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss index ad05f5b7b..afb718c90 100644 --- a/app/assets/stylesheets/dashboard.scss +++ b/app/assets/stylesheets/dashboard.scss @@ -243,6 +243,7 @@ padding-bottom: 6px; font-size: 14px; font-family: 'Roboto', sans-serif; + color: #282c37; &:focus, &:active { border-bottom: 2px solid #2b90d9; diff --git a/app/controllers/api/accounts/lookup_controller.rb b/app/controllers/api/accounts/lookup_controller.rb new file mode 100644 index 000000000..dc8bcb132 --- /dev/null +++ b/app/controllers/api/accounts/lookup_controller.rb @@ -0,0 +1,11 @@ +class Api::Accounts::LookupController < ApplicationController + def index + @accounts = Account.where(domain: nil).where(username: lookup_params) + end + + private + + def lookup_params + (params[:usernames] || '').split(',').map(&:strip) + end +end diff --git a/app/helpers/api/accounts/lookup_helper.rb b/app/helpers/api/accounts/lookup_helper.rb new file mode 100644 index 000000000..5caf0e28c --- /dev/null +++ b/app/helpers/api/accounts/lookup_helper.rb @@ -0,0 +1,2 @@ +module Api::Accounts::LookupHelper +end diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index b044e8a61..28fc41ed5 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -27,4 +27,12 @@ module StreamEntriesHelper def favourited_by_me_class(status) user_signed_in? && current_user.account.favourited?(status) ? 'favourited' : '' end + + def content_for_status(actual_status) + if actual_status.local? + linkify(actual_status) + else + sanitize(actual_status.content, tags: %w(a br p), attributes: %w(href rel)) + end + end end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index ed86f2230..634653546 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -1,6 +1,8 @@ class BaseService - include RoutingHelper include ActionView::Helpers::TextHelper + include ActionView::Helpers::SanitizeHelper + + include RoutingHelper include ApplicationHelper include AtomBuilderHelper end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 3d94f1049..45814cfb5 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -4,18 +4,25 @@ class FanOutOnWriteService < BaseService # Push a status into home and mentions feeds # @param [Status] status def call(status) - replied_to_user = status.reply? ? status.thread.account : nil + deliver_to_self(status) if status.account.local? + deliver_to_followers(status, status.reply? ? status.thread.account : nil) + deliver_to_mentioned(status) + end - # Deliver to local self - push(:home, status.account.id, status) if status.account.local? + private - # Deliver to local followers + def deliver_to_self(status) + push(:home, status.account.id, status) + end + + def deliver_to_followers(status, replied_to_user) status.account.followers.each do |follower| next if (status.reply? && !(follower.id = replied_to_user.id || follower.following?(replied_to_user))) || !follower.local? push(:home, follower.id, status) end + end - # Deliver to local mentioned + def deliver_to_mentioned(status) status.mentioned_accounts.each do |mention| mentioned_account = mention.account next unless mentioned_account.local? @@ -23,8 +30,6 @@ class FanOutOnWriteService < BaseService end end - private - def push(type, receiver_id, status) redis.zadd(key(type, receiver_id), status.created_at.to_i, status.id) trim(type, receiver_id) diff --git a/app/services/send_interaction_service.rb b/app/services/send_interaction_service.rb index e6708498f..a425dcc8e 100644 --- a/app/services/send_interaction_service.rb +++ b/app/services/send_interaction_service.rb @@ -1,6 +1,4 @@ class SendInteractionService < BaseService - include AtomBuilderHelper - # Send an Atom representation of an interaction to a remote Salmon endpoint # @param [StreamEntry] stream_entry # @param [Account] target_account diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml index d7751a323..d107f5274 100644 --- a/app/views/accounts/_grid_card.html.haml +++ b/app/views/accounts/_grid_card.html.haml @@ -5,4 +5,4 @@ = link_to url_for_target(account) do %span.display_name= display_name(account) %span.username= "@#{account.acct}" - %p.note= truncate(account.note, length: 150) + %p.note= truncate(strip_tags(account.note), length: 150) diff --git a/app/views/api/accounts/lookup/index.rabl b/app/views/api/accounts/lookup/index.rabl new file mode 100644 index 000000000..f6ae172ed --- /dev/null +++ b/app/views/api/accounts/lookup/index.rabl @@ -0,0 +1,2 @@ +collection @accounts +extends('api/accounts/show') diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml index 72d99af6f..11a9ac8e0 100644 --- a/app/views/stream_entries/_status.html.haml +++ b/app/views/stream_entries/_status.html.haml @@ -33,8 +33,7 @@ .counter-btn{ class: favourited_by_me_class(status) } %i.fa.fa-star %span.counter-number= status.reblog? ? status.reblog.favourites_count : status.favourites_count - .content - = status.reblog? ? (status.reblog.local? ? linkify(status.reblog) : status.reblog.content.html_safe) : (status.local? ? linkify(status) : status.content.html_safe) + .content= content_for_status(status.reblog? ? status.reblog : status) - if include_threads - status.descendants.with_includes.with_counters.each do |status| diff --git a/config/routes.rb b/config/routes.rb index 2c7b3aa32..f40746f30 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,6 +47,10 @@ Rails.application.routes.draw do resources :follows, only: [:create] resources :accounts, only: [:show] do + collection do + get :lookup, to: 'accounts/lookup#index', as: :lookup + end + member do get :statuses get :followers diff --git a/spec/controllers/api/accounts/lookup_controller_spec.rb b/spec/controllers/api/accounts/lookup_controller_spec.rb new file mode 100644 index 000000000..30dee8a3d --- /dev/null +++ b/spec/controllers/api/accounts/lookup_controller_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +RSpec.describe Api::Accounts::LookupController, type: :controller do + let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) } + let(:token) { double acceptable?: true, resource_owner_id: user.id } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + before do + Fabricate(:account, username: 'alice') + Fabricate(:account, username: 'bob') + get :index, usernames: 'alice,bob' + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/helpers/api/accounts/lookup_helper_spec.rb b/spec/helpers/api/accounts/lookup_helper_spec.rb new file mode 100644 index 000000000..64ec826af --- /dev/null +++ b/spec/helpers/api/accounts/lookup_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the Api::Accounts::LookupHelper. For example: +# +# describe Api::Accounts::LookupHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe Api::Accounts::LookupHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end