Fix voters count field

Mastodon API demands this be null unless it’s a multi-selection poll.
Not abiding by this can mess up display in some clients.

Fixes: AkkomaGang/akkoma#190
This commit is contained in:
Oneric 2024-06-20 19:52:47 +02:00
parent ca182a0ae7
commit d488cf476e
4 changed files with 17 additions and 5 deletions

View file

@ -18,6 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Fixed ## Fixed
- Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results - Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results
- AP objects with additional JSON-LD profiles beyond ActivityStreams can now be fetched - AP objects with additional JSON-LD profiles beyond ActivityStreams can now be fetched
- Single-selection polls no longer expose the voter_count; MastoAPI demands it be null
and this confused some clients leading to vote distributions >100%
## Changed ## Changed
- Refactored Rich Media to cache the content in the database. Fetching operations that could block status rendering have been eliminated. - Refactored Rich Media to cache the content in the database. Fetching operations that could block status rendering have been eliminated.

View file

@ -32,7 +32,9 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Poll do
}, },
voters_count: %Schema{ voters_count: %Schema{
type: :integer, type: :integer,
description: "How many unique accounts have voted. Number." nullable: true,
description:
"How many unique accounts have voted for a multi-selection poll. Number, or null if single-selection poll."
}, },
voted: %Schema{ voted: %Schema{
type: :boolean, type: :boolean,

View file

@ -19,7 +19,7 @@ def render("show.json", %{object: object, multiple: multiple, options: options}
expired: expired, expired: expired,
multiple: multiple, multiple: multiple,
votes_count: votes_count, votes_count: votes_count,
voters_count: voters_count(object), voters_count: voters_count(multiple, object),
options: options, options: options,
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"]) emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"])
} }
@ -68,11 +68,19 @@ defp options_and_votes_count(options) do
end) end)
end end
defp voters_count(%{data: %{"voters" => voters}}) when is_list(voters) do defp voters_count(false, _poll_data) do
# Mastodon always sets voter count to "null" unless multiple options were selectable
# Some clients may rely on this to detect multiple selection polls and it can mess
# up percentages for some clients if we never got a correct remote voter count and
# only count local voters here; see https://akkoma.dev/AkkomaGang/akkoma/issues/190
nil
end
defp voters_count(_multiple, %{data: %{"voters" => voters}}) when is_list(voters) do
length(voters) length(voters)
end end
defp voters_count(_), do: 0 defp voters_count(_, _), do: 0
defp voted_and_own_votes(%{object: object} = params, options) do defp voted_and_own_votes(%{object: object} = params, options) do
if params[:for] do if params[:for] do

View file

@ -43,7 +43,7 @@ test "renders a poll" do
%{title: "why are you even asking?", votes_count: 0} %{title: "why are you even asking?", votes_count: 0}
], ],
votes_count: 0, votes_count: 0,
voters_count: 0 voters_count: nil
} }
result = PollView.render("show.json", %{object: object}) result = PollView.render("show.json", %{object: object})