Merge pull request 'devel' (#77) from devel into main

Reviewed-on: #77
This commit is contained in:
inhji 2023-05-21 09:55:15 +02:00
commit 9be8ec73d3
11 changed files with 115 additions and 21 deletions

View file

@ -60,6 +60,10 @@ config :waffle,
storage: Waffle.Storage.Local,
storage_dir_prefix: "priv/waffle/public"
# Configure Timezones with :tz
config :elixir,
:time_zone_database, Tz.TimeZoneDatabase
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"

View file

@ -8,8 +8,17 @@ defmodule Chiya.Channels.Channel do
field :content, :string
field :name, :string
field :slug, ChannelSlug.Type
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
field :layout, Ecto.Enum, values: [:default, :gallery]
field :visibility, Ecto.Enum, values: [
:public,
:private,
:unlisted
]
field :layout, Ecto.Enum, values: [
:default,
:microblog,
:photoblog,
:gallery
]
many_to_many :notes, Chiya.Notes.Note,
join_through: "channels_notes",
@ -28,10 +37,10 @@ defmodule Chiya.Channels.Channel do
|> validate_exclusion(:slug, ~w(admin user dev))
end
def icon(%Chiya.Channels.Channel{visibility: vis}) do
case(vis) do
:public -> "🌍"
def icon(%Chiya.Channels.Channel{visibility: visibility}) do
case(visibility) do
:private -> "🔒"
:public -> "🌍"
:unlisted -> "👁️"
end
end

View file

@ -238,6 +238,7 @@ defmodule ChiyaWeb.CoreComponents do
"""
attr :for, :any, required: true, doc: "the datastructure for the form"
attr :as, :any, default: nil, doc: "the server side parameter to collect all input under"
attr :class, :string, default: "shadow rounded mt-10 bg-white dark:bg-gray-900"
attr :rest, :global,
include: ~w(autocomplete name rel action enctype method novalidate target multipart),
@ -248,8 +249,8 @@ defmodule ChiyaWeb.CoreComponents do
def simple_form(assigns) do
~H"""
<.form :let={f} for={@for} as={@as} {@rest}>
<div class="space-y-8 p-3 shadow rounded bg-white dark:bg-gray-900 mt-10">
<.form :let={f} for={@for} as={@as} {@rest} class={@class}>
<div class="space-y-8 p-3">
<%= render_slot(@inner_block, f) %>
<div :for={action <- @actions} class="mt-2 flex items-center justify-between gap-6">
<%= render_slot(action, f) %>
@ -323,8 +324,7 @@ defmodule ChiyaWeb.CoreComponents do
attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs"
attr :rest, :global,
include: ~w(autocomplete accept cols disabled form max maxlength min minlength
pattern placeholder readonly required rows size step)
include: ~w(autocomplete accept cols disabled form max maxlength min minlength pattern placeholder readonly required rows size step)
slot :inner_block

View file

@ -7,6 +7,8 @@ defmodule ChiyaWeb.PublicComponents do
statics: ChiyaWeb.static_paths()
import ChiyaWeb.Format
import ChiyaWeb.Markdown, only: [render: 1]
import Phoenix.HTML, only: [raw: 1]
@doc """
Renders a horizontal line
@ -90,9 +92,31 @@ defmodule ChiyaWeb.PublicComponents do
</section>
"""
_ ->
:microblog ->
~H"""
<section class="default | mt-6 sm:w-auto flex flex-col gap-1.5">
<section class="note-list microblog | mt-6 text-theme-base">
<%= for note <- assigns.notes do %>
<article class="mt-8 first:mt-0">
<div class="prose prose-gruvbox">
<%= raw render(note.content) %>
</div>
<time class="text-theme-base/75">
<%= pretty_datetime(note.published_at) %>
</time>
<span>·</span>
<a href={~p"/#{note.slug}"} class="text-theme-base/75">Permalink</a>
</article>
<% end %>
</section>
"""
:photoblog ->
~H"""
"""
_ -> # default, show headings only
~H"""
<section class="note-list default | mt-6 sm:w-auto flex flex-col gap-1.5">
<%= for note <- assigns.notes do %>
<a
href={~p"/#{note.slug}"}

View file

@ -104,6 +104,46 @@ defmodule ChiyaWeb.NoteController do
|> text(raw_note)
end
def publish(conn, %{"id" => id}) do
note_params = %{published_at: NaiveDateTime.local_now()}
note = Notes.get_note_preloaded!(id)
case Notes.update_note(note, note_params) do
{:ok, note} ->
conn
|> put_flash(:info, "Note published successfully.")
|> redirect(to: ~p"/admin/notes/#{note}")
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :edit,
note: note,
changeset: changeset,
channels: to_channel_options(),
tags: note.tags
)
end
end
def unpublish(conn, %{"id" => id}) do
note_params = %{published_at: nil}
note = Notes.get_note_preloaded!(id)
case Notes.update_note(note, note_params) do
{:ok, note} ->
conn
|> put_flash(:info, "Note un-published successfully.")
|> redirect(to: ~p"/admin/notes/#{note}")
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :edit,
note: note,
changeset: changeset,
channels: to_channel_options(),
tags: note.tags
)
end
end
def edit_image(conn, %{"image_id" => id}) do
image = Notes.get_note_image!(id)
changeset = Notes.change_note_image(image)

View file

@ -69,16 +69,20 @@
</article>
<% end %>
</aside>
<% else %>
<.line />
<h2 class="mb-6 text-theme-base">No comments yet.</h2>
<% end %>
<.line />
<.simple_form :let={f} for={@changeset} action={~p"/#{@note.slug}/comment"}>
<.simple_form :let={f} for={@changeset} action={~p"/#{@note.slug}/comment"} class="bg-theme-background -m-3">
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={f[:author_name]} type="text" placeholder="Name" />
<.input field={f[:content]} type="textarea" placeholder="Content" rows="3" />
<.input field={f[:author_name]} type="text" placeholder="Name" class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/40 dark:placeholder-theme-base/60 dark:focus:border-theme-base/60 dark:focus:border-theme-base/60" />
<.input field={f[:content]} type="textarea" placeholder="Content" rows="3" class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/60 dark:placeholder-theme-base/60 focus:border-theme-base/60 dark:focus:border-theme-base/60" />
<.input field={f[:note_id]} type="hidden" />
<:actions>
<.button>Submit Comment</.button>

View file

@ -1,12 +1,12 @@
defmodule ChiyaWeb.Format do
def from_now(%DateTime{} = later) do
now = DateTime.utc_now()
now = DateTime.local_now()
diff = DateTime.diff(now, later)
do_from_now(diff)
end
def from_now(%NaiveDateTime{} = later) do
now = NaiveDateTime.utc_now()
now = NaiveDateTime.local_now()
diff = NaiveDateTime.diff(now, later)
do_from_now(diff)
end
@ -27,9 +27,9 @@ defmodule ChiyaWeb.Format do
end
end
def pretty_date(%NaiveDateTime{} = date) do
Calendar.strftime(date, "%d.%m.%Y")
end
def pretty_date(%NaiveDateTime{} = date), do: Calendar.strftime(date, "%d.%m.%Y")
def pretty_date(_), do: ""
def pretty_datetime(%NaiveDateTime{} = date), do: Calendar.strftime(date, "%d.%m.%Y %H:%M")
def pretty_datetime(_), do: ""
end

View file

@ -25,6 +25,15 @@ defmodule ChiyaWeb.NoteShowLive do
<.link href={~p"/admin/notes/#{@note}/raw"}>
<.button>Raw</.button>
</.link>
<%= if is_nil(@note.published_at) do %>
<.link href={~p"/admin/notes/#{@note}/publish"}>
<.button>Publish</.button>
</.link>
<% else %>
<.link href={~p"/admin/notes/#{@note}/unpublish"}>
<.button>Un-Publish</.button>
</.link>
<% end %>
</:actions>
</.header>

View file

@ -67,6 +67,8 @@ defmodule ChiyaWeb.Router do
live "/notes/:id", NoteShowLive, :show
get "/notes/:id/raw", NoteController, :raw
get "/notes/:id/publish", NoteController, :publish
get "/notes/:id/unpublish", NoteController, :unpublish
get "/notes/:id/image/:image_id", NoteController, :edit_image
put "/notes/:id/image/:image_id", NoteController, :update_image

View file

@ -55,7 +55,8 @@ defmodule Chiya.MixProject do
{:waffle, "~> 1.1"},
{:waffle_ecto, "~> 0.0.12"},
{:earmark, "~> 1.4"},
{:yaml_front_matter, "~> 1.0.0"}
{:yaml_front_matter, "~> 1.0.0"},
{:tz, "~> 0.26.1"}
]
end

View file

@ -53,6 +53,7 @@
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
"tz": {:hex, :tz, "0.26.1", "773555ecb9c01c87fcf969b4c2d2140e63fe6b3d7d9520fa2134ac1072b540a8", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.5", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "da38cea41e9cfd0deaa7f634e167a30399dcc8b84fd3da32e1d972466053f57c"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"waffle": {:hex, :waffle, "1.1.7", "518f9bdda7b9b3d0958ad6ab16066631ce028f5f12217382822a428895fc4be3", [:mix], [{:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:ex_aws_s3, "~> 2.1", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "e97e7b10b7f380687b5dc5e65b391538a802eff636605ad183e0bed29b45b0ef"},
"waffle_ecto": {:hex, :waffle_ecto, "0.0.12", "e5c17c49b071b903df71861c642093281123142dc4e9908c930db3e06795b040", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:waffle, "~> 1.0", [hex: :waffle, repo: "hexpm", optional: false]}], "hexpm", "585fe6371057066d2e8e3383ddd7a2437ff0668caf3f4cbf5a041e0de9837168"},