List shared links (#15)
* Exclude not published items in directus client * Add link view to page controller * Add page controller links list view to router * Add links list view CSS * Add permalink view for link * Improve page titles * Let user copy link permalink to clipboard if alt, shift or ctrl are pressed, fallback to default behavior.
This commit is contained in:
parent
fae04e3fd7
commit
89b93cf231
10 changed files with 200 additions and 49 deletions
|
|
@ -118,7 +118,14 @@ main {
|
|||
font-size: large;
|
||||
box-sizing: border-box;
|
||||
|
||||
> pre {
|
||||
> footer {
|
||||
font-style: italic;
|
||||
text-align: right;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 2em 0;
|
||||
background-color: #022;
|
||||
overflow-y: auto;
|
||||
|
|
@ -133,13 +140,6 @@ main {
|
|||
top: 0.25em;
|
||||
right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
> footer {
|
||||
font-style: italic;
|
||||
text-align: right;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
|
|
@ -193,3 +193,9 @@ section > h2 {
|
|||
padding: 0.25em 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
> :is(h2, h3) {
|
||||
margin-top: 3em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
|
||||
import "../app.css";
|
||||
|
||||
import copyToClipboard from "./copy-to-clipboard.js";
|
||||
import {
|
||||
copyCodeToClipboard,
|
||||
copyUrlToClipboard,
|
||||
} from "./copy-to-clipboard.js";
|
||||
|
||||
copyToClipboard();
|
||||
copyCodeToClipboard();
|
||||
copyUrlToClipboard();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,30 @@
|
|||
export default () => {
|
||||
export const copyCodeToClipboard = () => {
|
||||
const codeblocks = document.querySelectorAll("pre>code");
|
||||
|
||||
for (const b of codeblocks) {
|
||||
const button = document.createElement("button");
|
||||
button.innerHTML = "Kopiera";
|
||||
button.addEventListener("click", function ({target}) {
|
||||
button.addEventListener("click", function ({ target }) {
|
||||
const text = target.previousSibling.innerHTML;
|
||||
navigator.clipboard.writeText(text);
|
||||
})
|
||||
});
|
||||
b.parentNode.appendChild(button);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const copyUrlToClipboard = () => {
|
||||
const permalinks = document.querySelectorAll(".permalink");
|
||||
for (const pl of permalinks) {
|
||||
pl.setAttribute(
|
||||
"title",
|
||||
pl.getAttribute("title") + ", klicka för att kopiera",
|
||||
);
|
||||
pl.addEventListener("click", function (evt) {
|
||||
const { target, shiftKey, ctrlKey, altKey } = evt;
|
||||
if (!shiftKey && !ctrlKey && !altKey) {
|
||||
evt.preventDefault();
|
||||
const text = target.href;
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
defmodule Mse25.Directus do
|
||||
@draft_filter "filter[status][_eq]=published"
|
||||
|
||||
def get_article(slug) do
|
||||
get_item(:articles, slug)
|
||||
end
|
||||
|
|
@ -173,6 +175,12 @@ defmodule Mse25.Directus do
|
|||
[base_url: base_url, token: token] = Application.fetch_env!(:mse25, :directus)
|
||||
req = Req.new(base_url: base_url <> "/items")
|
||||
|
||||
resource =
|
||||
case String.contains?(resource, "?") do
|
||||
true -> resource <> "&" <> @draft_filter
|
||||
false -> resource <> "?" <> @draft_filter
|
||||
end
|
||||
|
||||
case Req.get!(req, url: resource, auth: {:bearer, token})
|
||||
|> payload do
|
||||
{:ok, payload} -> payload
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="csrf-token" content={get_csrf_token()} />
|
||||
<title><%= assigns[:page_title] || "Anders Englöf Ytterström" %></title>
|
||||
<title><%= assigns[:page_title] || "Anders Englöf Ytterström" %> | madr.se</title>
|
||||
<link rel="stylesheet" href={~p"/assets/app.css"} />
|
||||
</head>
|
||||
<body class="bg-white">
|
||||
|
|
|
|||
|
|
@ -50,17 +50,16 @@ defmodule Mse25Web.ItemController do
|
|||
"pubDate" => published_at,
|
||||
"date_updated" => updated_at
|
||||
}) do
|
||||
updated =
|
||||
case updated_at do
|
||||
nil -> published_at
|
||||
s -> String.slice(s, 0..9)
|
||||
end
|
||||
|
||||
[
|
||||
page_title: heading,
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at,
|
||||
updated_at: updated,
|
||||
updated_at:
|
||||
case updated_at do
|
||||
nil -> published_at
|
||||
ua -> String.slice(ua, 0..9)
|
||||
end,
|
||||
year: String.slice(published_at, 0..3)
|
||||
]
|
||||
end
|
||||
|
|
@ -72,11 +71,12 @@ defmodule Mse25Web.ItemController do
|
|||
"lead" => lead
|
||||
}) do
|
||||
[
|
||||
page_title: heading,
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at,
|
||||
lead: lead,
|
||||
year: 2024
|
||||
year: String.slice(published_at, 0..3)
|
||||
]
|
||||
end
|
||||
|
||||
|
|
@ -84,15 +84,23 @@ defmodule Mse25Web.ItemController do
|
|||
"title" => heading,
|
||||
"contents" => contents,
|
||||
"pubDate" => published_at,
|
||||
"date_updated" => updated_at,
|
||||
"source" => url,
|
||||
"h1" => title
|
||||
}) do
|
||||
[
|
||||
page_title: heading,
|
||||
heading: heading,
|
||||
contents: Earmark.as_html!(contents),
|
||||
published_at: published_at,
|
||||
url: url,
|
||||
title: title
|
||||
title: title,
|
||||
year: String.slice(published_at, 0..3),
|
||||
updated_at:
|
||||
case updated_at do
|
||||
nil -> published_at
|
||||
ua -> String.slice(ua, 0..9)
|
||||
end
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,35 @@
|
|||
<article>
|
||||
<header>
|
||||
<date><%= @published_at %></date>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
<article class="article">
|
||||
<header>
|
||||
<ol class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
|
||||
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
|
||||
<a href="/" rel="home">
|
||||
<span itemprop="name">madr.se</span>
|
||||
</a>
|
||||
<meta itemprop="position" content="1" />
|
||||
</li>
|
||||
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
|
||||
<a href="/delningar">
|
||||
<span itemprop="name">Delningar</span>
|
||||
</a>
|
||||
<meta itemprop="position" content="2" />
|
||||
</li>
|
||||
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
|
||||
<a href={"/" <> @year}>
|
||||
<span itemprop="name"><%= @year %></span>
|
||||
</a>
|
||||
<meta itemprop="position" content="3" />
|
||||
</li>
|
||||
</ol>
|
||||
<h1><%= @heading %></h1>
|
||||
</header>
|
||||
|
||||
<%= raw @contents %>
|
||||
<p>
|
||||
Källa: <a href={@url} rel="external"><%= @title %></a>
|
||||
</p>
|
||||
<footer>
|
||||
<p>Skribent: Anders Englöf Ytterström. Publicerad <%= @published_at %>.</p>
|
||||
</footer>
|
||||
<%= raw(@contents) %>
|
||||
<p>
|
||||
Källa: <a href={@url} rel="external"><%= @title %></a>
|
||||
</p>
|
||||
<footer>
|
||||
<p>
|
||||
Publicerad <%= @published_at %> <br />och senast uppdaterad <%= @updated_at %>
|
||||
</p>
|
||||
</footer>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ defmodule Mse25Web.PageController do
|
|||
brutal_legends = Directus.get_albums!(limit: 1)
|
||||
|
||||
render(conn, :home,
|
||||
page_title: "Anders Englöf Ytterström @ madr.se",
|
||||
page_title: "Anders Englöf Ytterström",
|
||||
layout: false,
|
||||
recent_article: most_recent_article,
|
||||
older_article: older_article,
|
||||
|
|
@ -29,10 +29,26 @@ defmodule Mse25Web.PageController do
|
|||
)
|
||||
end
|
||||
|
||||
def links(conn, _params) do
|
||||
links = Directus.get_links!(limit: 9999) |> group_by_date
|
||||
|
||||
render(conn, :links,
|
||||
page_title: "Delningar",
|
||||
links: links
|
||||
)
|
||||
end
|
||||
|
||||
defp group_annually(items) do
|
||||
items
|
||||
|> Enum.group_by(fn %{"slug" => slug} -> String.slice(slug, 0..3) end)
|
||||
|> Map.to_list()
|
||||
|> Enum.sort(fn {a, _a}, {b, _b} -> b < a end)
|
||||
end
|
||||
|
||||
defp group_by_date(items) do
|
||||
items
|
||||
|> Enum.group_by(fn %{"pubDate" => pub_date} -> pub_date end)
|
||||
|> Map.to_list()
|
||||
|> Enum.sort(fn {a, _a}, {b, _b} -> b < a end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
73
lib/mse25_web/controllers/page_html/links.html.heex
Normal file
73
lib/mse25_web/controllers/page_html/links.html.heex
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<header>
|
||||
<ol class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
|
||||
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
|
||||
<a href="/" rel="home">
|
||||
<span itemprop="name">madr.se</span>
|
||||
</a>
|
||||
<meta itemprop="position" content="1" />
|
||||
</li>
|
||||
</ol>
|
||||
<h1>Delningar</h1>
|
||||
<p>
|
||||
Länkar som är värda att uppmärksammas och lämna åsikt om.
|
||||
</p>
|
||||
<%= for {date, links} <- @links do %>
|
||||
<section id={"d" <> date}>
|
||||
<div class="links">
|
||||
<h2>
|
||||
<%= date
|
||||
|> Date.from_iso8601!()
|
||||
|> Calendar.strftime(
|
||||
"%A, %d %B %Y",
|
||||
month_names: fn m ->
|
||||
Enum.at(
|
||||
[
|
||||
"januari",
|
||||
"februari",
|
||||
"mars",
|
||||
"april",
|
||||
"maj",
|
||||
"juni",
|
||||
"juli",
|
||||
"augusti",
|
||||
"september",
|
||||
"oktober",
|
||||
"november",
|
||||
"december"
|
||||
],
|
||||
m - 1
|
||||
)
|
||||
end,
|
||||
day_of_week_names: fn d ->
|
||||
Enum.at(
|
||||
[
|
||||
"måndag",
|
||||
"tisdag",
|
||||
"onsdag",
|
||||
"torsdag",
|
||||
"fredag",
|
||||
"lördag",
|
||||
"söndag"
|
||||
],
|
||||
d - 1
|
||||
)
|
||||
end
|
||||
)
|
||||
|> String.replace(~r/ 0/, " ") %>
|
||||
</h2>
|
||||
<%= for link <- links do %>
|
||||
<article>
|
||||
<h3>
|
||||
<%= link["title"] %>
|
||||
<a class="permalink" href={"/" <> link["slug"]} title="Permalänk">#</a>
|
||||
</h3>
|
||||
<%= link["contents"] |> Earmark.as_html!() |> raw %>
|
||||
<div class="source">
|
||||
Källa: <a href={link["source"]} rel="external"><%= link["h1"] %></a>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
</header>
|
||||
|
|
@ -24,8 +24,7 @@ defmodule Mse25Web.Router do
|
|||
# get "/event-map.js", EventController, :interactive_map
|
||||
|
||||
get "/webblogg", PageController, :articles
|
||||
|
||||
# get "/delningar", ShareController, :index
|
||||
get "/delningar", PageController, :links
|
||||
|
||||
# get "/:year", TimelineController, :annual
|
||||
# get "/prenumerera.xml", TimelineController, :feed
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue