Compare commits
5 Commits
c79cc5797a
...
8ea9afd39d
Author | SHA1 | Date | |
---|---|---|---|
8ea9afd39d | |||
873a4c0c15 | |||
90cacad449 | |||
d1e29822ac | |||
8cd4695794 |
8
app.lua
8
app.lua
@ -1,4 +1,5 @@
|
||||
local lapis = require("lapis")
|
||||
local date = require("date")
|
||||
local app = lapis.Application()
|
||||
local constants = require("constants")
|
||||
local babycode = require("lib.babycode")
|
||||
@ -14,6 +15,13 @@ local util = require("util")
|
||||
app:enable("etlua")
|
||||
app.layout = require "views.base"
|
||||
|
||||
app.cookie_attributes = function (self, name, value)
|
||||
if name == config.session_name then
|
||||
local expires = date(true):adddays(30):fmt("${http}")
|
||||
return "Expires="..expires.."; Path=/; HttpOnly; Secure"
|
||||
end
|
||||
end
|
||||
|
||||
local function inject_constants(req)
|
||||
req.constants = constants
|
||||
math.randomseed(os.time())
|
||||
|
@ -4,7 +4,6 @@ local secrets = require("secrets.secrets")
|
||||
local commit = nil
|
||||
local f = io.open(".git/refs/heads/main", "r")
|
||||
if f then
|
||||
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!read commit")
|
||||
commit = f:read(8)
|
||||
f:close()
|
||||
end
|
||||
|
@ -435,6 +435,12 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.block-img {
|
||||
object-fit: contain;
|
||||
max-width: 400px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
.thread-info-container {
|
||||
grid-area: thread-info-container;
|
||||
background-color: #c1ceb1;
|
||||
|
10
js/date-fmt.js
Normal file
10
js/date-fmt.js
Normal file
@ -0,0 +1,10 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const timestampSpans = document.getElementsByClassName("timestamp");
|
||||
for (let timestampSpan of timestampSpans) {
|
||||
const timestamp = parseInt(timestampSpan.dataset.utc);
|
||||
if (!isNaN(timestamp)) {
|
||||
const date = new Date(timestamp * 1000);
|
||||
timestampSpan.textContent = date.toLocaleString();
|
||||
}
|
||||
}
|
||||
})
|
@ -96,6 +96,13 @@ function babycode.to_html(s, escape_html)
|
||||
return "<ol>" .. get_list_items(list_body, escape_html) .. "</ol>"
|
||||
end)
|
||||
|
||||
-- images
|
||||
local images = {}
|
||||
text = text:gsub("%[img=(.-)%](.-)%[/img%]", function (img, alt)
|
||||
table.insert(images, {img = img, alt = alt})
|
||||
return "\1IMG:"..#images.."\1"
|
||||
end)
|
||||
|
||||
-- normalize newlines, attempt #4
|
||||
text = text:gsub(" +%s*\r?\n", "<br>")
|
||||
text = text:gsub("(%S)(\r?\n\r?\n)\r?\n*", "%1<br><br>")
|
||||
@ -131,6 +138,11 @@ function babycode.to_html(s, escape_html)
|
||||
-- rule
|
||||
text = text:gsub("\n+%-%-%-", "<hr>")
|
||||
|
||||
-- <div class=\"post-img-container\"><img src=%1 alt=%2></div>
|
||||
text = text:gsub("\1IMG:(%d+)\1", function (n)
|
||||
local img = images[tonumber(n)]
|
||||
return ("<div class=\"block-img-container\"><img class=\"block-img\" src=\"%s\" alt=\"%s\"></div>"):format(img.img, img.alt)
|
||||
end)
|
||||
-- replace code block placeholders back with their original contents
|
||||
text = text:gsub("\1CODE:(%d+)\1", function(n)
|
||||
local code = code_blocks[tonumber(n)]
|
||||
|
@ -447,6 +447,12 @@ input[type="text"], input[type="password"], textarea, select {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.block-img {
|
||||
object-fit: contain;
|
||||
max-width: 400px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
.thread-info-container {
|
||||
grid-area: thread-info-container;
|
||||
background-color: $accent_color;
|
||||
|
@ -17,5 +17,6 @@
|
||||
</span>
|
||||
</footer>
|
||||
<script src="/static/js/copy-code.js"></script>
|
||||
<script src="/static/js/date-fmt.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,6 +5,7 @@
|
||||
<li>[b]<b>bold</b>[/b]</li>
|
||||
<li>[i]<i>italic</i>[/i]</li>
|
||||
<li>[s]<del>strikethrough</del>[/s]</li>
|
||||
<li>[img=https://example.com/some-image]alt text[/img] creates an image</li>
|
||||
<li>[url=https://example.com]<a href="https://example.com">labeled URL</a>[/url]</li>
|
||||
<li>
|
||||
[ul] and [ol] are unordered and ordered lists:
|
||||
|
1
views/common/timestamp.etlua
Normal file
1
views/common/timestamp.etlua
Normal file
@ -0,0 +1 @@
|
||||
<span class="timestamp" data-utc="<%= timestamp %>"><%= os.date("%c", timestamp) %></span>
|
@ -22,14 +22,14 @@
|
||||
%>
|
||||
<a href="<%= post_url %>" title="Permalink"><i>
|
||||
<% if tonumber(post.edited_at) > tonumber(post.created_at) then -%>
|
||||
Edited at <%= os.date("%c", post.edited_at) %>
|
||||
Edited at <% render("views.common.timestamp", {timestamp = post.edited_at}) -%>
|
||||
<% else -%>
|
||||
Posted on <%= os.date("%c", post.created_at) %>
|
||||
Posted on <% render("views.common.timestamp", {timestamp = post.created_at}) -%>
|
||||
<% end -%>
|
||||
</i></a>
|
||||
<span>
|
||||
<%
|
||||
local show_edit = me.id == post.user_id and not me:is_guest() and not ntob(thread.is_locked) and not no_reply
|
||||
local show_edit = me.id == post.user_id and not me:is_guest() and (not ntob(thread.is_locked) or me:is_mod()) and not no_reply
|
||||
if show_edit then
|
||||
%>
|
||||
<a class="linkbutton" href="<%= url_for("edit_post", {post_id = post.id}) %>">Edit</a>
|
||||
@ -47,8 +47,8 @@
|
||||
end
|
||||
if show_reply then
|
||||
local d = post.created_at < post.edited_at and post.edited_at or post.created_at
|
||||
local quote_src_text = ("On [url=%s]%s[/url], [url=%s]%s[/url] said:"):format(
|
||||
post_url, os.date("%c", d), url_for("user", {username = post.username}), post.username
|
||||
local quote_src_text = ("[url=%s]%s said:[/url]"):format(
|
||||
post_url, post.username
|
||||
)
|
||||
local reply_text = ("%s\n[quote]%s[/quote]\n---\n\n"):format(quote_src_text, post.original_markup)
|
||||
%>
|
||||
|
@ -48,11 +48,11 @@
|
||||
<span class="thread-title"><a href="<%= url_for("thread", {slug = thread.slug}) %>"><%= thread.title %></a></span>
|
||||
•
|
||||
Started by <a href=<%= url_for("user", {username = thread.started_by}) %>><%= thread.started_by %></a>
|
||||
on <%= os.date("%c", thread.created_at) %>
|
||||
on <% render("views.common.timestamp", {timestamp = thread.created_at}) -%>
|
||||
</span>
|
||||
<span>
|
||||
Latest post by <a href="<%= url_for("user", {username = thread.latest_post_username}) %>"><%= thread.latest_post_username %></a>
|
||||
<a href="<%= url_for("thread", {slug = thread.slug}, {after = thread.latest_post_id}) .. "#post-" .. thread.latest_post_id %>">on <%= os.date("%c", thread.latest_post_created_at) %></a>:
|
||||
<a href="<%= url_for("thread", {slug = thread.slug}, {after = thread.latest_post_id}) .. "#post-" .. thread.latest_post_id %>">on <% render("views.common.timestamp", {timestamp = thread.latest_post_created_at}) -%></a>:
|
||||
</span>
|
||||
<span class="thread-info-post-preview">
|
||||
<%- thread.latest_post_content %>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<%= 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) %>
|
||||
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 <% render("views.common.timestamp", {timestamp = topic.latest_thread_created_at}) -%>
|
||||
</span>
|
||||
<% else %>
|
||||
<i>No threads yet.</i>
|
||||
|
@ -27,9 +27,9 @@
|
||||
<div class="post-info">
|
||||
<div><a href="<%= url_for("thread", {slug = post.thread_slug}, {after = post.id}) .. "#post-" .. post.id %>" title="Permalink"><i>
|
||||
<% if tonumber(post.edited_at) > tonumber(post.created_at) then -%>
|
||||
Edited in <%= post.thread_title %> at <%= os.date("%c", post.edited_at) %>
|
||||
Edited in <%= post.thread_title %> at <% render("views.common.timestamp", {timestamp = post.edited_at}) -%>
|
||||
<% else -%>
|
||||
Posted in <%= post.thread_title %> on <%= os.date("%c", post.created_at) %>
|
||||
Posted in <%= post.thread_title %> on <% render("views.common.timestamp", {timestamp = post.created_at}) -%>
|
||||
<% end -%>
|
||||
</i></a></div>
|
||||
</div>
|
||||
@ -48,12 +48,12 @@
|
||||
<div class="darkbg">
|
||||
<h1>Moderator controls</h2>
|
||||
<% if user:is_guest() then %>
|
||||
<p>This user is a guest. They signed up on <%= os.date("%c", user.created_at) %>.</p>
|
||||
<p>This user is a guest. They signed up on <% render("views.common.timestamp", {timestamp = user.created_at}) -%>.</p>
|
||||
<form class="modform" method="post" action="<%= url_for("confirm_user", {user_id = user.id}) %>">
|
||||
<input type="submit" value="Confirm user">
|
||||
</form>
|
||||
<% else %> <% --[[ user is not guest ]] %>
|
||||
<p>This user signed up on <%= os.date("%c", user.created_at) %> and was confirmed on <%= os.date("%c", user.confirmed_on) %>.</p>
|
||||
<p>This user signed up on <% render("views.common.timestamp", {timestamp = user.created_at}) -%> and was confirmed on <% render("views.common.timestamp", {timestamp = user.confirmed_on}) %>.</p>
|
||||
<% if user.permission < me.permission then %>
|
||||
<form class="modform" method="post" action="<%= url_for("guest_user", {user_id = user.id}) %>">
|
||||
<input class="warn" type="submit" value="Demote user to guest (soft ban)">
|
||||
|
Loading…
Reference in New Issue
Block a user