Merge pull request 'redesign' (#281) from devel into main

Reviewed-on: #281
This commit is contained in:
inhji 2023-09-05 22:02:37 +02:00
commit 487cae070c
16 changed files with 446 additions and 480 deletions

View file

@ -2,147 +2,83 @@
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./reset.css";
@import "./gruvbox.css";
@import "./lightbox.css";
@import "./tablesort.css";
/*
The base layer is for things like reset rules or default styles applied to plain HTML elements.
*/
@layer base {
:root {
--font-features: "case", "cpsp", "frac", "salt", "ccmp", "cv01", "cv02", "cv03", "cv04", "cv05", "cv06", "cv07", "cv09", "cv10", "cv11";
--color-background: 255 255 255;
--color-foreground: 0 0 0;
--color-primary: 0 0 0;
}
:root {
:root[mode=dark] {
--color-background: 0 0 0;
--color-foreground: 255 255 255;
--color-primary: 255 255 255;
}
html {
font-family: 'Inter', sans-serif;
font-feature-settings: var(--font-features);
}
@supports (font-variation-settings: normal) {
:root {
font-family: 'Inter var', sans-serif;
font-feature-settings: var(--font-features);
}
font-feature-settings: "case", "cpsp", "frac", "salt", "ccmp", "cv01", "cv02", "cv03", "cv04", "cv05", "cv06", "cv07", "cv09", "cv10", "cv11";
}
:root {
--color-primary: 214 93 14; /* orange */
--color-primary1: 175 58 3; /* orange faded */
--color-secondary: 104 157 106; /* aqua */
--color-secondary1: 66 123 88; /* aqua faded */
--color-blue: 69 133 136 ; /* blue */
--color-blue1: 7 102 120; /* blue faded */
--color-purple: 177 98 134 ; /* purple */
--color-purple1: 143 63 113; /* purple faded */
--color-yellow: 215 153 33; /* yellow */
--color-yellow1: 181 118 20; /* yellow faded */
--color-background: 253 244 193; /* light0 */
--color-background1: 235 219 178; /* light1 */
--color-foreground: 60 56 54; /* dark1 */
--color-foreground1: 80 73 69; /* dark2 */
--color-heading: var(--color-secondary);
@apply selection:bg-theme-primary/50;
}
:root[data-mode=dark] {
--color-primary: 214 93 14; /* orange */
--color-primary1: 254 128 25; /* orange bright */
--color-secondary: 104 157 106; /* aqua */
--color-secondary1: 142 192 124; /* aqua bright */
--color-blue: 69 133 136 ; /* blue */
--color-blue1: 131 165 152; /* blue bright */
--color-purple: 177 98 134 ; /* purple */
--color-purple1: 250 189 47; /* purple bright */
--color-yellow: 215 153 33; /* yellow */
--color-yellow1: 181 118 20; /* yellow bright */
--color-background: 40 40 40; /* dark0 */
--color-background1: 60 56 54; /* dark1 */
--color-foreground: 235 219 178; /* light1 */
--color-foreground1: 213 196 161; /* light2 */
--color-heading: var(--color-secondary);
}
:root[data-mode=dark] .prose {
@apply prose-invert;
}
.prose a, a.underline-link {
@apply underline decoration-1 decoration-theme-primary hover:decoration-theme-base transition;
}
.prose a[href^="http://"], .prose a[href^="https://"] {
@apply after:content-['_↗']
}
.prose em {
@apply text-theme-quaternary;
}
.prose h2 { @apply before:font-light before:text-theme-secondary; }
.prose h3 { @apply before:font-light before:text-theme-tertiary; }
.prose h4 { @apply before:font-light before:text-theme-quaternary; }
.prose h1 {
@apply before:content-['#'];
}
.prose h2 {
@apply before:content-['##'];
}
.prose h3 {
@apply before:content-['###'];
}
.prose h4 {
@apply before:content-['####'];
}
.prose pre {
@apply p-0;
}
.prose img {
@apply rounded-lg;
.stack > * + * {
margin-block-start: var(--flow-space, 1em);
}
}
/*
The components layer is for class-based styles that you want to be able to override with utilities.
*/
@layer components {
/* Set width and color for identity icons */
a[rel] svg {
width: 1em;
fill: rgb(var(--color-foreground));
}
.alert {
@apply p-3 mt-3 rounded;
#site-header {
@apply py-8 block px-3 bg-black text-white print:hidden;
}
.alert.alert-danger {
@apply bg-red-100 text-red-500 dark:bg-red-950 dark:text-red-500;
#site-header nav ul {
@apply flex gap-3;
}
.footnotes li p { display: inline; }
.footnotes hr { display: none; }
.footnote:before { content: '{'; }
.footnote:after { content: '}'; }
a.button {
@apply inline-block text-theme-base px-3 py-2.5 border border-theme-background1 hover:bg-theme-background1 rounded transition font-semibold;
#site-content {
@apply grid grid-cols-1 lg:grid-cols-4 gap-3;
}
aside#primary-sidebar {
@apply col-span-1;
}
aside#primary-sidebar nav {
@apply flex flex-col md:flex-row;
}
aside#primary-sidebar .menu {
@apply flex-1;
}
aside#primary-sidebar .menu h2 {
@apply font-bold;
}
aside#secondary-sidebar {
@apply col-span-1;
}
section#content-wrapper {
@apply col-span-3;
}
.divider {
@apply flex items-center my-8 before:flex-1 after:flex-1 before:content-[''] after:content-[''] before:p-[0.5px] after:p-[0.5px] w-full mx-auto last:hidden;
}
}
/*
The utilities layer is for small, single-purpose classes that should always take precedence over any other styles.
*/
@layer utilities {
}

