Add REST compact mode for statuses
This commit is contained in:
parent
91d6b018df
commit
73df565bde
28 changed files with 559 additions and 257 deletions
|
@ -8,8 +8,14 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -42,6 +48,10 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
@account.permitted_statuses(current_account)
|
@account.permitted_statuses(current_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def only_media_scope
|
def only_media_scope
|
||||||
Status.include_expired.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
Status.include_expired.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
||||||
end
|
end
|
||||||
|
@ -71,7 +81,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
params.slice(:limit, :only_media, :exclude_replies, :compact).permit(:limit, :only_media, :exclude_replies, :compact).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
|
|
|
@ -7,8 +7,14 @@ class Api::V1::BookmarksController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -18,11 +24,11 @@ class Api::V1::BookmarksController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_bookmarks
|
def cached_bookmarks
|
||||||
cache_collection(Status.include_expired.where(id: results.pluck(:status_id)), Status)
|
cache_collection(results.map(&:status), Status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
@_results ||= account_bookmarks.joins('INNER JOIN statuses ON statuses.deleted_at IS NULL AND statuses.id = bookmarks.status_id').to_a_paginated_by_id(
|
@_results ||= account_bookmarks.joins(:status).eager_load(:status).to_a_paginated_by_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params_slice(:max_id, :since_id, :min_id)
|
||||||
)
|
)
|
||||||
|
@ -32,6 +38,10 @@ class Api::V1::BookmarksController < Api::BaseController
|
||||||
current_account.bookmarks
|
current_account.bookmarks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
@ -57,6 +67,6 @@ class Api::V1::BookmarksController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit, :compact).permit(:limi, :compact).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,8 +7,14 @@ class Api::V1::EmojiReactionsController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -18,11 +24,11 @@ class Api::V1::EmojiReactionsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_emoji_reactions
|
def cached_emoji_reactions
|
||||||
cache_collection(Status.include_expired.where(id: results.pluck(:status_id)), Status)
|
cache_collection(results.map(&:status), Status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
@_results ||= filtered_emoji_reactions.joins('INNER JOIN statuses ON statuses.deleted_at IS NULL AND statuses.id = emoji_reactions.status_id').to_a_paginated_by_id(
|
@_results ||= filtered_emoji_reactions.joins(:status).eager_load(:status).to_a_paginated_by_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params_slice(:max_id, :since_id, :min_id)
|
||||||
)
|
)
|
||||||
|
@ -38,6 +44,10 @@ class Api::V1::EmojiReactionsController < Api::BaseController
|
||||||
current_account.emoji_reactions
|
current_account.emoji_reactions
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
@ -70,7 +80,7 @@ class Api::V1::EmojiReactionsController < Api::BaseController
|
||||||
emoji_reactions = EmojiReaction.none
|
emoji_reactions = EmojiReaction.none
|
||||||
|
|
||||||
emoji_reactions_params[:emojis].each do |emoji|
|
emoji_reactions_params[:emojis].each do |emoji|
|
||||||
shortcode, domain = emoji.split("@")
|
shortcode, domain = emoji.split('@')
|
||||||
custom_emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain)
|
custom_emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain)
|
||||||
|
|
||||||
emoji_reactions = emoji_reactions.or(EmojiReaction.where(name: shortcode, custom_emoji: custom_emoji))
|
emoji_reactions = emoji_reactions.or(EmojiReaction.where(name: shortcode, custom_emoji: custom_emoji))
|
||||||
|
@ -80,7 +90,7 @@ class Api::V1::EmojiReactionsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit, :compact).permit(:limit, :compact).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reactions_params
|
def emoji_reactions_params
|
||||||
|
|
|
@ -7,8 +7,14 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -18,11 +24,11 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_favourites
|
def cached_favourites
|
||||||
cache_collection(Status.include_expired.where(id: results.pluck(:status_id)), Status)
|
cache_collection(results.map(&:status), Status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
@_results ||= account_favourites.joins('INNER JOIN statuses ON statuses.deleted_at IS NULL AND statuses.id = favourites.status_id').to_a_paginated_by_id(
|
@_results ||= account_favourites.joins(:status).eager_load(:status).to_a_paginated_by_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params_slice(:max_id, :since_id, :min_id)
|
||||||
)
|
)
|
||||||
|
@ -32,6 +38,10 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
current_account.favourites
|
current_account.favourites
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
@ -61,6 +71,6 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit, :compact).permit(:limit, :compact).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,8 +9,14 @@ class Api::V1::Statuses::ReferredByStatusesController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -20,7 +26,7 @@ class Api::V1::Statuses::ReferredByStatusesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_referred_by_statuses
|
def cached_referred_by_statuses
|
||||||
cache_collection(Status.where(id: results.pluck(:id)), Status)
|
cache_collection(results, Status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
|
@ -34,6 +40,10 @@ class Api::V1::Statuses::ReferredByStatusesController < Api::BaseController
|
||||||
@status.referred_by_statuses(current_user&.account)
|
@status.referred_by_statuses(current_user&.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
@ -66,6 +76,6 @@ class Api::V1::Statuses::ReferredByStatusesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit, :compact).permit(:limit, :compact).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,14 @@ class Api::V1::Timelines::GroupController < Api::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
|
||||||
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -48,6 +55,10 @@ class Api::V1::Timelines::GroupController < Api::BaseController
|
||||||
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,13 +7,14 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
|
|
||||||
render json: @statuses,
|
if compact?
|
||||||
each_serializer: REST::StatusSerializer,
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer, status: account_home_feed.regenerating? ? 206 : 200
|
||||||
relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id),
|
else
|
||||||
account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id),
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
status: account_home_feed.regenerating? ? 206 : 200
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id), status: account_home_feed.regenerating? ? 206 : 200
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -40,6 +41,10 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
HomeFeed.new(current_account)
|
HomeFeed.new(current_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,12 +9,13 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||||
|
|
||||||
def show
|
def show
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
render json: @statuses,
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
each_serializer: REST::StatusSerializer,
|
end
|
||||||
relationships: StatusRelationshipsPresenter.new(@statuses, current_user.account_id),
|
|
||||||
account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -44,6 +45,10 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||||
ListFeed.new(@list)
|
ListFeed.new(@list)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,9 +6,14 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -51,6 +56,10 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,14 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
accountIds = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(accountIds, current_user&.account_id)
|
if compact?
|
||||||
|
render json: CompactStatusesPresenter.new(statuses: @statuses), serializer: REST::CompactStatusesSerializer
|
||||||
|
else
|
||||||
|
account_ids = @statuses.filter(&:quote?).map { |status| status.quote.account_id }.uniq
|
||||||
|
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id), account_relationships: AccountRelationshipsPresenter.new(account_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -52,6 +58,10 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
true & (params[:without_bot].nil? && current_user&.setting_hide_bot_on_public_timeline || truthy_param?(:without_bot))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
set_pagination_headers(next_path, prev_path)
|
set_pagination_headers(next_path, prev_path)
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,12 +10,18 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@search = Search.new(search_results)
|
@search = Search.new(search_results)
|
||||||
render json: @search, serializer: REST::SearchSerializer
|
render json: @search, serializer: compact? ? REST::CompactSearchSerializer : REST::SearchSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def search_results
|
def search_results
|
||||||
|
search_service_results.tap do |results|
|
||||||
|
results[:statuses] = CompactStatusesPresenter.new(statuses: results[:statuses]) if compact?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_service_results
|
||||||
SearchService.new.call(
|
SearchService.new.call(
|
||||||
params[:q],
|
params[:q],
|
||||||
current_account,
|
current_account,
|
||||||
|
@ -24,7 +30,11 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compact?
|
||||||
|
truthy_param?(:compact)
|
||||||
|
end
|
||||||
|
|
||||||
def search_params
|
def search_params
|
||||||
params.permit(:type, :offset, :min_id, :max_id, :account_id, :with_profiles, :searchability)
|
params.permit(:type, :offset, :min_id, :max_id, :account_id, :with_profiles, :searchability, :compact)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -138,14 +138,11 @@ export function fetchAccountsFromStatuses(statuses) {
|
||||||
return fetchAccounts(
|
return fetchAccounts(
|
||||||
uniq(
|
uniq(
|
||||||
statuses
|
statuses
|
||||||
.flatMap(status => status.reblog ? status.reblog.emoji_reactions : status.emoji_reactions)
|
.map(status => status.reblog ? status.reblog : status)
|
||||||
.concat(
|
.flatMap(status => [status.emoji_reactions, status.quote?.emoji_reactions])
|
||||||
statuses
|
|
||||||
.flatMap(status => status.quote ? status.quote.emoji_reactions : null)
|
|
||||||
)
|
|
||||||
.flatMap(emoji_reaction => emoji_reaction?.account_ids)
|
.flatMap(emoji_reaction => emoji_reaction?.account_ids)
|
||||||
.filter(e => !!e)
|
.filter(e => !!e),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -671,7 +668,7 @@ export function fetchSubscribing(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(fetchSubscribeRequest(id));
|
dispatch(fetchSubscribeRequest(id));
|
||||||
|
|
||||||
api(getState).get(`/api/v1/accounts/subscribing`).then(response => {
|
api(getState).get('/api/v1/accounts/subscribing').then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
|
||||||
dispatch(importFetchedAccounts(response.data));
|
dispatch(importFetchedAccounts(response.data));
|
||||||
|
@ -761,13 +758,10 @@ export function fetchRelationshipsFromStatuses(statuses) {
|
||||||
return fetchRelationships(
|
return fetchRelationships(
|
||||||
uniq(
|
uniq(
|
||||||
statuses
|
statuses
|
||||||
.map(status => status.reblog ? status.reblog.account.id : status.account.id)
|
.map(status => status.reblog ? status.reblog : status)
|
||||||
.concat(
|
.flatMap(status => [status.account.id, status.quote?.account?.id])
|
||||||
statuses
|
.filter(e => !!e),
|
||||||
.map(status => status.quote ? status.quote.account.id : null)
|
),
|
||||||
)
|
|
||||||
.filter(e => !!e)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api';
|
||||||
import { importFetchedStatuses } from './importer';
|
import { importFetchedStatuses, importFetchedAccounts } from './importer';
|
||||||
import { uniq } from '../utils/uniq';
|
|
||||||
|
|
||||||
export const BOOKMARKED_STATUSES_FETCH_REQUEST = 'BOOKMARKED_STATUSES_FETCH_REQUEST';
|
export const BOOKMARKED_STATUSES_FETCH_REQUEST = 'BOOKMARKED_STATUSES_FETCH_REQUEST';
|
||||||
export const BOOKMARKED_STATUSES_FETCH_SUCCESS = 'BOOKMARKED_STATUSES_FETCH_SUCCESS';
|
export const BOOKMARKED_STATUSES_FETCH_SUCCESS = 'BOOKMARKED_STATUSES_FETCH_SUCCESS';
|
||||||
|
@ -19,13 +18,21 @@ export function fetchBookmarkedStatuses() {
|
||||||
|
|
||||||
dispatch(fetchBookmarkedStatusesRequest());
|
dispatch(fetchBookmarkedStatusesRequest());
|
||||||
|
|
||||||
api(getState).get('/api/v1/bookmarks').then(response => {
|
api(getState).get('/api/v1/bookmarks?compact=true').then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(fetchBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(fetchBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(fetchBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchBookmarkedStatusesFail(error));
|
dispatch(fetchBookmarkedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
@ -65,11 +72,19 @@ export function expandBookmarkedStatuses() {
|
||||||
|
|
||||||
api(getState).get(url).then(response => {
|
api(getState).get(url).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(expandBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(expandBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(expandBookmarkedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(expandBookmarkedStatusesFail(error));
|
dispatch(expandBookmarkedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api';
|
||||||
import { importFetchedStatuses } from './importer';
|
import { importFetchedStatuses, importFetchedAccounts } from './importer';
|
||||||
import { uniq } from '../utils/uniq';
|
|
||||||
|
|
||||||
export const EMOJI_REACTIONED_STATUSES_FETCH_REQUEST = 'EMOJI_REACTIONED_STATUSES_FETCH_REQUEST';
|
export const EMOJI_REACTIONED_STATUSES_FETCH_REQUEST = 'EMOJI_REACTIONED_STATUSES_FETCH_REQUEST';
|
||||||
export const EMOJI_REACTIONED_STATUSES_FETCH_SUCCESS = 'EMOJI_REACTIONED_STATUSES_FETCH_SUCCESS';
|
export const EMOJI_REACTIONED_STATUSES_FETCH_SUCCESS = 'EMOJI_REACTIONED_STATUSES_FETCH_SUCCESS';
|
||||||
|
@ -19,13 +18,21 @@ export function fetchEmojiReactionedStatuses() {
|
||||||
|
|
||||||
dispatch(fetchEmojiReactionedStatusesRequest());
|
dispatch(fetchEmojiReactionedStatusesRequest());
|
||||||
|
|
||||||
api(getState).get('/api/v1/emoji_reactions').then(response => {
|
api(getState).get('/api/v1/emoji_reactions?compact=true').then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(fetchEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(fetchEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(fetchEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchEmojiReactionedStatusesFail(error));
|
dispatch(fetchEmojiReactionedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
@ -65,11 +72,19 @@ export function expandEmojiReactionedStatuses() {
|
||||||
|
|
||||||
api(getState).get(url).then(response => {
|
api(getState).get(url).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(expandEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(expandEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(expandEmojiReactionedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(expandEmojiReactionedStatusesFail(error));
|
dispatch(expandEmojiReactionedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api';
|
||||||
import { importFetchedStatuses } from './importer';
|
import { importFetchedStatuses, importFetchedAccounts } from './importer';
|
||||||
import { uniq } from '../utils/uniq';
|
|
||||||
|
|
||||||
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
|
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
|
||||||
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
|
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
|
||||||
|
@ -19,13 +18,21 @@ export function fetchFavouritedStatuses() {
|
||||||
|
|
||||||
dispatch(fetchFavouritedStatusesRequest());
|
dispatch(fetchFavouritedStatusesRequest());
|
||||||
|
|
||||||
api(getState).get('/api/v1/favourites').then(response => {
|
api(getState).get('/api/v1/favourites?compact=true').then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(fetchFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(fetchFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(fetchFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchFavouritedStatusesFail(error));
|
dispatch(fetchFavouritedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
@ -68,11 +75,19 @@ export function expandFavouritedStatuses() {
|
||||||
|
|
||||||
api(getState).get(url).then(response => {
|
api(getState).get(url).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(expandFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(expandFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
dispatch(expandFavouritedStatusesSuccess(statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(expandFavouritedStatusesFail(error));
|
dispatch(expandFavouritedStatusesFail(error));
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,20 +63,21 @@ export function importFetchedStatuses(statuses) {
|
||||||
const polls = [];
|
const polls = [];
|
||||||
|
|
||||||
function processStatus(status) {
|
function processStatus(status) {
|
||||||
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
|
|
||||||
pushUnique(accounts, status.account);
|
|
||||||
|
|
||||||
if (status.reblog && status.reblog.id) {
|
|
||||||
processStatus(status.reblog);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.quote && status.quote.id) {
|
|
||||||
processStatus(status.quote);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.poll && status.poll.id) {
|
if (status.poll && status.poll.id) {
|
||||||
pushUnique(polls, normalizePoll(status.poll));
|
pushUnique(polls, normalizePoll(status.poll));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof status.account === 'object') {
|
||||||
|
pushUnique(accounts, status.account);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.reblog && status.reblog.id) {
|
||||||
|
processStatus(status.reblog);
|
||||||
|
} else if (status.quote && status.quote.id) {
|
||||||
|
processStatus(status.quote);
|
||||||
|
}
|
||||||
|
|
||||||
|
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
|
||||||
}
|
}
|
||||||
|
|
||||||
statuses.forEach(processStatus);
|
statuses.forEach(processStatus);
|
||||||
|
|
|
@ -44,7 +44,9 @@ export function normalizeAccount(account) {
|
||||||
|
|
||||||
export function normalizeStatus(status, normalOldStatus) {
|
export function normalizeStatus(status, normalOldStatus) {
|
||||||
const normalStatus = { ...status };
|
const normalStatus = { ...status };
|
||||||
|
if (typeof status.account === 'object') {
|
||||||
normalStatus.account = status.account.id;
|
normalStatus.account = status.account.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (status.reblog && status.reblog.id) {
|
if (status.reblog && status.reblog.id) {
|
||||||
normalStatus.reblog = status.reblog.id;
|
normalStatus.reblog = status.reblog.id;
|
||||||
|
@ -64,7 +66,6 @@ export function normalizeStatus(status, normalOldStatus) {
|
||||||
normalStatus.spoiler_text = normalOldStatus.get('spoiler_text');
|
normalStatus.spoiler_text = normalOldStatus.get('spoiler_text');
|
||||||
normalStatus.hidden = normalOldStatus.get('hidden');
|
normalStatus.hidden = normalOldStatus.get('hidden');
|
||||||
normalStatus.visibility = normalOldStatus.get('visibility');
|
normalStatus.visibility = normalOldStatus.get('visibility');
|
||||||
normalStatus.quote = normalOldStatus.get('quote');
|
|
||||||
normalStatus.quote_hidden = normalOldStatus.get('quote_hidden');
|
normalStatus.quote_hidden = normalOldStatus.get('quote_hidden');
|
||||||
} else {
|
} else {
|
||||||
// If the status has a CW but no contents, treat the CW as if it were the
|
// If the status has a CW but no contents, treat the CW as if it were the
|
||||||
|
@ -88,29 +89,7 @@ export function normalizeStatus(status, normalOldStatus) {
|
||||||
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
|
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
|
||||||
normalStatus.hidden = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive;
|
normalStatus.hidden = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive;
|
||||||
normalStatus.visibility = normalStatus.visibility_ex ? normalStatus.visibility_ex : normalStatus.visibility;
|
normalStatus.visibility = normalStatus.visibility_ex ? normalStatus.visibility_ex : normalStatus.visibility;
|
||||||
|
normalStatus.quote = null;
|
||||||
if (status.quote && status.quote.id) {
|
|
||||||
const quote_spoilerText = status.quote.spoiler_text || '';
|
|
||||||
const quote_searchContent = [quote_spoilerText, status.quote.content].join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
|
|
||||||
|
|
||||||
const quote_emojiMap = makeEmojiMap(normalStatus.quote);
|
|
||||||
|
|
||||||
const quote_account_emojiMap = makeEmojiMap(status.quote.account);
|
|
||||||
const displayName = normalStatus.quote.account.display_name.length === 0 ? normalStatus.quote.account.username : normalStatus.quote.account.display_name;
|
|
||||||
normalStatus.quote.account.display_name_html = emojify(escapeTextContentForBrowser(displayName), quote_account_emojiMap);
|
|
||||||
normalStatus.quote.search_index = domParser.parseFromString(quote_searchContent, 'text/html').documentElement.textContent;
|
|
||||||
let docElem = domParser.parseFromString(normalStatus.quote.content, 'text/html').documentElement;
|
|
||||||
Array.from(docElem.querySelectorAll('p,br'), line => {
|
|
||||||
let parentNode = line.parentNode;
|
|
||||||
if (line.nextSibling) {
|
|
||||||
parentNode.insertBefore(document.createTextNode(' '), line.nextSibling);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let _contentHtml = docElem.textContent;
|
|
||||||
normalStatus.quote.contentHtml = '<p>'+emojify(_contentHtml.substr(0, 150), quote_emojiMap) + (_contentHtml.substr(150) ? '...' : '')+'</p>';
|
|
||||||
normalStatus.quote.spoilerHtml = emojify(escapeTextContentForBrowser(quote_spoilerText), quote_emojiMap);
|
|
||||||
normalStatus.quote_hidden = expandSpoilers ? false : quote_spoilerText.length > 0 || normalStatus.quote.sensitive;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalStatus;
|
return normalStatus;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api';
|
||||||
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
|
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
|
||||||
import { fetchRelationships, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationships, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
||||||
import { me } from '../initial_state';
|
import { me } from '../initial_state';
|
||||||
|
|
||||||
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
|
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
|
||||||
|
@ -567,13 +567,21 @@ export function fetchReferredByStatuses(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(fetchReferredByStatusesRequest(id));
|
dispatch(fetchReferredByStatusesRequest(id));
|
||||||
|
|
||||||
api(getState).get(`/api/v1/statuses/${id}/referred_by`).then(response => {
|
api(getState).get(`/api/v1/statuses/${id}/referred_by?compact=true`).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(fetchReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(fetchReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
dispatch(fetchReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(fetchReferredByStatusesFail(id, error));
|
dispatch(fetchReferredByStatusesFail(id, error));
|
||||||
});
|
});
|
||||||
|
@ -616,11 +624,19 @@ export function expandReferredByStatuses(id) {
|
||||||
|
|
||||||
api(getState).get(url).then(response => {
|
api(getState).get(url).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(expandReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(expandReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
dispatch(expandReferredByStatusesSuccess(id, statuses, next ? next.uri : null));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(expandReferredByStatusesFail(id, error));
|
dispatch(expandReferredByStatusesFail(id, error));
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
import { fetchRelationships, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationships, fetchAccountsFromStatuses } from './accounts';
|
||||||
import { importFetchedAccounts, importFetchedStatuses } from './importer';
|
import { importFetchedAccounts, importFetchedStatuses } from './importer';
|
||||||
|
|
||||||
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
|
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
|
||||||
|
@ -44,6 +44,7 @@ export function submitSearch() {
|
||||||
resolve: true,
|
resolve: true,
|
||||||
limit: 5,
|
limit: 5,
|
||||||
with_profiles: true,
|
with_profiles: true,
|
||||||
|
compact: true,
|
||||||
},
|
},
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (response.data.accounts) {
|
if (response.data.accounts) {
|
||||||
|
@ -55,9 +56,17 @@ export function submitSearch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.data.statuses) {
|
if (response.data.statuses) {
|
||||||
|
if (response.data.statuses.statuses && response.data.statuses.accounts) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data.statuses;
|
||||||
|
response.data.statuses = statuses;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
} else {
|
||||||
dispatch(importFetchedStatuses(response.data.statuses));
|
dispatch(importFetchedStatuses(response.data.statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(response.data.statuses));
|
dispatch(fetchAccountsFromStatuses(response.data.statuses));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(fetchSearchSuccess(response.data, value));
|
dispatch(fetchSearchSuccess(response.data, value));
|
||||||
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
|
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
|
||||||
|
@ -101,6 +110,7 @@ export const expandSearch = type => (dispatch, getState) => {
|
||||||
type,
|
type,
|
||||||
offset,
|
offset,
|
||||||
with_profiles: true,
|
with_profiles: true,
|
||||||
|
compact: true,
|
||||||
},
|
},
|
||||||
}).then(({ data }) => {
|
}).then(({ data }) => {
|
||||||
if (data.accounts) {
|
if (data.accounts) {
|
||||||
|
@ -112,9 +122,17 @@ export const expandSearch = type => (dispatch, getState) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.statuses) {
|
if (data.statuses) {
|
||||||
|
if (data.statuses.statuses && data.statuses.accounts) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = data.statuses;
|
||||||
|
data.statuses = statuses;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
} else {
|
||||||
dispatch(importFetchedStatuses(data.statuses));
|
dispatch(importFetchedStatuses(data.statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(data.statuses));
|
dispatch(fetchAccountsFromStatuses(data.statuses));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(expandSearchSuccess(data, value, type));
|
dispatch(expandSearchSuccess(data, value, type));
|
||||||
dispatch(fetchRelationships(data.accounts.map(item => item.id)));
|
dispatch(fetchRelationships(data.accounts.map(item => item.id)));
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { fetchRelationshipsFromStatus, fetchAccountsFromStatus, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
import { fetchRelationshipsSuccess, fetchRelationshipsFromStatus, fetchAccountsFromStatus, fetchRelationshipsFromStatuses, fetchAccountsFromStatuses } from './accounts';
|
||||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
import { importFetchedStatus, importFetchedStatuses, importFetchedAccounts } from './importer';
|
||||||
import { submitMarkers } from './markers';
|
import { submitMarkers } from './markers';
|
||||||
import api, { getLinks } from 'mastodon/api';
|
import api, { getLinks } from 'mastodon/api';
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||||
import compareId from 'mastodon/compare_id';
|
import compareId from 'mastodon/compare_id';
|
||||||
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
|
import { usePendingItems as preferPendingItems, show_follow_button_on_timeline, show_subscribe_button_on_timeline } from 'mastodon/initial_state';
|
||||||
import { getHomeVisibilities, getLimitedVisibilities } from 'mastodon/selectors';
|
import { getHomeVisibilities, getLimitedVisibilities } from 'mastodon/selectors';
|
||||||
|
|
||||||
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
||||||
|
@ -42,8 +42,12 @@ export function updateTimeline(timeline, status, accept) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(importFetchedStatus(status));
|
dispatch(importFetchedStatus(status));
|
||||||
|
if (show_follow_button_on_timeline || show_subscribe_button_on_timeline || status.quote_id) {
|
||||||
dispatch(fetchRelationshipsFromStatus(status));
|
dispatch(fetchRelationshipsFromStatus(status));
|
||||||
|
}
|
||||||
|
if (status.emoji_reactions.length) {
|
||||||
dispatch(fetchAccountsFromStatus(status));
|
dispatch(fetchAccountsFromStatus(status));
|
||||||
|
}
|
||||||
|
|
||||||
const insertTimeline = timeline => {
|
const insertTimeline = timeline => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -140,17 +144,27 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.compact = true;
|
||||||
|
|
||||||
const isLoadingRecent = !!params.since_id;
|
const isLoadingRecent = !!params.since_id;
|
||||||
|
|
||||||
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
|
dispatch(expandTimelineRequest(timelineId, isLoadingMore));
|
||||||
|
|
||||||
api(getState).get(path, { params }).then(response => {
|
api(getState).get(path, { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
if ('statuses' in response.data && 'accounts' in response.data) {
|
||||||
|
const { statuses, referenced_statuses, accounts, relationships } = response.data;
|
||||||
|
dispatch(importFetchedStatuses(statuses.concat(referenced_statuses)));
|
||||||
|
dispatch(importFetchedAccounts(accounts));
|
||||||
|
dispatch(fetchRelationshipsSuccess(relationships));
|
||||||
|
dispatch(expandTimelineSuccess(timelineId, statuses, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
|
||||||
|
} else {
|
||||||
const statuses = response.data;
|
const statuses = response.data;
|
||||||
dispatch(importFetchedStatuses(statuses));
|
dispatch(importFetchedStatuses(statuses));
|
||||||
dispatch(fetchRelationshipsFromStatuses(statuses));
|
dispatch(fetchRelationshipsFromStatuses(statuses));
|
||||||
dispatch(fetchAccountsFromStatuses(statuses));
|
dispatch(fetchAccountsFromStatuses(statuses));
|
||||||
dispatch(expandTimelineSuccess(timelineId, statuses, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
|
dispatch(expandTimelineSuccess(timelineId, statuses, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
|
||||||
|
}
|
||||||
|
|
||||||
if (timelineId === 'home') {
|
if (timelineId === 'home') {
|
||||||
dispatch(submitMarkers());
|
dispatch(submitMarkers());
|
||||||
|
|
|
@ -37,12 +37,6 @@ import {
|
||||||
UNPIN_SUCCESS,
|
UNPIN_SUCCESS,
|
||||||
} from '../actions/interactions';
|
} from '../actions/interactions';
|
||||||
|
|
||||||
const initialListState = ImmutableMap({
|
|
||||||
next: null,
|
|
||||||
isLoading: false,
|
|
||||||
items: ImmutableList(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
favourites: ImmutableMap({
|
favourites: ImmutableMap({
|
||||||
next: null,
|
next: null,
|
||||||
|
|
|
@ -86,62 +86,56 @@ export const getFiltersRegex = makeGetFiltersRegex();
|
||||||
export const makeGetStatus = () => {
|
export const makeGetStatus = () => {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
[
|
[
|
||||||
(state, { id }) => state.getIn(['statuses', id]),
|
(state, { id }) => state.getIn(['statuses', id], null),
|
||||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account']), 'moved'], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
|
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', id, 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
|
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account'])]),
|
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote', 'account'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', id, 'account'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account']), 'moved'], null),
|
||||||
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
|
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account'])]),
|
|
||||||
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote', 'account'])]),
|
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id'])], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['accounts', state.getIn(['statuses', id, 'account']), 'moved'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account']), 'moved'])]),
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account']), 'moved'], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account']), 'moved'])]),
|
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', id, 'quote_id']), 'account'])], null),
|
||||||
(state, { id }) => state.getIn(['accounts', state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote', 'account']), 'moved'])]),
|
|
||||||
|
(state, { id }) => state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id'])], null),
|
||||||
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id']), 'account'])], null),
|
||||||
|
(state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id']), 'account']), 'moved'], null),
|
||||||
|
(state, { id }) => state.getIn(['relationships', state.getIn(['statuses', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'quote_id']), 'account'])], null),
|
||||||
|
|
||||||
getFiltersRegex,
|
getFiltersRegex,
|
||||||
],
|
],
|
||||||
|
|
||||||
(statusBase, statusReblog, statusQuote, accountBase, accountReblog, accountQuote, accountReblogQuote, relationship, reblogRelationship, quoteRelationship, reblogQuoteRelationship, moved, reblogMoved, quoteMoved, reblogQuoteMoved, filtersRegex) => {
|
(
|
||||||
if (!statusBase) {
|
statusBase,
|
||||||
|
accountBase,
|
||||||
|
moved,
|
||||||
|
relationship,
|
||||||
|
|
||||||
|
statusReblog,
|
||||||
|
accountReblog,
|
||||||
|
reblogMoved,
|
||||||
|
reblogRelationship,
|
||||||
|
|
||||||
|
statusQuote,
|
||||||
|
accountQuote,
|
||||||
|
quoteMoved,
|
||||||
|
quoteRelationship,
|
||||||
|
|
||||||
|
statusReblogQuote,
|
||||||
|
accountReblogQuote,
|
||||||
|
reblogQuoteMoved,
|
||||||
|
reblogQuoteRelationship,
|
||||||
|
|
||||||
|
filtersRegex,
|
||||||
|
) => {
|
||||||
|
if (!statusBase || !accountBase) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
accountBase = accountBase.withMutations(map => {
|
|
||||||
map.set('relationship', relationship);
|
|
||||||
map.set('moved', moved);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (statusReblog) {
|
|
||||||
accountReblog = accountReblog.withMutations(map => {
|
|
||||||
map.set('relationship', reblogRelationship);
|
|
||||||
map.set('moved', reblogMoved);
|
|
||||||
});
|
|
||||||
statusReblog = statusReblog.set('account', accountReblog);
|
|
||||||
} else {
|
|
||||||
statusReblog = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusQuote) {
|
|
||||||
accountQuote = accountQuote.withMutations(map => {
|
|
||||||
map.set('relationship', quoteRelationship);
|
|
||||||
map.set('moved', quoteMoved);
|
|
||||||
});
|
|
||||||
statusQuote = statusQuote.set('account', accountQuote);
|
|
||||||
} else {
|
|
||||||
statusQuote = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusReblog && accountReblogQuote) {
|
|
||||||
accountReblogQuote = accountReblog.withMutations(map => {
|
|
||||||
map.set('relationship', reblogQuoteRelationship);
|
|
||||||
map.set('moved', reblogQuoteMoved);
|
|
||||||
});
|
|
||||||
statusReblog = statusReblog.setIn(['quote', 'account'], accountReblogQuote);
|
|
||||||
}
|
|
||||||
|
|
||||||
const dropRegex = (accountReblog || accountBase).get('id') !== me && filtersRegex[0];
|
const dropRegex = (accountReblog || accountBase).get('id') !== me && filtersRegex[0];
|
||||||
if (dropRegex && dropRegex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'))) {
|
if (dropRegex && dropRegex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'))) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -150,12 +144,50 @@ export const makeGetStatus = () => {
|
||||||
const regex = (accountReblog || accountBase).get('id') !== me && filtersRegex[1];
|
const regex = (accountReblog || accountBase).get('id') !== me && filtersRegex[1];
|
||||||
const filtered = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'));
|
const filtered = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'));
|
||||||
|
|
||||||
return statusBase.withMutations(map => {
|
if (statusReblogQuote && accountReblogQuote) {
|
||||||
|
accountReblogQuote = accountReblogQuote.withMutations(map => {
|
||||||
|
map.set('relationship', reblogQuoteRelationship);
|
||||||
|
map.set('moved', reblogQuoteMoved);
|
||||||
|
});
|
||||||
|
statusReblogQuote = statusReblogQuote.withMutations(map => {
|
||||||
|
map.set('account', accountReblogQuote);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusReblog && accountReblog) {
|
||||||
|
accountReblog = accountReblog.withMutations(map => {
|
||||||
|
map.set('relationship', reblogRelationship);
|
||||||
|
map.set('moved', reblogMoved);
|
||||||
|
});
|
||||||
|
statusReblog = statusReblog.withMutations(map => {
|
||||||
|
map.set('quote', statusReblogQuote);
|
||||||
|
map.set('account', accountReblog);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusQuote && accountQuote) {
|
||||||
|
accountQuote = accountQuote.withMutations(map => {
|
||||||
|
map.set('relationship', quoteRelationship);
|
||||||
|
map.set('moved', quoteMoved);
|
||||||
|
});
|
||||||
|
statusQuote = statusQuote.withMutations(map => {
|
||||||
|
map.set('account', accountQuote);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
accountBase = accountBase.withMutations(map => {
|
||||||
|
map.set('relationship', relationship);
|
||||||
|
map.set('moved', moved);
|
||||||
|
});
|
||||||
|
|
||||||
|
statusBase = statusBase.withMutations(map => {
|
||||||
map.set('reblog', statusReblog);
|
map.set('reblog', statusReblog);
|
||||||
map.set('quote', statusQuote);
|
map.set('quote', statusQuote);
|
||||||
map.set('account', accountBase);
|
map.set('account', accountBase);
|
||||||
map.set('filtered', filtered);
|
map.set('filtered', filtered);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return statusBase;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,10 +44,7 @@ class Status < ApplicationRecord
|
||||||
|
|
||||||
# If `override_timestamps` is set at creation time, Snowflake ID creation
|
# If `override_timestamps` is set at creation time, Snowflake ID creation
|
||||||
# will be based on current time instead of `created_at`
|
# will be based on current time instead of `created_at`
|
||||||
attr_accessor :override_timestamps
|
attr_accessor :override_timestamps, :circle, :expires_at, :expires_action
|
||||||
|
|
||||||
attr_accessor :circle
|
|
||||||
attr_accessor :expires_at, :expires_action
|
|
||||||
|
|
||||||
update_index('statuses', :proper)
|
update_index('statuses', :proper)
|
||||||
|
|
||||||
|
@ -335,6 +332,19 @@ class Status < ApplicationRecord
|
||||||
status_stat&.status_referred_by_count || 0
|
status_stat&.status_referred_by_count || 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def account_ids(recursive: true)
|
||||||
|
ids = (Oj.load(status_stat&.emoji_reactions_cache || '', mode: :strict) || []).flat_map { |emoji_reaction| emoji_reaction['account_ids'] }
|
||||||
|
ids << account_id.to_s
|
||||||
|
|
||||||
|
if recursive
|
||||||
|
ids.concat(quote.account_ids(recursive: false)) unless quote.nil?
|
||||||
|
ids.concat(reblog.account_ids(recursive: false)) unless reblog.nil?
|
||||||
|
ids.concat(reblog.quote.account_ids(recursive: false)) unless reblog&.quote.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
ids.uniq
|
||||||
|
end
|
||||||
|
|
||||||
def grouped_emoji_reactions(account = nil)
|
def grouped_emoji_reactions(account = nil)
|
||||||
(Oj.load(status_stat&.emoji_reactions_cache || '', mode: :strict) || []).tap do |emoji_reactions|
|
(Oj.load(status_stat&.emoji_reactions_cache || '', mode: :strict) || []).tap do |emoji_reactions|
|
||||||
if account.present?
|
if account.present?
|
||||||
|
@ -513,13 +523,12 @@ class Status < ApplicationRecord
|
||||||
return [] if text.blank?
|
return [] if text.blank?
|
||||||
|
|
||||||
text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.filter_map do |url|
|
text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.filter_map do |url|
|
||||||
status = begin
|
status =
|
||||||
if TagManager.instance.local_url?(url)
|
if TagManager.instance.local_url?(url)
|
||||||
ActivityPub::TagManager.instance.uri_to_resource(url, Status)
|
ActivityPub::TagManager.instance.uri_to_resource(url, Status)
|
||||||
else
|
else
|
||||||
EntityCache.instance.status(url)
|
EntityCache.instance.status(url)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
status&.distributable? ? status : nil
|
status&.distributable? ? status : nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
5
app/presenters/compact_statuses_presenter.rb
Normal file
5
app/presenters/compact_statuses_presenter.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CompactStatusesPresenter < ActiveModelSerializers::Model
|
||||||
|
attributes :statuses
|
||||||
|
end
|
8
app/serializers/rest/compact_search_serializer.rb
Normal file
8
app/serializers/rest/compact_search_serializer.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class REST::CompactSearchSerializer < ActiveModel::Serializer
|
||||||
|
has_many :accounts, serializer: REST::AccountSerializer
|
||||||
|
has_one :statuses, serializer: REST::CompactStatusesSerializer
|
||||||
|
has_many :hashtags, serializer: REST::TagSerializer
|
||||||
|
has_many :profiles, serializer: REST::AccountSerializer
|
||||||
|
end
|
58
app/serializers/rest/compact_statuses_serializer.rb
Normal file
58
app/serializers/rest/compact_statuses_serializer.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class REST::CompactStatusesSerializer < ActiveModel::Serializer
|
||||||
|
attribute :statuses
|
||||||
|
attribute :referenced_statuses
|
||||||
|
attribute :accounts
|
||||||
|
attribute :relationships
|
||||||
|
|
||||||
|
def current_user?
|
||||||
|
!current_user.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses
|
||||||
|
object.statuses.map do |status|
|
||||||
|
REST::StatusSerializer.new(status, root: false, relationships: status_relationships, account_relationships: account_relationships, compact: true, scope: current_user, scope_name: :current_user)
|
||||||
|
end || []
|
||||||
|
end
|
||||||
|
|
||||||
|
def referenced_statuses
|
||||||
|
Status.where(id: referenced_status_ids).map do |status|
|
||||||
|
REST::StatusSerializer.new(status, root: false, relationships: status_relationships, account_relationships: account_relationships, compact: true, scope: current_user, scope_name: :current_user)
|
||||||
|
end || []
|
||||||
|
end
|
||||||
|
|
||||||
|
def accounts
|
||||||
|
source_accounts.map do |account|
|
||||||
|
REST::AccountSerializer.new(account, root: false, scope: current_user, scope_name: :current_user)
|
||||||
|
end || []
|
||||||
|
end
|
||||||
|
|
||||||
|
def relationships
|
||||||
|
return [] unless current_user?
|
||||||
|
|
||||||
|
source_accounts.map do |account|
|
||||||
|
REST::RelationshipSerializer.new(account, root: false, relationships: account_relationships, scope: current_user, scope_name: :current_user)
|
||||||
|
end || []
|
||||||
|
end
|
||||||
|
|
||||||
|
def referenced_status_ids
|
||||||
|
@referenced_status_ids ||= object.statuses.flat_map { |status| [status.reblog_of_id, status.quote_id, status.reblog&.quote_id] }.compact.uniq - object.statuses.pluck(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_accounts
|
||||||
|
@source_accounts ||= Account.where(id: source_accounts_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_accounts_ids
|
||||||
|
@source_accounts_ids ||= object.statuses.flat_map(&:account_ids).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_relationships
|
||||||
|
@status_relationships ||= StatusRelationshipsPresenter.new(object.statuses, current_user&.account_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_relationships
|
||||||
|
@account_relationships ||= AccountRelationshipsPresenter.new(source_accounts_ids, current_user&.account_id)
|
||||||
|
end
|
||||||
|
end
|
|
@ -135,6 +135,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
||||||
:misskey_location,
|
:misskey_location,
|
||||||
:status_reference,
|
:status_reference,
|
||||||
:searchability,
|
:searchability,
|
||||||
|
:status_compact_mode,
|
||||||
]
|
]
|
||||||
|
|
||||||
capabilities << :profile_search unless Chewy.enabled?
|
capabilities << :profile_search unless Chewy.enabled?
|
||||||
|
|
|
@ -24,13 +24,14 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
attribute :quote_id, if: :quote?
|
attribute :quote_id, if: :quote?
|
||||||
|
|
||||||
attribute :expires_at, if: :has_expires?
|
attribute :expires_at, if: :expires?
|
||||||
attribute :expires_action, if: :has_expires?
|
attribute :expires_action, if: :expires?
|
||||||
attribute :visibility_ex, if: :visibility_ex?
|
attribute :visibility_ex, if: :visibility_ex?
|
||||||
|
|
||||||
belongs_to :reblog, serializer: REST::StatusSerializer
|
attribute :account
|
||||||
|
attribute :reblog
|
||||||
|
|
||||||
belongs_to :application, if: :show_application?
|
belongs_to :application, if: :show_application?
|
||||||
belongs_to :account, serializer: REST::AccountSerializer
|
|
||||||
|
|
||||||
has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
|
has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
|
||||||
has_many :ordered_mentions, key: :mentions
|
has_many :ordered_mentions, key: :mentions
|
||||||
|
@ -40,6 +41,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
||||||
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
||||||
|
|
||||||
|
delegate :quote?, to: :object
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
end
|
end
|
||||||
|
@ -56,6 +59,24 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
object.quote_id.to_s
|
object.quote_id.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def account
|
||||||
|
if instance_options[:compact]
|
||||||
|
object.account.id.to_s
|
||||||
|
else
|
||||||
|
REST::AccountSerializer.new(object.account, root: false, scope: current_user, scope_name: :current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reblog
|
||||||
|
if object.reblog.nil?
|
||||||
|
nil
|
||||||
|
elsif instance_options[:compact]
|
||||||
|
object.reblog.id.to_s
|
||||||
|
else
|
||||||
|
REST::StatusSerializer.new(object.reblog, root: false, relationships: instance_options[:relationships], account_relationships: instance_options[:account_relationships], compact: false, scope: current_user, scope_name: :current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def current_user?
|
def current_user?
|
||||||
!current_user.nil?
|
!current_user.nil?
|
||||||
end
|
end
|
||||||
|
@ -68,11 +89,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
object.account.user_shows_application? || owned_status?
|
object.account.user_shows_application? || owned_status?
|
||||||
end
|
end
|
||||||
|
|
||||||
def quote?
|
def expires?
|
||||||
object.quote?
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_expires?
|
|
||||||
object.expires? || object.expired?
|
object.expires? || object.expired?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -265,9 +282,20 @@ class REST::NestedQuoteSerializer < REST::StatusSerializer
|
||||||
current_user.account.muting?(object.account) || object.account.blocking?(current_user.account) || current_user.account.blocking?(object.account) || current_user.account.domain_blocking?(object.account.domain)
|
current_user.account.muting?(object.account) || object.account.blocking?(current_user.account) || current_user.account.blocking?(object.account) || current_user.account.domain_blocking?(object.account.domain)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class REST::StatusSerializer < ActiveModel::Serializer
|
class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
belongs_to :quote, serializer: REST::NestedQuoteSerializer
|
attribute :quote
|
||||||
|
|
||||||
|
def quote
|
||||||
|
if object.quote.nil?
|
||||||
|
nil
|
||||||
|
elsif instance_options[:compact]
|
||||||
|
object.quote.id.to_s
|
||||||
|
else
|
||||||
|
REST::NestedQuoteSerializer.new(object.quote, root: false, relationships: instance_options[:relationships], account_relationships: instance_options[:account_relationships], compact: false, scope: current_user, scope_name: :current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue