mix format
This commit is contained in:
18
README.md
18
README.md
@ -1,19 +1,9 @@
|
|||||||
# SomethingErlang
|
# SomethingErlang
|
||||||
|
|
||||||
To start your Phoenix server:
|
Up and running:
|
||||||
|
|
||||||
* Install dependencies with `mix deps.get`
|
* `mix deps.get`
|
||||||
* Create and migrate your database with `mix ecto.setup`
|
* `mix ecto.setup`
|
||||||
* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server`
|
* `mix phx.server`
|
||||||
|
|
||||||
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
|
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
|
||||||
|
|
||||||
Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html).
|
|
||||||
|
|
||||||
## Learn more
|
|
||||||
|
|
||||||
* Official website: https://www.phoenixframework.org/
|
|
||||||
* Guides: https://hexdocs.pm/phoenix/overview.html
|
|
||||||
* Docs: https://hexdocs.pm/phoenix
|
|
||||||
* Forum: https://elixirforum.com/c/phoenix-forum
|
|
||||||
* Source: https://github.com/phoenixframework/phoenix
|
|
||||||
|
@ -42,7 +42,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pagination i {
|
.pagination i {
|
||||||
@apply h-5 px-1;
|
@apply h-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alerts and form errors used by phx.new */
|
/* Alerts and form errors used by phx.new */
|
||||||
|
@ -39,14 +39,16 @@ config :esbuild,
|
|||||||
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||||
]
|
]
|
||||||
|
|
||||||
config :tailwind, version: "3.0.24", default: [
|
config :tailwind,
|
||||||
args: ~w(
|
version: "3.0.24",
|
||||||
|
default: [
|
||||||
|
args: ~w(
|
||||||
--config=tailwind.config.js
|
--config=tailwind.config.js
|
||||||
--input=css/app.css
|
--input=css/app.css
|
||||||
--output=../priv/static/assets/app.css
|
--output=../priv/static/assets/app.css
|
||||||
),
|
),
|
||||||
cd: Path.expand("../assets", __DIR__)
|
cd: Path.expand("../assets", __DIR__)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Configures Elixir's Logger
|
# Configures Elixir's Logger
|
||||||
config :logger, :console,
|
config :logger, :console,
|
||||||
|
@ -9,7 +9,8 @@ import Config
|
|||||||
# manifest is generated by the `mix phx.digest` task,
|
# manifest is generated by the `mix phx.digest` task,
|
||||||
# which you should run after static files are built and
|
# which you should run after static files are built and
|
||||||
# before starting your production server.
|
# before starting your production server.
|
||||||
config :something_erlang, SomethingErlangWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
|
config :something_erlang, SomethingErlangWeb.Endpoint,
|
||||||
|
cache_static_manifest: "priv/static/cache_manifest.json"
|
||||||
|
|
||||||
# Do not print debug messages in production
|
# Do not print debug messages in production
|
||||||
config :logger, level: :info
|
config :logger, level: :info
|
||||||
|
@ -8,10 +8,8 @@ defmodule SomethingErlang.Application do
|
|||||||
@impl true
|
@impl true
|
||||||
def start(_type, _args) do
|
def start(_type, _args) do
|
||||||
children = [
|
children = [
|
||||||
{Registry, [name: SomethingErlang.Registry.Grovers,
|
{Registry, [name: SomethingErlang.Registry.Grovers, keys: :unique]},
|
||||||
keys: :unique]},
|
{DynamicSupervisor, [name: SomethingErlang.Supervisor.Grovers, strategy: :one_for_one]},
|
||||||
{DynamicSupervisor, [name: SomethingErlang.Supervisor.Grovers,
|
|
||||||
strategy: :one_for_one]},
|
|
||||||
# Start the Ecto repository
|
# Start the Ecto repository
|
||||||
SomethingErlang.Repo,
|
SomethingErlang.Repo,
|
||||||
# Start the Telemetry supervisor
|
# Start the Telemetry supervisor
|
||||||
|
@ -6,6 +6,7 @@ defmodule SomethingErlang.AwfulApi.Bookmarks do
|
|||||||
def compile(page, user) do
|
def compile(page, user) do
|
||||||
doc = Client.bookmarks_doc(page, user)
|
doc = Client.bookmarks_doc(page, user)
|
||||||
html = Floki.parse_document!(doc)
|
html = Floki.parse_document!(doc)
|
||||||
|
|
||||||
for thread <- Floki.find(html, "tr.thread") do
|
for thread <- Floki.find(html, "tr.thread") do
|
||||||
parse(thread)
|
parse(thread)
|
||||||
end
|
end
|
||||||
@ -17,26 +18,33 @@ defmodule SomethingErlang.AwfulApi.Bookmarks do
|
|||||||
icon: Floki.find(thread, "td.icon") |> inner_html() |> Floki.raw_html(),
|
icon: Floki.find(thread, "td.icon") |> inner_html() |> Floki.raw_html(),
|
||||||
author: Floki.find(thread, "td.author") |> inner_html() |> Floki.text(),
|
author: Floki.find(thread, "td.author") |> inner_html() |> Floki.text(),
|
||||||
replies: Floki.find(thread, "td.replies") |> inner_html() |> Floki.text(),
|
replies: Floki.find(thread, "td.replies") |> inner_html() |> Floki.text(),
|
||||||
views: Floki.find(thread, "td.views") |> inner_html() |> Floki.text(),
|
views: Floki.find(thread, "td.views") |> inner_html() |> Floki.text(),
|
||||||
rating: Floki.find(thread, "td.rating") |> inner_html() |> Floki.raw_html(),
|
rating: Floki.find(thread, "td.rating") |> inner_html() |> Floki.raw_html(),
|
||||||
lastpost: Floki.find(thread, "td.lastpost") |> inner_html() |> Floki.raw_html()
|
lastpost: Floki.find(thread, "td.lastpost") |> inner_html() |> Floki.raw_html()
|
||||||
}
|
}
|
||||||
|
|
||||||
for {"td", [{"class", class} | _attrs], children} <- Floki.find(thread, "td"),
|
for {"td", [{"class", class} | _attrs], children} <- Floki.find(thread, "td"),
|
||||||
String.starts_with?(class, "star") == false,
|
String.starts_with?(class, "star") == false,
|
||||||
into: %{} do
|
into: %{} do
|
||||||
case class do
|
case class do
|
||||||
<<"title", _rest::binary>> ->
|
<<"title", _rest::binary>> ->
|
||||||
{:title, children |> Floki.raw_html()}
|
{:title, children |> Floki.raw_html()}
|
||||||
|
|
||||||
<<"icon", _rest::binary>> ->
|
<<"icon", _rest::binary>> ->
|
||||||
{:icon, children |> Floki.raw_html()}
|
{:icon, children |> Floki.raw_html()}
|
||||||
|
|
||||||
<<"author", _rest::binary>> ->
|
<<"author", _rest::binary>> ->
|
||||||
{:author, children |> Floki.text()}
|
{:author, children |> Floki.text()}
|
||||||
|
|
||||||
<<"replies", _rest::binary>> ->
|
<<"replies", _rest::binary>> ->
|
||||||
{:replies, children |> Floki.text() |> String.to_integer()}
|
{:replies, children |> Floki.text() |> String.to_integer()}
|
||||||
|
|
||||||
<<"views", _rest::binary>> ->
|
<<"views", _rest::binary>> ->
|
||||||
{:views, children |> Floki.text() |> String.to_integer()}
|
{:views, children |> Floki.text() |> String.to_integer()}
|
||||||
|
|
||||||
<<"rating", _rest::binary>> ->
|
<<"rating", _rest::binary>> ->
|
||||||
{:rating, children |> Floki.raw_html()}
|
{:rating, children |> Floki.raw_html()}
|
||||||
|
|
||||||
<<"lastpost", _rest::binary>> ->
|
<<"lastpost", _rest::binary>> ->
|
||||||
{:lastpost, children |> Floki.raw_html()}
|
{:lastpost, children |> Floki.raw_html()}
|
||||||
end
|
end
|
||||||
|
@ -45,7 +45,8 @@ defmodule SomethingErlang.AwfulApi.Client do
|
|||||||
cache: true,
|
cache: true,
|
||||||
headers: [cookie: [cookies(%{bbuserid: user.id, bbpassword: user.hash})]]
|
headers: [cookie: [cookies(%{bbuserid: user.id, bbpassword: user.hash})]]
|
||||||
)
|
)
|
||||||
# |> Req.Request.append_request_steps(inspect: &IO.inspect/1)
|
|
||||||
|
# |> Req.Request.append_request_steps(inspect: &IO.inspect/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp cookies(args) when is_map(args) do
|
defp cookies(args) when is_map(args) do
|
||||||
|
@ -8,7 +8,6 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
html = Floki.parse_document!(doc)
|
html = Floki.parse_document!(doc)
|
||||||
thread = Floki.find(html, "#thread") |> Floki.filter_out("table.post.ignored")
|
thread = Floki.find(html, "#thread") |> Floki.filter_out("table.post.ignored")
|
||||||
|
|
||||||
|
|
||||||
title = Floki.find(html, "title") |> Floki.text()
|
title = Floki.find(html, "title") |> Floki.text()
|
||||||
title = title |> String.replace(" - The Something Awful Forums", "")
|
title = title |> String.replace(" - The Something Awful Forums", "")
|
||||||
|
|
||||||
@ -18,28 +17,23 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
s -> String.to_integer(s)
|
s -> String.to_integer(s)
|
||||||
end
|
end
|
||||||
|
|
||||||
posts = for post <- Floki.find(thread, "table.post") do
|
posts =
|
||||||
%{
|
for post <- Floki.find(thread, "table.post") do
|
||||||
userinfo: post |> userinfo(),
|
%{
|
||||||
postdate: post |> postdate(),
|
userinfo: post |> userinfo(),
|
||||||
postbody: post |> postbody()
|
postdate: post |> postdate(),
|
||||||
}
|
postbody: post |> postbody()
|
||||||
end
|
}
|
||||||
|
end
|
||||||
|
|
||||||
%{id: id,
|
%{id: id, title: title, page: page, page_count: page_count, posts: posts}
|
||||||
title: title,
|
|
||||||
page: page,
|
|
||||||
page_count: page_count,
|
|
||||||
posts: posts}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp userinfo(post) do
|
defp userinfo(post) do
|
||||||
user = Floki.find(post, "dl.userinfo")
|
user = Floki.find(post, "dl.userinfo")
|
||||||
name = user |> Floki.find("dt") |> Floki.text()
|
name = user |> Floki.find("dt") |> Floki.text()
|
||||||
regdate = user |> Floki.find("dd.registered") |> Floki.text()
|
regdate = user |> Floki.find("dd.registered") |> Floki.text()
|
||||||
title =
|
title = user |> Floki.find("dd.title") |> List.first() |> Floki.children() |> Floki.raw_html()
|
||||||
user |> Floki.find("dd.title") |> List.first()
|
|
||||||
|> Floki.children() |> Floki.raw_html()
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
name: name,
|
name: name,
|
||||||
@ -49,18 +43,28 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp postdate(post) do
|
defp postdate(post) do
|
||||||
date =
|
date = Floki.find(post, "td.postdate") |> Floki.find("td.postdate") |> Floki.text()
|
||||||
Floki.find(post, "td.postdate")
|
|
||||||
|> Floki.find("td.postdate") |> Floki.text()
|
|
||||||
|
|
||||||
[month_text, day, year, hours, minutes] = date
|
[month_text, day, year, hours, minutes] =
|
||||||
|> String.split(~r{[\s,:]}, trim: true)
|
date
|
||||||
|> Enum.drop(1)
|
|> String.split(~r{[\s,:]}, trim: true)
|
||||||
|
|> Enum.drop(1)
|
||||||
|
|
||||||
month = 1 + Enum.find_index(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
month =
|
||||||
fn m -> m == month_text end)
|
1 +
|
||||||
NaiveDateTime.new!(year |> String.to_integer(), month, day |> String.to_integer(),
|
Enum.find_index(
|
||||||
hours |> String.to_integer(), minutes |> String.to_integer(), 0)
|
["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||||
|
fn m -> m == month_text end
|
||||||
|
)
|
||||||
|
|
||||||
|
NaiveDateTime.new!(
|
||||||
|
year |> String.to_integer(),
|
||||||
|
month,
|
||||||
|
day |> String.to_integer(),
|
||||||
|
hours |> String.to_integer(),
|
||||||
|
minutes |> String.to_integer(),
|
||||||
|
0
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp postbody(post) do
|
defp postbody(post) do
|
||||||
@ -82,6 +86,7 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
|
|
||||||
defp transform(:img, attrs, _children) do
|
defp transform(:img, attrs, _children) do
|
||||||
{"class", class} = List.keyfind(attrs, "class", 0, {"class", ""})
|
{"class", class} = List.keyfind(attrs, "class", 0, {"class", ""})
|
||||||
|
|
||||||
if class == "sa-smilie" do
|
if class == "sa-smilie" do
|
||||||
{"img", attrs, []}
|
{"img", attrs, []}
|
||||||
else
|
else
|
||||||
@ -92,6 +97,7 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
|
|
||||||
defp transform(:a, attrs, children) do
|
defp transform(:a, attrs, children) do
|
||||||
{"href", href} = List.keyfind(attrs, "href", 0, {"href", ""})
|
{"href", href} = List.keyfind(attrs, "href", 0, {"href", ""})
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
# skip internal links
|
# skip internal links
|
||||||
String.starts_with?(href, "/") ->
|
String.starts_with?(href, "/") ->
|
||||||
@ -113,27 +119,31 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
transform_link(:ytshort, href)
|
transform_link(:ytshort, href)
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
Logger.debug "no transform for #{href}"
|
Logger.debug("no transform for #{href}")
|
||||||
{"a", [{"href", href}], children}
|
{"a", [{"href", href}], children}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp transform_link(:mp4, href),
|
defp transform_link(:mp4, href),
|
||||||
do: {"div", [{"class", "responsive-embed"}],
|
do:
|
||||||
[{"video", [{"class", "img-responsive"}, {"controls", ""}],
|
{"div", [{"class", "responsive-embed"}],
|
||||||
[{"source", [{"src", href}, {"type", "video/mp4"}], []}]
|
[
|
||||||
}]
|
{"video", [{"class", "img-responsive"}, {"controls", ""}],
|
||||||
}
|
[{"source", [{"src", href}, {"type", "video/mp4"}], []}]}
|
||||||
|
]}
|
||||||
|
|
||||||
defp transform_link(:gifv, href),
|
defp transform_link(:gifv, href),
|
||||||
do: {"div", [{"class", "responsive-embed"}],
|
do:
|
||||||
[{"video", [{"class", "img-responsive"}, {"controls", ""}],
|
{"div", [{"class", "responsive-embed"}],
|
||||||
[{"source", [{"src", String.replace(href, ".gifv", ".webm")},
|
[
|
||||||
{"type", "video/webm"}], []},
|
{"video", [{"class", "img-responsive"}, {"controls", ""}],
|
||||||
{"source", [{"src", String.replace(href, ".gifv", ".mp4")},
|
[
|
||||||
{"type", "video/mp4"}], []}]
|
{"source", [{"src", String.replace(href, ".gifv", ".webm")}, {"type", "video/webm"}],
|
||||||
}]
|
[]},
|
||||||
}
|
{"source", [{"src", String.replace(href, ".gifv", ".mp4")}, {"type", "video/mp4"}],
|
||||||
|
[]}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
|
||||||
defp transform_link(:ytlong, href) do
|
defp transform_link(:ytlong, href) do
|
||||||
String.replace(href, "/watch?v=", "/embed/")
|
String.replace(href, "/watch?v=", "/embed/")
|
||||||
@ -146,14 +156,15 @@ defmodule SomethingErlang.AwfulApi.Thread do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp youtube_iframe(src),
|
defp youtube_iframe(src),
|
||||||
do: {"div", [{"class", "responsive-embed"}],
|
do:
|
||||||
[{"iframe",
|
{"div", [{"class", "responsive-embed"}],
|
||||||
[
|
[
|
||||||
{"class", "youtube-player"},
|
{"iframe",
|
||||||
{"loading", "lazy"},
|
[
|
||||||
{"allow", "fullscreen"},
|
{"class", "youtube-player"},
|
||||||
{"src", src}
|
{"loading", "lazy"},
|
||||||
], []}
|
{"allow", "fullscreen"},
|
||||||
]}
|
{"src", src}
|
||||||
|
], []}
|
||||||
|
]}
|
||||||
end
|
end
|
||||||
|
@ -36,7 +36,8 @@ defmodule SomethingErlang.Forums do
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
def get_thread!(id),
|
def get_thread!(id),
|
||||||
do: %Thread{id: id, thread_id: id, title: "foo"} #Repo.get!(Thread, id)
|
# Repo.get!(Thread, id)
|
||||||
|
do: %Thread{id: id, thread_id: id, title: "foo"}
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a thread.
|
Creates a thread.
|
||||||
|
@ -5,10 +5,11 @@ defmodule SomethingErlang.Grover do
|
|||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def mount(user) do
|
def mount(user) do
|
||||||
{:ok, _pid} = DynamicSupervisor.start_child(
|
{:ok, _pid} =
|
||||||
SomethingErlang.Supervisor.Grovers,
|
DynamicSupervisor.start_child(
|
||||||
{__MODULE__, [self(), user]}
|
SomethingErlang.Supervisor.Grovers,
|
||||||
)
|
{__MODULE__, [self(), user]}
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_thread!(thread_id, page_number) do
|
def get_thread!(thread_id, page_number) do
|
||||||
@ -23,18 +24,20 @@ defmodule SomethingErlang.Grover do
|
|||||||
GenServer.start_link(
|
GenServer.start_link(
|
||||||
__MODULE__,
|
__MODULE__,
|
||||||
[lv_pid, user],
|
[lv_pid, user],
|
||||||
name: via(lv_pid))
|
name: via(lv_pid)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init([pid, user]) do
|
def init([pid, user]) do
|
||||||
%{bbuserid: userid, bbpassword: userhash} = user
|
%{bbuserid: userid, bbpassword: userhash} = user
|
||||||
|
|
||||||
initial_state = %{
|
initial_state = %{
|
||||||
lv_pid: pid,
|
lv_pid: pid,
|
||||||
user: %{id: userid, hash: userhash}
|
user: %{id: userid, hash: userhash}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.debug "init #{userid} #{inspect(pid)}"
|
Logger.debug("init #{userid} #{inspect(pid)}")
|
||||||
Process.monitor(pid)
|
Process.monitor(pid)
|
||||||
{:ok, initial_state}
|
{:ok, initial_state}
|
||||||
end
|
end
|
||||||
@ -53,7 +56,8 @@ defmodule SomethingErlang.Grover do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:DOWN, _ref, :process, _object, reason}, state) do
|
def handle_info({:DOWN, _ref, :process, _object, reason}, state) do
|
||||||
Logger.debug "received :DOWN from: #{inspect(state.lv_pid)} reason: #{inspect(reason)}"
|
Logger.debug("received :DOWN from: #{inspect(state.lv_pid)} reason: #{inspect(reason)}")
|
||||||
|
|
||||||
case reason do
|
case reason do
|
||||||
{:shutdown, _} -> {:stop, :normal, state}
|
{:shutdown, _} -> {:stop, :normal, state}
|
||||||
:killed -> {:stop, :normal, state}
|
:killed -> {:stop, :normal, state}
|
||||||
|
@ -7,11 +7,14 @@ defmodule SomethingErlangWeb.PageController do
|
|||||||
|
|
||||||
def to_forum_path(conn, %{"to" => redir_params} = _params) do
|
def to_forum_path(conn, %{"to" => redir_params} = _params) do
|
||||||
%{"forum_path" => path} = redir_params
|
%{"forum_path" => path} = redir_params
|
||||||
|
|
||||||
with [_, thread] <- Regex.run(~r{threadid=(\d+)}, path),
|
with [_, thread] <- Regex.run(~r{threadid=(\d+)}, path),
|
||||||
[_, page] <- Regex.run(~r{pagenumber=(\d+)}, path) do
|
[_, page] <- Regex.run(~r{pagenumber=(\d+)}, path) do
|
||||||
redirect(conn,
|
redirect(conn,
|
||||||
to: Routes.thread_show_path(conn, :show, thread, page: page))
|
to: Routes.thread_show_path(conn, :show, thread, page: page)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
put_flash(conn, :error, "Could not resolve URL")
|
put_flash(conn, :error, "Could not resolve URL")
|
||||||
render(conn, "index.html")
|
render(conn, "index.html")
|
||||||
end
|
end
|
||||||
|
@ -4,12 +4,12 @@ defmodule SomethingErlangWeb.Icons do
|
|||||||
@priv_dir Path.join(:code.priv_dir(:something_erlang), "icons")
|
@priv_dir Path.join(:code.priv_dir(:something_erlang), "icons")
|
||||||
@repo_url "https://github.com/CoreyGinnivan/system-uicons.git"
|
@repo_url "https://github.com/CoreyGinnivan/system-uicons.git"
|
||||||
|
|
||||||
System.cmd("rm", ["-rf", Path.join(@priv_dir, "system-uicons")])
|
System.cmd("rm", ["-rf", Path.join(@priv_dir, "system-uicons")])
|
||||||
System.cmd("git", ["clone", "--depth=1", @repo_url, Path.join(@priv_dir, "system-uicons")])
|
System.cmd("git", ["clone", "--depth=1", @repo_url, Path.join(@priv_dir, "system-uicons")])
|
||||||
|
|
||||||
source_data = File.read!(Path.join(@priv_dir, "system-uicons/src/js/data.js"))
|
source_data = File.read!(Path.join(@priv_dir, "system-uicons/src/js/data.js"))
|
||||||
|
|
||||||
<<"var sourceData = "::utf8 , rest::binary>> = source_data
|
<<"var sourceData = "::utf8, rest::binary>> = source_data
|
||||||
# remove trailing semicolon
|
# remove trailing semicolon
|
||||||
sslice = String.slice(rest, 0..-3//1)
|
sslice = String.slice(rest, 0..-3//1)
|
||||||
# quote object keys
|
# quote object keys
|
||||||
@ -18,15 +18,18 @@ defmodule SomethingErlangWeb.Icons do
|
|||||||
rm_trailing_commas = Regex.replace(~r/,\s+(}|])/, quote_keys, "\\1")
|
rm_trailing_commas = Regex.replace(~r/,\s+(}|])/, quote_keys, "\\1")
|
||||||
icon_data = Jason.decode!(rm_trailing_commas)
|
icon_data = Jason.decode!(rm_trailing_commas)
|
||||||
|
|
||||||
icon_map = Enum.map(icon_data, fn %{"icon_path" => path} = icon ->
|
icon_map =
|
||||||
svg = File.read!(Path.join(@priv_dir, "system-uicons/src/images/icons/#{path}.svg"))
|
Enum.map(icon_data, fn %{"icon_path" => path} = icon ->
|
||||||
Map.put_new(icon, "icon_svg", svg)
|
svg = File.read!(Path.join(@priv_dir, "system-uicons/src/images/icons/#{path}.svg"))
|
||||||
|> Map.new(fn {k, v} -> {String.to_atom(k), v} end)
|
|
||||||
end)
|
Map.put_new(icon, "icon_svg", svg)
|
||||||
|
|> Map.new(fn {k, v} -> {String.to_atom(k), v} end)
|
||||||
|
end)
|
||||||
|
|
||||||
for %{icon_path: path, icon_svg: svg} <- icon_map do
|
for %{icon_path: path, icon_svg: svg} <- icon_map do
|
||||||
def unquote(String.to_atom(path))(assigns) do
|
def unquote(String.to_atom(path))(assigns) do
|
||||||
svg = unquote(svg)
|
svg = unquote(svg)
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<i class={"icon"}>
|
<i class={"icon"}>
|
||||||
<%= Phoenix.HTML.raw svg %>
|
<%= Phoenix.HTML.raw svg %>
|
||||||
|
@ -15,6 +15,7 @@ defmodule SomethingErlangWeb.BookmarksLive.Show do
|
|||||||
@impl true
|
@impl true
|
||||||
def handle_params(%{"page" => page}, _, socket) do
|
def handle_params(%{"page" => page}, _, socket) do
|
||||||
bookmarks = Grover.get_bookmarks!(page |> String.to_integer())
|
bookmarks = Grover.get_bookmarks!(page |> String.to_integer())
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, "bookmarks")
|
|> assign(:page_title, "bookmarks")
|
||||||
@ -23,8 +24,9 @@ defmodule SomethingErlangWeb.BookmarksLive.Show do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_params(_, _, socket) do
|
def handle_params(_, _, socket) do
|
||||||
{:noreply, push_redirect(socket,
|
{:noreply,
|
||||||
to: Routes.bookmarks_show_path(socket, :show, page: 1))}
|
push_redirect(socket,
|
||||||
|
to: Routes.bookmarks_show_path(socket, :show, page: 1)
|
||||||
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -15,6 +15,7 @@ defmodule SomethingErlangWeb.ThreadLive.Show do
|
|||||||
@impl true
|
@impl true
|
||||||
def handle_params(%{"id" => id, "page" => page}, _, socket) do
|
def handle_params(%{"id" => id, "page" => page}, _, socket) do
|
||||||
thread = Grover.get_thread!(id, page |> String.to_integer())
|
thread = Grover.get_thread!(id, page |> String.to_integer())
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, thread.title)
|
|> assign(:page_title, thread.title)
|
||||||
@ -23,8 +24,10 @@ defmodule SomethingErlangWeb.ThreadLive.Show do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_params(%{"id" => id}, _, socket) do
|
def handle_params(%{"id" => id}, _, socket) do
|
||||||
{:noreply, push_redirect(socket,
|
{:noreply,
|
||||||
to: Routes.thread_show_path(socket, :show, id, page: 1))}
|
push_redirect(socket,
|
||||||
|
to: Routes.thread_show_path(socket, :show, id, page: 1)
|
||||||
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def post(assigns) do
|
def post(assigns) do
|
||||||
@ -61,10 +64,10 @@ defmodule SomethingErlangWeb.ThreadLive.Show do
|
|||||||
%{page: page_number, page_count: page_count} = assigns.thread
|
%{page: page_number, page_count: page_count} = assigns.thread
|
||||||
|
|
||||||
first_page_disabled_button = if page_number == 1, do: " btn-disabled", else: ""
|
first_page_disabled_button = if page_number == 1, do: " btn-disabled", else: ""
|
||||||
last_page_disabled_button = if page_number == page_count, do: " btn-disabled", else: ""
|
last_page_disabled_button = if page_number == page_count, do: " btn-disabled", else: ""
|
||||||
active_page_button = " btn-active"
|
active_page_button = " btn-active"
|
||||||
|
|
||||||
prev_button_target = if page_number >= 1, do: page_number - 1, else: 1
|
prev_button_target = if page_number > 1, do: page_number - 1, else: 1
|
||||||
next_button_target = if page_number < page_count, do: page_number + 1, else: page_count
|
next_button_target = if page_number < page_count, do: page_number + 1, else: page_count
|
||||||
|
|
||||||
buttons = [
|
buttons = [
|
||||||
@ -78,16 +81,16 @@ defmodule SomethingErlangWeb.ThreadLive.Show do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class="navbar my-4 bg-base-200">
|
<div class="navbar my-4 bg-base-200">
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<div class="pagination flex-none btn-group">
|
<div class="pagination flex-none btn-group grid grid-cols-5">
|
||||||
<%= for btn <- buttons do %>
|
<%= for btn <- buttons do %>
|
||||||
<%= live_redirect class: "btn btn-sm" <> btn.special,
|
<%= live_redirect class: "btn btn-sm btn-ghost" <> btn.special,
|
||||||
to: Routes.thread_show_path(@socket, :show, @thread.id, page: btn.page) do %>
|
to: Routes.thread_show_path(@socket, :show, @thread.id, page: btn.page) do %>
|
||||||
<%= case btn.label do %>
|
<%= case btn.label do %>
|
||||||
<% "«" -> %>1 <Icons.chevron_left_double />
|
<% "«" -> %><Icons.chevron_left_double /><%= btn.page %>
|
||||||
<% "‹" -> %><Icons.chevron_left />
|
<% "‹" -> %><Icons.chevron_left /><%= btn.page %>
|
||||||
<% "›" -> %><Icons.chevron_right />
|
<% "›" -> %><%= btn.page %><Icons.chevron_right />
|
||||||
<% "»" -> %><Icons.chevron_right_double /> <%= page_count %>
|
<% "»" -> %><%= btn.page %><Icons.chevron_right_double />
|
||||||
<% _ -> %><%= btn.label %>
|
<% _ -> %><%= btn.page %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -3,7 +3,6 @@ defmodule SomethingErlangWeb.UserLiveAuth do
|
|||||||
|
|
||||||
alias SomethingErlang.Accounts
|
alias SomethingErlang.Accounts
|
||||||
|
|
||||||
|
|
||||||
def on_mount(:default, _params, %{"user_token" => user_token} = _session, socket) do
|
def on_mount(:default, _params, %{"user_token" => user_token} = _session, socket) do
|
||||||
user = Accounts.get_user_by_session_token(user_token)
|
user = Accounts.get_user_by_session_token(user_token)
|
||||||
socket = assign_new(socket, :current_user, fn -> user end)
|
socket = assign_new(socket, :current_user, fn -> user end)
|
||||||
|
@ -9,6 +9,7 @@ defmodule SomethingErlangWeb.ErrorViewTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "renders 500.html" do
|
test "renders 500.html" do
|
||||||
assert render_to_string(SomethingErlangWeb.ErrorView, "500.html", []) == "Internal Server Error"
|
assert render_to_string(SomethingErlangWeb.ErrorView, "500.html", []) ==
|
||||||
|
"Internal Server Error"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user