148
assets/css/app.old.css Normal file
View file

@ -0,0 +1,148 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./reset.css";
@import "./gruvbox.css";
@import "./lightbox.css";
@import "./tablesort.css";
@layer base {
:root {
--font-features: "case", "cpsp", "frac", "salt", "ccmp", "cv01", "cv02", "cv03", "cv04", "cv05", "cv06", "cv07", "cv09", "cv10", "cv11";
}
:root {
font-family: 'Inter', sans-serif;
font-feature-settings: var(--font-features);
}
@supports (font-variation-settings: normal) {
:root {
font-family: 'Inter var', sans-serif;
font-feature-settings: var(--font-features);
}
}
:root {
--color-primary: 214 93 14; /* orange */
--color-primary1: 175 58 3; /* orange faded */
--color-secondary: 104 157 106; /* aqua */
--color-secondary1: 66 123 88; /* aqua faded */
--color-blue: 69 133 136 ; /* blue */
--color-blue1: 7 102 120; /* blue faded */
--color-purple: 177 98 134 ; /* purple */
--color-purple1: 143 63 113; /* purple faded */
--color-yellow: 215 153 33; /* yellow */
--color-yellow1: 181 118 20; /* yellow faded */
--color-background: 253 244 193; /* light0 */
--color-background1: 235 219 178; /* light1 */
--color-foreground: 60 56 54; /* dark1 */
--color-foreground1: 80 73 69; /* dark2 */
--color-heading: var(--color-secondary);
@apply selection:bg-theme-primary/50;
}
:root[data-mode=dark] {
--color-primary: 214 93 14; /* orange */
--color-primary1: 254 128 25; /* orange bright */
--color-secondary: 104 157 106; /* aqua */
--color-secondary1: 142 192 124; /* aqua bright */
--color-blue: 69 133 136 ; /* blue */
--color-blue1: 131 165 152; /* blue bright */
--color-purple: 177 98 134 ; /* purple */
--color-purple1: 250 189 47; /* purple bright */
--color-yellow: 215 153 33; /* yellow */
--color-yellow1: 181 118 20; /* yellow bright */
--color-background: 40 40 40; /* dark0 */
--color-background1: 60 56 54; /* dark1 */
--color-foreground: 235 219 178; /* light1 */
--color-foreground1: 213 196 161; /* light2 */
--color-heading: var(--color-secondary);
}
:root[data-mode=dark] .prose {
@apply prose-invert;
}
.prose a, a.underline-link {
@apply underline decoration-1 decoration-theme-primary hover:decoration-theme-base transition;
}
.prose a[href^="http://"], .prose a[href^="https://"] {
@apply after:content-['_↗']
}
.prose em {
@apply text-theme-quaternary;
}
.prose h2 { @apply before:font-light before:text-theme-secondary; }
.prose h3 { @apply before:font-light before:text-theme-tertiary; }
.prose h4 { @apply before:font-light before:text-theme-quaternary; }
.prose h1 {
@apply before:content-['#'];
}
.prose h2 {
@apply before:content-['##'];
}
.prose h3 {
@apply before:content-['###'];
}
.prose h4 {
@apply before:content-['####'];
}
.prose pre {
@apply p-0;
}
.prose img {
@apply rounded-lg;
}
}
@layer components {
/* Set width and color for identity icons */
a[rel] svg {
width: 1em;
fill: rgb(var(--color-foreground));
}
.alert {
@apply p-3 mt-3 rounded;
}
.alert.alert-danger {
@apply bg-red-100 text-red-500 dark:bg-red-950 dark:text-red-500;
}
.footnotes li p { display: inline; }
.footnotes hr { display: none; }
.footnote:before { content: '{'; }
.footnote:after { content: '}'; }
a.button {
@apply inline-block text-theme-base px-3 py-2.5 border border-theme-background1 hover:bg-theme-background1 rounded transition font-semibold;
}
}

