- |> add_if_present(params, "header", :banner, fn value ->
- with %Plug.Upload{} <- value,
- {:ok, object} <- ActivityPub.upload(value, type: :banner) do
- {:ok, object.data}
- end
- end)
- |> add_if_present(params, "pleroma_background_image", :background, fn value ->
- with %Plug.Upload{} <- value,
- {:ok, object} <- ActivityPub.upload(value, type: :background) do
- {:ok, object.data}
- end
- end)
- |> add_if_present(params, "fields_attributes", :fields, fn fields ->
- fields = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
-
- {:ok, fields}
- end)
- |> add_if_present(params, "fields_attributes", :raw_fields)
- |> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
- {:ok, Map.merge(user.pleroma_settings_store, value)}
- end)
- |> add_if_present(params, "default_scope", :default_scope)
- |> add_if_present(params, "actor_type", :actor_type)
-
- emojis_text = (user_params["display_name"] || "") <> (user_params["note"] || "")
-
- user_emojis =
- user
- |> Map.get(:emoji, [])
- |> Enum.concat(Emoji.Formatter.get_emoji_map(emojis_text))
- |> Enum.dedup()
-
- user_params = Map.put(user_params, :emoji, user_emojis)
- changeset = User.update_changeset(user, user_params)
-
- with {:ok, user} <- User.update_and_set_cache(changeset) do
- if original_user != user, do: CommonAPI.update(user)
-
- render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
+ |> Maps.put_if_present(:actor_type, params[:actor_type])
+
+ # What happens here:
+ #
+ # We want to update the user through the pipeline, but the ActivityPub
+ # update information is not quite enough for this, because this also
+ # contains local settings that don't federate and don't even appear
+ # in the Update activity.
+ #
+ # So we first build the normal local changeset, then apply it to the
+ # user data, but don't persist it. With this, we generate the object
+ # data for our update activity. We feed this and the changeset as meta
+ # inforation into the pipeline, where they will be properly updated and
+ # federated.
+ with changeset <- User.update_changeset(user, user_params),
+ {:ok, unpersisted_user} <- Ecto.Changeset.apply_action(changeset, :update),
+ updated_object <-
+ Pleroma.Web.ActivityPub.UserView.render("user.json", user: unpersisted_user)
+ |> Map.delete("@context"),
+ {:ok, update_data, []} <- Builder.update(user, updated_object),
+ {:ok, _update, _} <-
+ Pipeline.common_pipeline(update_data,
+ local: true,
+ user_update_changeset: changeset
+ ) do
+ render(conn, "show.json",
+ user: unpersisted_user,
+ for: unpersisted_user,
+ with_pleroma_settings: true
+ )