add markup to topics list view

This commit is contained in:
Lera Elvoé 2025-05-22 01:46:08 +03:00
parent 9b42d05174
commit 1cb9262ad7
Signed by: yagich
SSH Key Fingerprint: SHA256:6xjGb6uA7lAVcULa7byPEN//rQ0wPoG+UzYVMfZnbvc
5 changed files with 115 additions and 13 deletions

View File

@ -22,7 +22,25 @@ local ThreadCreateError = {
}
app:get("all_topics", "", function(self)
self.topic_list = db.query("select * from topics limit 25;")
self.topic_list = db.query([[
SELECT
topics.name, topics.slug, topics.description, topics.is_locked,
users.username AS latest_thread_username,
threads.title AS latest_thread_title,
threads.slug AS latest_thread_slug,
threads.created_at AS latest_thread_created_at
FROM
topics
LEFT JOIN (
SELECT
*,
row_number() OVER (PARTITION BY threads.topic_id ORDER BY threads.created_at DESC) as rn
FROM
threads
) threads ON threads.topic_id = topics.id AND threads.rn = 1
LEFT JOIN
users on users.id = threads.user_id
]])
self.me = util.get_logged_in_user_or_transient(self)
return {render = "topics.topics"}
end)

View File

@ -35,6 +35,10 @@ $button_color: color.adjust($accent_color, $hue: 90);
&:active {
background-color: color.scale($color, $lightness: -10%, $saturation: -70%);
}
&:disabled {
background-color: color.scale($color, $lightness: 30%, $saturation: -90%);
}
}
@mixin navbar($color) {
@ -338,3 +342,27 @@ input[type="text"], input[type="password"], textarea, select {
text-overflow: ellipsis;
display: inline;
}
.topic {
display: grid;
grid-template-columns: 1.5fr 64px;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"topic-info-container topic-locked-container";
}
.topic-info-container {
grid-area: topic-info-container;
background-color: $accent_color;
padding: 5px 20px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.topic-locked-container {
grid-area: topic-locked-container;
border: 2px outset $light;
}

View File

@ -164,6 +164,9 @@ button:hover, input[type=submit]:hover, .linkbutton:hover {
button:active, input[type=submit]:active, .linkbutton:active {
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
}
button:disabled, input[type=submit]:disabled, .linkbutton:disabled {
background-color: rgb(209.535, 211.565, 211.46);
}
button.critical, input[type=submit].critical, .linkbutton.critical {
color: white;
background-color: red;
@ -174,6 +177,9 @@ button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:h
button.critical:active, input[type=submit].critical:active, .linkbutton.critical:active {
background-color: rgb(149.175, 80.325, 80.325);
}
button.critical:disabled, input[type=submit].critical:disabled, .linkbutton.critical:disabled {
background-color: rgb(174.675, 156.825, 156.825);
}
button.warn, input[type=submit].warn, .linkbutton.warn {
background-color: #fbfb8d;
}
@ -183,6 +189,9 @@ button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
button.warn:active, input[type=submit].warn:active, .linkbutton.warn:active {
background-color: rgb(198.3813559322, 198.3813559322, 154.4186440678);
}
button.warn:disabled, input[type=submit].warn:disabled, .linkbutton.warn:disabled {
background-color: rgb(217.55, 217.55, 209.85);
}
input[type=file]::file-selector-button {
background-color: rgb(177, 206, 204.5);
@ -194,6 +203,9 @@ input[type=file]::file-selector-button:hover {
input[type=file]::file-selector-button:active {
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
}
input[type=file]::file-selector-button:disabled {
background-color: rgb(209.535, 211.565, 211.46);
}
p {
margin: 15px 0;
@ -213,6 +225,9 @@ p {
.pagebutton:active {
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
}
.pagebutton:disabled {
background-color: rgb(209.535, 211.565, 211.46);
}
.currentpage {
border: none;
@ -326,3 +341,26 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
text-overflow: ellipsis;
display: inline;
}
.topic {
display: grid;
grid-template-columns: 1.5fr 64px;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas: "topic-info-container topic-locked-container";
}
.topic-info-container {
grid-area: topic-info-container;
background-color: #c1ceb1;
padding: 5px 20px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.topic-locked-container {
grid-area: topic-locked-container;
border: 2px outset rgb(217.26, 220.38, 213.42);
}

View File

@ -1,16 +1,33 @@
<h1>Topics</h1>
<nav class="darkbg">
<h1 class="thread-title">All topics</h1>
<% if me:is_mod() then %>
<a class="linkbutton" href="<%= url_for("topic_create") %>">Create new topic</a>
<% end %>
</nav>
<% if #topic_list == 0 then %>
<p>There are no topics.</p>
<p>There are no topics.</p>
<% else %>
<ul>
<% for i, v in ipairs(topic_list) do %>
<li>
<a href=<%= url_for("topic", {slug = v.slug}) %>><%= v.name %></a> - <%= v.description %>
</li>
<% for _, topic in ipairs(topic_list) do %>
<% local is_locked = ntob(topic.is_locked) %>
<div class="topic">
<div class="topic-info-container">
<a href=<%= url_for("topic", {slug = topic.slug}) %>><%= topic.name %></a>
<%= topic.description %>
<% if topic.latest_thread_username then %>
<span>
Latest thread: <a href="<%= url_for("thread", {slug = topic.latest_thread_slug}) %>"><%= topic.latest_thread_title %></a> by <a href="<%= url_for("user", {username = topic.latest_thread_username}) %>"><%= topic.latest_thread_username %></a> on <%= os.date("%c", topic.latest_thread_created_at) %>
</span>
<% else %>
<i>No threads yet.</i>
<% end %>
</div>
<div class="topic-locked-container contain-svg">
<% if is_locked then -%>
<% render("svg-icons.lock") %>
<i>Locked</i>
<% end -%>
</div>
</div>
<% end %>
<% end %>
</ul>
<% if me:is_mod() then %>
<a href="<%= url_for("topic_create") %>">Create new topic</a>
<% end %>

View File

@ -1,3 +1,4 @@
<% local disable_avatar = me:is_logged_in_guest() %>
<div class="darkbg settings-container">
<h1>User settings</h1>
<% if infobox then %>
@ -7,7 +8,7 @@
<img src="<%= avatar_url(me) %>">
<input id="file" type="file" name="avatar" accept="image/*" required>
<div>
<input type="submit" value="Update avatar">
<input type="submit" value="Update avatar" <%= disable_avatar and "disabled=disabled" %>>
<% if not me:is_default_avatar() then %>
<input type="submit" value="Clear avatar" formaction="<%= url_for("user_clear_avatar", {username = me.username}) %>" formnovalidate>
<% end %>