View file

@ -14,59 +14,7 @@ module.exports = {
],
darkMode: ['class', '[data-mode="dark"]'],
theme: {
extend: {
typography: {
gruvbox: {
css: {
'--tw-prose-td-borders': 'rgb(var(--color-background1))',
'--tw-prose-th-borders': 'rgb(var(--color-background1))',
'--tw-prose-body': 'rgb(var(--color-foreground))',
'--tw-prose-links': 'rgb(var(--color-foreground))',
'--tw-prose-headings': 'rgb(var(--color-foreground))',
'--tw-prose-bold': 'rgb(var(--color-yellow1))',
'--tw-prose-quotes': 'rgb(var(--color-foreground))',
'--tw-prose-bullets': 'rgb(var(--color-primary))',
'--tw-prose-code': 'rgb(var(--color-yellow1))',
'--tw-prose-pre-bg': 'rgb(var(--color-background1))',
'--tw-prose-quote-borders': 'rgb(var(--color-primary))',
'--tw-prose-counters': 'rgb(var(--color-foreground))',
'--tw-prose-invert-td-borders': 'rgb(var(--color-background1))',
'--tw-prose-invert-th-borders': 'rgb(var(--color-background1))',
'--tw-prose-invert-body': 'rgb(var(--color-foreground))',
'--tw-prose-invert-links': 'rgb(var(--color-foreground))',
'--tw-prose-invert-headings': 'rgb(var(--color-foreground))',
'--tw-prose-invert-bold': 'rgb(var(--color-yellow))',
'--tw-prose-invert-quotes': 'rgb(var(--color-foreground))',
'--tw-prose-invert-bullets': 'rgb(var(--color-primary))',
'--tw-prose-invert-quote-borders': 'rgb(var(--color-primary))',
'--tw-prose-invert-code': 'rgb(var(--color-yellow))',
'--tw-prose-invert-pre-bg': 'rgb(var(--color-background1))',
'--tw-prose-invert-counters': 'rgb(var(--color-foreground))',
}
}
},
colors: {
code: colors.emerald,
gray: colors.zinc,
theme: {
background: 'rgb(var(--color-background) / <alpha-value>)',
background1: 'rgb(var(--color-background1) / <alpha-value>)',
base: 'rgb(var(--color-foreground) / <alpha-value>)',
base1: 'rgb(var(--color-foreground1) / <alpha-value>)',
primary: 'rgb(var(--color-primary) / <alpha-value>)',
primary1: 'rgb(var(--color-primary1) / <alpha-value>)',
secondary: 'rgb(var(--color-secondary) / <alpha-value>)',
secondary1: 'rgb(var(--color-secondary1) / <alpha-value>)',
tertiary: 'rgb(var(--color-blue) / <alpha-value>)',
tertiary1: 'rgb(var(--color-blue1) / <alpha-value>)',
quaternary: 'rgb(var(--color-purple) / <alpha-value>)',
quaternary1: 'rgb(var(--color-purple1) / <alpha-value>)',
quinary: 'rgb(var(--color-yellow) / <alpha-value>)',
quinary1: 'rgb(var(--color-yellow1) / <alpha-value>)',
heading: 'rgb(var(--color-heading) / <alpha-value>)'
}
}
},
container: { center: true }
},
plugins: [
require("@tailwindcss/forms"),

View file

@ -1,7 +1,5 @@
defmodule ChiyaWeb.Layouts do
use ChiyaWeb, :html
import ChiyaWeb.PublicComponents, only: [divider: 1, site_header: 1]
embed_templates "layouts/*"
end

View file

@ -34,56 +34,96 @@
<%= @settings.custom_css %>
</style>
</head>
<body class="text-theme-base bg-theme-background | h-feed hfeed">
<aside class="block print:hidden">
<%= raw(@settings.custom_html) %>
</aside>
<header class="my-8 block px-3 print:hidden">
<.site_header user={@current_user} />
<body class="stack | h-feed hfeed">
<header id="site-header">
<nav class="container">
<ul>
<li>
<a href="/">
<span>Home</span>
</a>
</li>
<li>
<a href="/about">
<span>About</span>
</a>
</li>
<li>
<a href="/wiki">
<span>Wiki</span>
</a>
</li>
<li>
<a href="/bookmarks">
<span>Bookmarks</span>
</a>
</li>
<li class="flex-1"></li>
<%= if @current_user do %>
<li>
<a href="/admin">
Admin
</a>
</li>
<% end %>
</ul>
</nav>
</header>
<main class="mx-3 md:mx-0">
<%= @inner_content %>
<main id="site-content" class="container print:hidden">
<aside id="primary-sidebar">
<nav>
<div class="menu">
<h2>Info</h2>
<ul>
<li>Served by Chiya v<%= Application.spec(:chiya, :vsn) %></li>
<li>Made by Inhji</li>
</ul>
</div>
<div class="menu">
<h2>Links</h2>
<ul>
<li><a href={~p"/wiki"}>Wiki</a></li>
<li><a href={~p"/about"}>About</a></li>
</ul>
</div>
<div class="menu">
<h2>Elsewhere</h2>
<ul>
<%= for identity <- @public_identities do %>
<li><a href={identity.url}><%= identity.name %></a></li>
<% end %>
</ul>
</div>
<div class="menu">
<h2>Elsewhere</h2>
<ul>
<%= for channel <- @channels do %>
<li>
<a href={~p"/channel/#{channel.slug}"}>
<%= channel.name %>
</a>
</li>
<% end %>
</ul>
</div>
</nav>
</aside>
<section id="content-wrapper">
<%= @inner_content %>
</section>
</main>
<footer class="max-w-full mt-8 p-8 text-theme-base/75 bg-theme-background1 print:hidden">
<section class="max-w-2xl mx-auto flex gap-3">
<div class="flex-1">
<h2 class="font-bold tracking-wider">Info</h2>
<ul class="list-disc list-inside">
<li>Served by Chiya v<%= Application.spec(:chiya, :vsn) %></li>
<li>Made by Inhji</li>
</ul>
</div>
<div class="flex-1">
<h2 class="font-bold tracking-wider">Links</h2>
<ul class="list-disc list-inside">
<li><a href={~p"/wiki"}>Wiki</a></li>
<li><a href={~p"/about"}>About</a></li>
</ul>
</div>
<div class="flex-1">
<h2 class="font-bold tracking-wider">Elsewhere</h2>
<ul class="list-disc list-inside">
<%= for identity <- @public_identities do %>
<li><a href={identity.url}><%= identity.name %></a></li>
<% end %>
</ul>
</div>
</section>
<section class="max-w-2xl mx-auto">
<.divider />
<div data-dummy="true" />
</section>
<p class="mt-4 max-w-2xl mx-auto text-center">
<p class="container text-center">
Struggling to make a decent website since 2011
</p>
</footer>

View file

@ -58,17 +58,7 @@ defmodule ChiyaWeb.PublicComponents do
do: ~H"""
<hr class="my-6 border-theme-base/20" />
"""
attr :text, :string, default: ""
def divider(assigns) do
~H"""
<div class="flex items-center my-8 text-theme-primary before:flex-1 after:flex-1 before:content-[''] after:content-[''] before:p-[0.5px] after:p-[0.5px] before:bg-theme-base/25 after:bg-theme-base/25 w-full mx-auto last:hidden">
<%= assigns.text %>
</div>
"""
end
attr :note, :map, required: true
attr :class_tag, :string, default: ""
attr :linked, :boolean, default: true
@ -116,211 +106,7 @@ defmodule ChiyaWeb.PublicComponents do
</header>
"""
end
attr :layout, :atom, default: :list
attr :notes, :list, required: true
attr :show_content, :boolean, default: true
def note_list(assigns) do
case assigns.layout do
:gallery ->
note_list_gallery(assigns)
:microblog ->
note_list_microblog(assigns)
_ ->
note_list_default(assigns)
end
end
attr :notes, :list, required: true
@doc """
Default note list that renders a list of rounded boxes,
which show the note title and an excerpt of the content
"""
def note_list_default(assigns) do
~H"""
<section class="note-list default | sm:w-auto flex flex-col gap-3">
<%= for note <- assigns.notes do %>
<a
href={~p"/note/#{note.slug}"}
class="block rounded-lg px-6 py-4 border border-theme-background1 hover:bg-theme-background1 transition"
>
<header class="flex flex-row items-center gap-1">
<span class="text-theme-primary text-lg font-semibold leading-8 flex-1">
<%= note.name %>
</span>
<span class="text-theme-base/75 text-sm">
<%= pretty_date(note.published_at) %>
</span>
</header>
<%= if assigns.show_content do %>
<p class="text-theme-base">
<%= String.slice(note.content, 0..150) %>
</p>
<% end %>
<%= if not Enum.empty?(note.tags) do %>
<span class="inline-block">
<.tags note={note} linked={false} />
</span>
<% end %>
</a>
<% end %>
</section>
"""
end
attr :notes, :list, required: true
def note_list_microblog(assigns) do
~H"""
<section class="note-list microblog | mt-6 text-theme-base">
<%= for note <- assigns.notes do %>
<article class="mt-4 first:mt-0">
<.featured_images note={note} />
<header class="mt-4 text-lg">
<%= if(note.kind == :bookmark) do %>
<strong><%= note.name %></strong>
<% end %>
</header>
<div class="prose prose-gruvbox mt-4">
<%= raw(render(note.content)) %>
</div>
<footer class="mt-4">
<a href={~p"/note/#{note.slug}"}>
<time class="text-theme-base/75">
<%= pretty_datetime(note.published_at) %>
</time>
</a>
<%= if not Enum.empty?(note.tags) do %>
<.dot />
<.tags note={note} class_tag="text-theme-base/75" />
<% end %>
</footer>
</article>
<.divider />
<% end %>
</section>
"""
end
attr :notes, :list, required: true
def note_list_gallery(assigns) do
~H"""
<section class="note-list gallery | mt-6">
<%= for note <- assigns.notes do %>
<article>
<section class="flex flex-wrap justify-start gap-3">
<%= for image <- note.images do %>
<a
href={ChiyaWeb.Helpers.image_url(image, :full)}
class="lightbox | w-28"
data-gallery={gallery_name(note)}
data-description={ChiyaWeb.Markdown.render(image.content)}
>
<img src={ChiyaWeb.Helpers.image_url(image, :thumb)} loading="lazy" />
</a>
<% end %>
</section>
<a
href={~p"/note/#{note.slug}"}
class="text-theme-secondary text-lg/10 font-semibold rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-secondary/10 transition"
>
<%= note.name %>
<span class="text-theme-base/75 text-sm">
<%= pretty_date(note.published_at) %>
</span>
</a>
</article>
<.line />
<% end %>
</section>
"""
end
attr :user, :map, required: true
def site_header(assigns) do
~H"""
<nav class="mx-auto max-w-2xl">
<ul class="flex gap-3">
<li>
<a href="/" class="button">
<.icon name="hero-home" />
</a>
</li>
<li>
<a href="/about" class="button">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-umbrella inline"
viewBox="0 0 16 16"
>
<path d="M8 0a.5.5 0 0 1 .5.5v.514C12.625 1.238 16 4.22 16 8c0 0 0 .5-.5.5-.149 0-.352-.145-.352-.145l-.004-.004-.025-.023a3.484 3.484 0 0 0-.555-.394A3.166 3.166 0 0 0 13 7.5c-.638 0-1.178.213-1.564.434a3.484 3.484 0 0 0-.555.394l-.025.023-.003.003s-.204.146-.353.146-.352-.145-.352-.145l-.004-.004-.025-.023a3.484 3.484 0 0 0-.555-.394 3.3 3.3 0 0 0-1.064-.39V13.5H8h.5v.039l-.005.083a2.958 2.958 0 0 1-.298 1.102 2.257 2.257 0 0 1-.763.88C7.06 15.851 6.587 16 6 16s-1.061-.148-1.434-.396a2.255 2.255 0 0 1-.763-.88 2.958 2.958 0 0 1-.302-1.185v-.025l-.001-.009v-.003s0-.002.5-.002h-.5V13a.5.5 0 0 1 1 0v.506l.003.044a1.958 1.958 0 0 0 .195.726c.095.191.23.367.423.495.19.127.466.229.879.229s.689-.102.879-.229c.193-.128.328-.304.424-.495a1.958 1.958 0 0 0 .197-.77V7.544a3.3 3.3 0 0 0-1.064.39 3.482 3.482 0 0 0-.58.417l-.004.004S5.65 8.5 5.5 8.5c-.149 0-.352-.145-.352-.145l-.004-.004a3.482 3.482 0 0 0-.58-.417A3.166 3.166 0 0 0 3 7.5c-.638 0-1.177.213-1.564.434a3.482 3.482 0 0 0-.58.417l-.004.004S.65 8.5.5 8.5C0 8.5 0 8 0 8c0-3.78 3.375-6.762 7.5-6.986V.5A.5.5 0 0 1 8 0zM6.577 2.123c-2.833.5-4.99 2.458-5.474 4.854A4.124 4.124 0 0 1 3 6.5c.806 0 1.48.25 1.962.511a9.706 9.706 0 0 1 .344-2.358c.242-.868.64-1.765 1.271-2.53zm-.615 4.93A4.16 4.16 0 0 1 8 6.5a4.16 4.16 0 0 1 2.038.553 8.688 8.688 0 0 0-.307-2.13C9.434 3.858 8.898 2.83 8 2.117c-.898.712-1.434 1.74-1.731 2.804a8.687 8.687 0 0 0-.307 2.131zm3.46-4.93c.631.765 1.03 1.662 1.272 2.53.233.833.328 1.66.344 2.358A4.14 4.14 0 0 1 13 6.5c.77 0 1.42.23 1.897.477-.484-2.396-2.641-4.355-5.474-4.854z" />
</svg>
<span class="hidden sm:inline-block">About</span>
</a>
</li>
<li>
<a href="/wiki" class="button">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-journals inline"
viewBox="0 0 16 16"
>
<path d="M5 0h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2 2 2 0 0 1-2 2H3a2 2 0 0 1-2-2h1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1H1a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v9a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1H3a2 2 0 0 1 2-2z" />
<path d="M1 6v-.5a.5.5 0 0 1 1 0V6h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0V9h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 2.5v.5H.5a.5.5 0 0 0 0 1h2a.5.5 0 0 0 0-1H2v-.5a.5.5 0 0 0-1 0z" />
</svg>
<span class="hidden sm:inline">Wiki</span>
</a>
</li>
<li>
<a href="/bookmarks" class="button">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-bookmark-fill inline"
viewBox="0 0 16 16"
>
<path d="M2 2v13.5a.5.5 0 0 0 .74.439L8 13.069l5.26 2.87A.5.5 0 0 0 14 15.5V2a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2z" />
</svg>
<span class="hidden sm:inline-block">Bookmarks</span>
</a>
</li>
<li class="flex-1"></li>
<%= if @user do %>
<li>
<a href="/admin" class="button">
<.icon name="hero-beaker" />
</a>
</li>
<% end %>
<li>
<.darkmode_toggle class="button" />
</li>
</ul>
</nav>
"""
end
attr :note, :map, required: true
def featured_images(assigns) do
@ -406,8 +192,6 @@ defmodule ChiyaWeb.PublicComponents do
"""
end
defp gallery_name(note), do: "gallery-#{note.id}"
defp main_images(note),
do: Enum.filter(note.images, fn image -> image.featured end)
end

View file

@ -1,9 +1,14 @@
defmodule ChiyaWeb.PageHTML do
use ChiyaWeb, :html_public
import Phoenix.HTML.Tag, only: [content_tag: 3, content_tag: 2]
import ChiyaWeb.Format, only: [pretty_datetime: 1, pretty_date: 1, datetime: 1]
embed_templates "page_html/*"
attr :notes, :list, required: true
def note_list_default(assigns)
def tag_list([]), do: "No Tags"
def tag_list(tags), do: Enum.map_join(tags, ", ", fn t -> t.name end)

View file

@ -8,7 +8,15 @@
<section class="mt-6 grid grid-cols-1 md:grid-cols-3 gap-3 max-w-4xl mx-auto">
<section class="col-span-1 md:col-span-2">
<.note_list notes={@notes} layout={@channel.layout} show_content={false} />
<%= if @channel.layout == :default do %>
<.note_list_default notes={@channel.notes}/>
<% end %>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery notes={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog notes={@channel.notes}/>
<% end %>
</section>
<section>

View file

@ -5,6 +5,14 @@
</.header>
<div class="w-full mt-6 sm:w-auto flex flex-col gap-1.5">
<.note_list notes={@channel.notes} layout={@channel.layout} />
<%= if @channel.layout == :default do %>
<.note_list_default notes={@channel.notes}/>
<% end %>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery notes={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog notes={@channel.notes}/>
<% end %>
</div>
</section>

View file

@ -1,29 +1,11 @@
<section class="max-w-2xl mx-auto">
<.header class_title="text-theme-primary p-name" class_subtitle="p-summary">
<%= @settings.title %>
<:subtitle><%= @settings.subtitle %></:subtitle>
</.header>
<section class="text-sm my-8">
<ul class="flex flex-wrap gap-3">
<li>
<a href="#" class="button">
<.icon name="hero-megaphone" />
</a>
</li>
<%= for channel <- @channels do %>
<li>
<a href={~p"/channel/#{channel.slug}"} class="button">
<%= channel.name %>
</a>
</li>
<% end %>
</ul>
</section>
<%= if @channel do %>
<section class="mt-8">
<.note_list notes={@channel.notes} layout={@channel.layout} />
</section>
<%= if @channel do %>
<%= if @channel.layout == :default do %>
<.note_list_default notes={@channel.notes}/>
<% end %>
</section>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery notes={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog notes={@channel.notes}/>
<% end %>
<% end %>

View file

@ -34,8 +34,8 @@
<%= if not Enum.empty?(@note.links_to) do %>
<section class="mt-8 prose prose-gruvbox max-w-2xl mx-auto">
<.divider text="" /> Notes linking here:
<ul class="">
Notes linking here:
<ul>
<%= for link <- @note.links_to do %>
<li><a href={~p"/note/#{link.slug}"}><%= link.name %></a></li>
<% end %>
@ -45,7 +45,6 @@
<%= if String.length(@note.url || "") > 0 do %>
<section class="mt-8 max-w-2xl mx-auto text-center text-lg">
<.divider text=" " />
<.icon name="hero-link" /> <a href={@note.url}><%= @note.url %></a>
</section>
<% end %>
@ -77,8 +76,6 @@
<section class="max-w-2xl mx-auto mt-8">
<%= if !Enum.empty?(@note.images) do %>
<.line />
<div class="flex flex-wrap gap-3">
<%= for image <- @note.images do %>
<a

View file

@ -0,0 +1,29 @@
<section class="note-list default">
<%= for note <- assigns.notes do %>
<a
href={~p"/note/#{note.slug}"}
class="block rounded-lg px-6 py-4 border border-theme-background1 hover:bg-theme-background1 transition"
>
<header class="flex flex-row items-center gap-1">
<span class="text-theme-primary text-lg font-semibold leading-8 flex-1">
<%= note.name %>
</span>
<span class="text-theme-base/75 text-sm">
<%= pretty_date(note.published_at) %>
</span>
</header>
<%= if assigns.show_content do %>
<p class="text-theme-base">
<%= String.slice(note.content, 0..150) %>
</p>
<% end %>
<%= if not Enum.empty?(note.tags) do %>
<span class="inline-block">
<.tags note={note} linked={false} />
</span>
<% end %>
</a>
<% end %>
</section>

View file

@ -0,0 +1,30 @@
<section class="note-list gallery | stack">
<%= for note <- assigns.notes do %>
<article>
<section class="flex flex-wrap justify-start gap-3">
<%= for image <- note.images do %>
<a
href={ChiyaWeb.Helpers.image_url(image, :full)}
class="lightbox | w-28"
data-gallery={"gallery-#{note.id}"}
data-description={ChiyaWeb.Markdown.render(image.content)}
>
<img src={ChiyaWeb.Helpers.image_url(image, :thumb)} loading="lazy" />
</a>
<% end %>
</section>
<a
href={~p"/note/#{note.slug}"}
class="text-theme-secondary text-lg/10 font-semibold rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-secondary/10 transition"
>
<%= note.name %>
<span class="text-theme-base/75 text-sm">
<%= pretty_date(note.published_at) %>
</span>
</a>
</article>
<.line />
<% end %>
</section>

View file

@ -0,0 +1,29 @@
<section class="note-list microblog | stack">
<%= for note <- assigns.notes do %>
<article class="stack">
<.featured_images note={note} />
<header class="text-lg">
<%= if(note.kind == :bookmark) do %>
<strong><%= note.name %></strong>
<% end %>
</header>
<div class="prose">
<%= raw(Markdown.render(note.content)) %>
</div>
<footer>
<a href={~p"/note/#{note.slug}"}>
<time>
<%= pretty_datetime(note.published_at) %>
</time>
</a>
<%= if not Enum.empty?(note.tags) do %>
<.dot />
<.tags note={note} />
<% end %>
</footer>
</article>
<% end %>
</section>

View file

@ -5,6 +5,14 @@
</.header>
<div class="w-full mt-6 sm:w-auto flex flex-col gap-1.5">
<.note_list notes={@tag.notes} />
<%= if @channel.layout == :default do %>
<.note_list_default note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog note={@channel.notes}/>
<% end %>
</div>
</section>

View file

@ -14,13 +14,29 @@
<div class="mt-6 flex flex-1 flex-col gap-1.5">
<h2 class="text-xl text-theme-base">Recently Updated</h2>
<.note_list notes={@notes_updated} layout={@channel.layout} show_content={false} />
<%= if @channel.layout == :default do %>
<.note_list_default note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog note={@channel.notes}/>
<% end %>
</div>
<div class="mt-6 flex flex-1 flex-col gap-1.5">
<h2 class="text-xl text-theme-base">Recently Published</h2>
<.note_list notes={@notes_published} layout={@channel.layout} show_content={false} />
<%= if @channel.layout == :default do %>
<.note_list_default note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :gallery do %>
<.note_list_gallery note={@channel.notes}/>
<% end %>
<%= if @channel.layout == :microblog do %>
<.note_list_microblog note={@channel.notes}/>
<% end %>
</div>
</aside>
</section>