From 43cad4570597c610178d351d198acc2fc830663e Mon Sep 17 00:00:00 2001 From: Inhji Date: Sun, 30 Apr 2023 13:35:22 +0200 Subject: [PATCH] add comments --- lib/chiya/notes.ex | 31 +++++++++++++++-- lib/chiya/notes/note.ex | 15 +++++---- lib/chiya/notes/note_comment.ex | 23 +++++++++++++ .../controllers/comment_controller.ex | 17 ++++++++++ lib/chiya_web/controllers/comment_html.ex | 5 +++ lib/chiya_web/controllers/page_controller.ex | 4 ++- .../controllers/page_html/note.html.heex | 33 +++++++++++++++++++ lib/chiya_web/router.ex | 2 ++ .../20230429074000_create_note_comments.exs | 18 ++++++++++ 9 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 lib/chiya/notes/note_comment.ex create mode 100644 lib/chiya_web/controllers/comment_controller.ex create mode 100644 lib/chiya_web/controllers/comment_html.ex create mode 100644 priv/repo/migrations/20230429074000_create_note_comments.exs diff --git a/lib/chiya/notes.ex b/lib/chiya/notes.ex index e4110a4..e9fd096 100644 --- a/lib/chiya/notes.ex +++ b/lib/chiya/notes.ex @@ -5,9 +5,22 @@ defmodule Chiya.Notes do import Ecto.Query, warn: false alias Chiya.Repo - alias Chiya.Notes.{Note, NoteImage, NoteNote, NoteTag} + alias Chiya.Notes.{Note, NoteImage, NoteNote, NoteTag, NoteComment} - @preloads [:channels, :images, :links_from, :links_to, :tags] + @preloads [ + :channels, + :images, + :links_from, + :links_to, + :tags, + comments: + from(c in NoteComment, + order_by: [ + desc: :approved_at, + desc: :inserted_at + ] + ) + ] def note_preloads(), do: @preloads @doc """ @@ -264,4 +277,18 @@ defmodule Chiya.Notes do def delete_note_tag(%NoteTag{} = note_tag) do Repo.delete(note_tag) end + + def create_note_comment(attrs \\ %{}) do + %NoteComment{} + |> NoteComment.changeset(attrs) + |> Repo.insert() + end + + def delete_note_comment(%NoteComment{} = note_comment) do + Repo.delete(note_comment) + end + + def change_note_comment(%NoteComment{} = note_comment, attrs \\ %{}) do + NoteComment.changeset(note_comment, attrs) + end end diff --git a/lib/chiya/notes/note.ex b/lib/chiya/notes/note.ex index e7eda5f..faf5f43 100644 --- a/lib/chiya/notes/note.ex +++ b/lib/chiya/notes/note.ex @@ -1,9 +1,9 @@ defmodule Chiya.Notes.Note do use Ecto.Schema import Ecto.Changeset - alias Chiya.Notes.NoteSlug + alias Chiya.Notes.{Note, NoteSlug, NoteNote, NoteTag} - @reserved_slugs [] + @reserved_slugs ~w(user admin dev api) @derive {Jason.Encoder, only: [:id, :name, :content, :slug, :channels]} schema "notes" do @@ -23,19 +23,20 @@ defmodule Chiya.Notes.Note do join_keys: [note: :id, channel: :id], on_replace: :delete - many_to_many :links_from, Chiya.Notes.Note, - join_through: Chiya.Notes.NoteNote, + many_to_many :links_from, Note, + join_through: NoteNote, join_keys: [source_id: :id, target_id: :id] - many_to_many :links_to, Chiya.Notes.Note, - join_through: Chiya.Notes.NoteNote, + many_to_many :links_to, Note, + join_through: NoteNote, join_keys: [target_id: :id, source_id: :id] many_to_many :tags, Chiya.Tags.Tag, - join_through: Chiya.Notes.NoteTag, + join_through: NoteTag, join_keys: [note_id: :id, tag_id: :id] has_many :images, Chiya.Notes.NoteImage + has_many :comments, Chiya.Notes.NoteComment field :tags_string, :string, virtual: true, diff --git a/lib/chiya/notes/note_comment.ex b/lib/chiya/notes/note_comment.ex new file mode 100644 index 0000000..2daeff5 --- /dev/null +++ b/lib/chiya/notes/note_comment.ex @@ -0,0 +1,23 @@ +defmodule Chiya.Notes.NoteComment do + use Ecto.Schema + import Ecto.Changeset + + schema "note_comments" do + field :approved_at, :naive_datetime + field :author_name, :string + field :author_id, :id + field :content, :string + field :kind, Ecto.Enum, values: [:anon, :fedi], default: :anon + + belongs_to :note, Chiya.Notes.Note + + timestamps() + end + + @doc false + def changeset(note_comment, attrs) do + note_comment + |> cast(attrs, [:content, :author_name, :author_id, :kind, :note_id, :approved_at]) + |> validate_required([:content, :author_name, :kind, :note_id]) + end +end diff --git a/lib/chiya_web/controllers/comment_controller.ex b/lib/chiya_web/controllers/comment_controller.ex new file mode 100644 index 0000000..5559a96 --- /dev/null +++ b/lib/chiya_web/controllers/comment_controller.ex @@ -0,0 +1,17 @@ +defmodule ChiyaWeb.CommentController do + use ChiyaWeb, :controller + + def create(conn, %{"slug" => note_slug, "note_comment" => comment_params}) do + note = Chiya.Notes.get_note_by_slug_preloaded!(note_slug) + + IO.inspect(comment_params) + + case Chiya.Notes.create_note_comment(comment_params) do + {:ok, _comment} -> + redirect(conn, to: ~p"/#{note_slug}?error=0") + + {:error, changeset} -> + redirect(conn, to: ~p"/#{note_slug}?error=1") + end + end +end diff --git a/lib/chiya_web/controllers/comment_html.ex b/lib/chiya_web/controllers/comment_html.ex new file mode 100644 index 0000000..da6c63b --- /dev/null +++ b/lib/chiya_web/controllers/comment_html.ex @@ -0,0 +1,5 @@ +defmodule ChiyaWeb.CommentHTML do + use ChiyaWeb, :html + + embed_templates "comment_html/*" +end diff --git a/lib/chiya_web/controllers/page_controller.ex b/lib/chiya_web/controllers/page_controller.ex index b882bd5..322bca5 100644 --- a/lib/chiya_web/controllers/page_controller.ex +++ b/lib/chiya_web/controllers/page_controller.ex @@ -41,6 +41,7 @@ defmodule ChiyaWeb.PageController do def note(conn, %{"slug" => note_slug}) do note = Chiya.Notes.get_note_by_slug_preloaded!(note_slug) + changeset = Chiya.Notes.change_note_comment(%Chiya.Notes.NoteComment{}, %{note_id: note.id}) if is_nil(note.published_at) and is_nil(conn.assigns.current_user) do render_error(conn, :not_found) @@ -48,7 +49,8 @@ defmodule ChiyaWeb.PageController do render(conn, :note, layout: {ChiyaWeb.Layouts, "public.html"}, note: note, - page_title: note.name + page_title: note.name, + changeset: changeset ) end end diff --git a/lib/chiya_web/controllers/page_html/note.html.heex b/lib/chiya_web/controllers/page_html/note.html.heex index 18de334..3bf35b2 100644 --- a/lib/chiya_web/controllers/page_html/note.html.heex +++ b/lib/chiya_web/controllers/page_html/note.html.heex @@ -50,4 +50,37 @@ <% end %> <% end %> + + <%= if not Enum.empty?(@note.comments) do %> + <.line /> + +

<%= Enum.count(@note.comments) %> Comments

+ + + <% end %> + + <.line /> + + <.simple_form :let={f} for={@changeset} action={~p"/#{@note.slug}/comment"}> + <.error :if={@changeset.action}> + Oops, something went wrong! Please check the errors below. + + <.input field={f[:author_name]} type="text" placeholder="Name" /> + <.input field={f[:content]} type="textarea" placeholder="Content" rows="3" /> + <.input field={f[:note_id]} type="hidden" /> + <:actions> + <.button>Submit Comment + + + diff --git a/lib/chiya_web/router.ex b/lib/chiya_web/router.ex index c8ae3c5..3af5fff 100644 --- a/lib/chiya_web/router.ex +++ b/lib/chiya_web/router.ex @@ -119,5 +119,7 @@ defmodule ChiyaWeb.Router do get "/c/:slug", PageController, :channel get "/t/:slug", PageController, :tag get "/", PageController, :home + + post "/:slug/comment", CommentController, :create end end diff --git a/priv/repo/migrations/20230429074000_create_note_comments.exs b/priv/repo/migrations/20230429074000_create_note_comments.exs new file mode 100644 index 0000000..936d62d --- /dev/null +++ b/priv/repo/migrations/20230429074000_create_note_comments.exs @@ -0,0 +1,18 @@ +defmodule Chiya.Repo.Migrations.CreateNoteComments do + use Ecto.Migration + + def change do + create table(:note_comments) do + add :content, :text + add :author_name, :string + add :author_id, :integer + add :kind, :string + add :approved_at, :naive_datetime + add :note_id, references(:notes, on_delete: :delete_all) + + timestamps() + end + + create index(:note_comments, [:note_id]) + end +end