Add replying to statuses
This commit is contained in:
parent
6c0fc06c21
commit
7d071d971c
|
@ -32,6 +32,7 @@ defmodule Clacks.ActivityPub do
|
|||
actor :: String.t(),
|
||||
html :: String.t(),
|
||||
context :: String.t() | nil,
|
||||
in_reply_to :: String.t() | nil,
|
||||
id :: String.t() | nil,
|
||||
published :: DateTime.t(),
|
||||
to :: [String.t()],
|
||||
|
@ -41,6 +42,7 @@ defmodule Clacks.ActivityPub do
|
|||
actor,
|
||||
html,
|
||||
context \\ nil,
|
||||
in_reply_to \\ nil,
|
||||
id \\ nil,
|
||||
published \\ DateTime.utc_now(),
|
||||
to \\ [@public],
|
||||
|
@ -61,6 +63,7 @@ defmodule Clacks.ActivityPub do
|
|||
"content" => html,
|
||||
"conversation" => context,
|
||||
"context" => context,
|
||||
"inReplyTo" => in_reply_to,
|
||||
"published" => published |> DateTime.to_iso8601()
|
||||
}
|
||||
end
|
||||
|
|
|
@ -18,7 +18,27 @@ defmodule ClacksWeb.ActivitiesController do
|
|||
end
|
||||
|
||||
_ ->
|
||||
resp(conn, 404, "Not Found")
|
||||
case conn.assigns[:format] do
|
||||
"activity+json" ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Not Found"})
|
||||
|
||||
"html" ->
|
||||
resp(conn, 404, "Not Found")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_status(conn, %{"id" => status_id}) do
|
||||
case Activity.get(status_id) do
|
||||
%Activity{local: true, data: data} ->
|
||||
json(conn, data)
|
||||
|
||||
_ ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Not Found"})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,8 @@ defmodule ClacksWeb.FrontendController do
|
|||
alias ClacksWeb.Router.Helpers, as: Routes
|
||||
alias ClacksWeb.Endpoint
|
||||
|
||||
@public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
def index(%Plug.Conn{assigns: %{user: user}} = conn, params) do
|
||||
user = Repo.preload(user, :actor)
|
||||
|
||||
|
@ -48,23 +50,67 @@ defmodule ClacksWeb.FrontendController do
|
|||
|
||||
with %Activity{
|
||||
local: true,
|
||||
data:
|
||||
%{
|
||||
"type" => "Create",
|
||||
"object" => %{"type" => "Note", "attributedTo" => author_id} = note
|
||||
} = data
|
||||
} <- Activity.get(id),
|
||||
%Actor{} = author <- Actor.get_by_ap_id(author_id) do
|
||||
case conn.assigns[:format] do
|
||||
"activity+json" ->
|
||||
json(conn, data)
|
||||
|
||||
"html" ->
|
||||
render(conn, "status.html", %{
|
||||
current_user: current_user,
|
||||
note: note,
|
||||
author: author
|
||||
})
|
||||
end
|
||||
else
|
||||
nil ->
|
||||
case conn.assigns[:format] do
|
||||
"activity+json" ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Not Found"})
|
||||
|
||||
"html" ->
|
||||
resp(conn, 404, "Not Found")
|
||||
end
|
||||
|
||||
%Activity{local: false, data: %{"id" => ap_id}} ->
|
||||
case conn.assigns[:format] do
|
||||
"activity+json" ->
|
||||
conn
|
||||
|> put_status(404)
|
||||
|> json(%{error: "Not Found"})
|
||||
|
||||
"html" ->
|
||||
redirect(conn, external: ap_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def reply(conn, %{"id" => id}) do
|
||||
current_user = conn.assigns[:user]
|
||||
|
||||
with %Activity{
|
||||
data: %{
|
||||
"type" => "Create",
|
||||
"object" => %{"type" => "Note", "attributedTo" => author_id} = note
|
||||
}
|
||||
} <- Activity.get(id),
|
||||
%Actor{} = author <- Actor.get_by_ap_id(author_id) do
|
||||
render(conn, "status.html", %{
|
||||
render(conn, "reply.html", %{
|
||||
current_user: current_user,
|
||||
note: note,
|
||||
author: author
|
||||
})
|
||||
else
|
||||
nil ->
|
||||
put_status(conn, 404)
|
||||
|
||||
%Activity{local: false, data: %{"id" => ap_id}} ->
|
||||
redirect(conn, external: ap_id)
|
||||
_ ->
|
||||
resp(conn, 404, "Not Found")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,7 +135,7 @@ defmodule ClacksWeb.FrontendController do
|
|||
def post_status(conn, %{"content" => content} = params) do
|
||||
current_user = conn.assigns[:user] |> Repo.preload(:actor)
|
||||
|
||||
note = ActivityPub.note(current_user.actor.ap_id, content)
|
||||
note = note_for_posting(current_user, params)
|
||||
note_changeset = Object.changeset_for_creating(note)
|
||||
{:ok, object} = Repo.insert(note_changeset)
|
||||
|
||||
|
@ -104,4 +150,31 @@ defmodule ClacksWeb.FrontendController do
|
|||
path = Map.get(params, "continue", Routes.frontend_path(Endpoint, :status, activity.id))
|
||||
redirect(conn, to: path)
|
||||
end
|
||||
|
||||
defp note_for_posting(current_user, %{"content" => content, "in_reply_to" => in_reply_to_ap_id}) do
|
||||
with %Activity{data: %{"context" => context, "actor" => in_reply_to_actor}} <-
|
||||
Activity.get_by_ap_id(in_reply_to_ap_id) do
|
||||
to = [in_reply_to_actor, @public]
|
||||
# todo: followers
|
||||
cc = []
|
||||
|
||||
ActivityPub.note(
|
||||
current_user.actor.ap_id,
|
||||
content,
|
||||
context,
|
||||
in_reply_to_ap_id,
|
||||
nil,
|
||||
DateTime.utc_now(),
|
||||
to,
|
||||
cc
|
||||
)
|
||||
else
|
||||
_ ->
|
||||
ActivityPub.note(current_user.actor.ap_id, content)
|
||||
end
|
||||
end
|
||||
|
||||
defp note_for_posting(current_user, %{"content" => content}) do
|
||||
ActivityPub.note(current_user.actor.ap_id, content)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,13 +51,13 @@ defmodule ClacksWeb.Router do
|
|||
pipe_through :browser_maybe_authenticated
|
||||
|
||||
get "/", FrontendController, :index
|
||||
get "/status/:id", FrontendController, :status
|
||||
post "/post", FrontendController, :post_status
|
||||
end
|
||||
|
||||
scope "/", ClacksWeb do
|
||||
pipe_through :browser
|
||||
pipe_through :browser_authenticated
|
||||
|
||||
post "/post", FrontendController, :post_status
|
||||
end
|
||||
|
||||
scope "/", ClacksWeb do
|
||||
|
@ -80,6 +80,7 @@ defmodule ClacksWeb.Router do
|
|||
get "/users/:username", ActorController, :get
|
||||
get "/activities/:id", ActivitiesController, :get
|
||||
get "/objects/:id", ObjectsController, :get
|
||||
get "/status/:id", FrontendController, :status
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<%= @author.data["name"] %>
|
||||
</a>
|
||||
</h3>
|
||||
<a href="<%= @note["url"] %>">Permalink</a>
|
||||
<div class="status-content">
|
||||
<%= @note["content"] %>
|
||||
</div>
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
<%= render "_status.html", author: @author, note: @note %>
|
||||
|
||||
<hr>
|
||||
|
||||
<%= form_tag Routes.frontend_path(@conn, :post_status), method: :post do %>
|
||||
<input type="hidden" name="in_reply_to" value="<%= @note["id"] %>">
|
||||
<textarea id="content" name="content" cols="30" rows="10" placeholder="Reply"></textarea>
|
||||
<%= submit "Post" %>
|
||||
<% end %>
|
||||
|
|
Loading…
Reference in New Issue