Compare commits
No commits in common. "2eddb70d632a59f92f5e3f51746d1304d5ef8ec0" and "00c56f1417730853f1573c39be3edf319246d9cc" have entirely different histories.
2eddb70d63
...
00c56f1417
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,5 +3,5 @@ nginx.conf.compiled
|
|||||||
db.*.sqlite
|
db.*.sqlite
|
||||||
.vscode/
|
.vscode/
|
||||||
.local/
|
.local/
|
||||||
static/avatars/
|
static/
|
||||||
secrets.lua
|
secrets.lua
|
||||||
|
4
app.lua
4
app.lua
@ -25,8 +25,8 @@ app:include("apps.users", {path = "/user"})
|
|||||||
app:include("apps.topics", {path = "/topics"})
|
app:include("apps.topics", {path = "/topics"})
|
||||||
app:include("apps.threads", {path = "/threads"})
|
app:include("apps.threads", {path = "/threads"})
|
||||||
|
|
||||||
app:get("/", function(self)
|
app:get("/", function()
|
||||||
return {redirect_to = self:url_for("all_topics")}
|
return "Welcome to Lapis " .. require("lapis.version")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@ -9,8 +9,6 @@ local Topics = models.Topics
|
|||||||
local Threads = models.Threads
|
local Threads = models.Threads
|
||||||
local Posts = models.Posts
|
local Posts = models.Posts
|
||||||
|
|
||||||
local POSTS_PER_PAGE = 10
|
|
||||||
|
|
||||||
app:get("thread_create", "/create", function(self)
|
app:get("thread_create", "/create", function(self)
|
||||||
local user = util.get_logged_in_user(self)
|
local user = util.get_logged_in_user(self)
|
||||||
if not user then
|
if not user then
|
||||||
@ -22,8 +20,6 @@ app:get("thread_create", "/create", function(self)
|
|||||||
return "how did you get here?"
|
return "how did you get here?"
|
||||||
end
|
end
|
||||||
self.all_topics = all_topics
|
self.all_topics = all_topics
|
||||||
self.page_title = "creating thread"
|
|
||||||
self.me = user
|
|
||||||
return {render = "threads.create"}
|
return {render = "threads.create"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -61,6 +57,7 @@ app:post("thread_create", "/create", function(self)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
app:get("thread", "/:slug", function(self)
|
app:get("thread", "/:slug", function(self)
|
||||||
|
local posts_per_page = 10
|
||||||
local thread = Threads:find({
|
local thread = Threads:find({
|
||||||
slug = self.params.slug
|
slug = self.params.slug
|
||||||
})
|
})
|
||||||
@ -68,26 +65,14 @@ app:get("thread", "/:slug", function(self)
|
|||||||
return {status = 404}
|
return {status = 404}
|
||||||
end
|
end
|
||||||
self.thread = thread
|
self.thread = thread
|
||||||
|
|
||||||
if self.params.after then
|
|
||||||
local after_id = tonumber(self.params.after)
|
|
||||||
local post_position = Posts:count(db.clause({
|
|
||||||
thread_id = thread.id,
|
|
||||||
{"id <= ?", after_id},
|
|
||||||
}))
|
|
||||||
self.page = math.floor((post_position - 1) / POSTS_PER_PAGE) + 1
|
|
||||||
else
|
|
||||||
self.page = tonumber(self.params.page) or 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local post_count = Posts:count(db.clause({
|
local post_count = Posts:count(db.clause({
|
||||||
thread_id = thread.id
|
thread_id = thread.id
|
||||||
}))
|
}))
|
||||||
self.pages = math.ceil(post_count / POSTS_PER_PAGE)
|
self.pages = math.ceil(post_count / posts_per_page)
|
||||||
-- self.page = math.max(1, math.min(self.page, self.pages))
|
self.page = tonumber(self.params.page) or 1
|
||||||
local posts = db.query([[
|
local posts = db.query([[
|
||||||
SELECT
|
SELECT
|
||||||
posts.id, posts.created_at, post_history.content, post_history.edited_at, users.username, users.status, avatars.file_path AS avatar_path
|
posts.id, post_history.content, users.username, avatars.file_path AS avatar_path
|
||||||
FROM
|
FROM
|
||||||
posts
|
posts
|
||||||
JOIN
|
JOIN
|
||||||
@ -101,13 +86,10 @@ app:get("thread", "/:slug", function(self)
|
|||||||
ORDER BY
|
ORDER BY
|
||||||
posts.created_at ASC
|
posts.created_at ASC
|
||||||
LIMIT ? OFFSET ?
|
LIMIT ? OFFSET ?
|
||||||
]], thread.id, POSTS_PER_PAGE, (self.page - 1) * POSTS_PER_PAGE)
|
]], thread.id, posts_per_page, (self.page - 1) * posts_per_page)
|
||||||
self.topic = Topics:find(thread.topic_id)
|
self.topic = Topics:find(thread.topic_id)
|
||||||
self.me = util.get_logged_in_user_or_transient(self)
|
self.user = util.get_logged_in_user_or_transient(self)
|
||||||
self.posts = posts
|
self.posts = posts
|
||||||
|
|
||||||
self.page_title = thread.title
|
|
||||||
|
|
||||||
return {render = "threads.thread"}
|
return {render = "threads.thread"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -133,15 +115,11 @@ app:post("thread", "/:slug", function(self)
|
|||||||
|
|
||||||
local post_content = self.params.post_content
|
local post_content = self.params.post_content
|
||||||
local post = util.create_post(thread.id, user.id, post_content)
|
local post = util.create_post(thread.id, user.id, post_content)
|
||||||
local post_count = Posts:count(db.clause({
|
|
||||||
thread_id = thread.id
|
|
||||||
}))
|
|
||||||
local last_page = math.ceil(post_count / POSTS_PER_PAGE)
|
|
||||||
if not post then
|
if not post then
|
||||||
return {redirect_to = self:url_for("thread", {slug = thread.slug}, {page = last_page}) .. "#latest-post"}
|
return {redirect_to = self:url_for("thread", {slug = thread.slug})}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {redirect_to = self:url_for("thread", {slug = thread.slug}, {page = last_page}) .. "#latest-post"}
|
return {redirect_to = self:url_for("thread", {slug = thread.slug})}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@ -21,7 +21,7 @@ local ThreadCreateError = {
|
|||||||
|
|
||||||
app:get("all_topics", "", function(self)
|
app:get("all_topics", "", function(self)
|
||||||
self.topic_list = db.query("select * from topics limit 25;")
|
self.topic_list = db.query("select * from topics limit 25;")
|
||||||
self.me = util.get_logged_in_user_or_transient(self)
|
self.user = util.get_logged_in_user(self) or util.TransientUser
|
||||||
return {render = "topics.topics"}
|
return {render = "topics.topics"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -31,9 +31,6 @@ app:get("topic_create", "/create", function(self)
|
|||||||
return {status = 403}
|
return {status = 403}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.page_title = "creating topic"
|
|
||||||
self.me = user
|
|
||||||
|
|
||||||
return {render = "topics.create"}
|
return {render = "topics.create"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -68,7 +65,7 @@ app:get("topic", "/:slug", function(self)
|
|||||||
self.threads_list = db.query("SELECT * FROM threads WHERE topic_id = ? ORDER BY is_stickied DESC, created_at DESC", topic.id)
|
self.threads_list = db.query("SELECT * FROM threads WHERE topic_id = ? ORDER BY is_stickied DESC, created_at DESC", topic.id)
|
||||||
local user = util.get_logged_in_user_or_transient(self)
|
local user = util.get_logged_in_user_or_transient(self)
|
||||||
print(topic.is_locked, type(topic.is_locked))
|
print(topic.is_locked, type(topic.is_locked))
|
||||||
self.me = user
|
self.user = user
|
||||||
self.ThreadCreateError = ThreadCreateError
|
self.ThreadCreateError = ThreadCreateError
|
||||||
self.thread_create_error = ThreadCreateError.OK
|
self.thread_create_error = ThreadCreateError.OK
|
||||||
if user:is_logged_in_guest() then
|
if user:is_logged_in_guest() then
|
||||||
@ -79,8 +76,6 @@ app:get("topic", "/:slug", function(self)
|
|||||||
self.thread_create_error = ThreadCreateError.TOPIC_LOCKED
|
self.thread_create_error = ThreadCreateError.TOPIC_LOCKED
|
||||||
end
|
end
|
||||||
|
|
||||||
self.page_title = "all threads in " .. topic.name
|
|
||||||
|
|
||||||
return {render = "topics.topic"}
|
return {render = "topics.topic"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -96,9 +91,6 @@ app:get("topic_edit", "/:slug/edit", function(self)
|
|||||||
return {redirect_to = self:url_for("all_topics")}
|
return {redirect_to = self:url_for("all_topics")}
|
||||||
end
|
end
|
||||||
self.topic = topic
|
self.topic = topic
|
||||||
self.me = user
|
|
||||||
self.page_title = "editing topic " .. topic.name
|
|
||||||
|
|
||||||
return {render = "topics.edit"}
|
return {render = "topics.edit"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ app:get("user", "/:username", function(self)
|
|||||||
self.session.flash = {}
|
self.session.flash = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local me = util.get_logged_in_user_or_transient(self)
|
-- local me = validate_session(self.session.session_key) or TransientUser
|
||||||
|
local me = util.get_logged_in_user(self) or util.TransientUser
|
||||||
self.user = user
|
self.user = user
|
||||||
self.me = me
|
self.me = me
|
||||||
|
|
||||||
@ -82,26 +83,6 @@ app:get("user", "/:username", function(self)
|
|||||||
return {status = 404}
|
return {status = 404}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.latest_posts = db.query([[
|
|
||||||
SELECT
|
|
||||||
posts.id, posts.created_at, post_history.content, post_history.edited_at, threads.title AS thread_title, topics.name as topic_name, threads.slug as thread_slug
|
|
||||||
FROM
|
|
||||||
posts
|
|
||||||
JOIN
|
|
||||||
post_history ON posts.current_revision_id = post_history.id
|
|
||||||
JOIN
|
|
||||||
threads ON posts.thread_id = threads.id
|
|
||||||
JOIN
|
|
||||||
topics ON threads.topic_id = topics.id
|
|
||||||
WHERE
|
|
||||||
posts.user_id = ?
|
|
||||||
ORDER BY posts.created_at DESC
|
|
||||||
LIMIT 10
|
|
||||||
]], user.id)
|
|
||||||
|
|
||||||
self.page_title = user.username .. "'s profile"
|
|
||||||
|
|
||||||
return {render = "user.user"}
|
return {render = "user.user"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -147,9 +128,7 @@ app:get("user_delete_confirm", "/:username/delete_confirm", function(self)
|
|||||||
self.err = self.session.flash.error
|
self.err = self.session.flash.error
|
||||||
self.session.flash = {}
|
self.session.flash = {}
|
||||||
end
|
end
|
||||||
self.me = target_user
|
self.user = target_user
|
||||||
self.page_title = "confirm deletion"
|
|
||||||
|
|
||||||
return {render = "user.delete_confirm"}
|
return {render = "user.delete_confirm"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -227,9 +206,7 @@ app:get("user_settings", "/:username/settings", function(self)
|
|||||||
self.flash_msg = flash.error
|
self.flash_msg = flash.error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.me = target_user
|
self.user = target_user
|
||||||
self.page_title = "settings"
|
|
||||||
|
|
||||||
return {render = "user.settings"}
|
return {render = "user.settings"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -268,9 +245,6 @@ app:get("user_login", "/login", function(self)
|
|||||||
self.err = self.session.flash.error
|
self.err = self.session.flash.error
|
||||||
self.session.flash = {}
|
self.session.flash = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.page_title = "log in"
|
|
||||||
|
|
||||||
return {render = "user.login"}
|
return {render = "user.login"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -313,9 +287,6 @@ app:get("user_signup", "/signup", function(self)
|
|||||||
self.err = self.session.flash.error
|
self.err = self.session.flash.error
|
||||||
self.session.flash = {}
|
self.session.flash = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.page_title = "sign up"
|
|
||||||
|
|
||||||
return {render = "user.signup"}
|
return {render = "user.signup"}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
local babycode = {}
|
local babycode = {}
|
||||||
|
|
||||||
|
local _escape_html = function(text)
|
||||||
|
return text:gsub("[&<>\"']", {
|
||||||
|
["&"] = "&",
|
||||||
|
["<"] = "<",
|
||||||
|
[">"] = ">",
|
||||||
|
['"'] = """,
|
||||||
|
["'"] = "'"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
---renders babycode to html
|
---renders babycode to html
|
||||||
---@param s string input babycode
|
---@param s string input babycode
|
||||||
---@param escape_html fun(s: string): string function that escapes html
|
---@param escape_html fun(s: string): string function that escapes html
|
||||||
@ -11,8 +21,7 @@ function babycode.to_html(s, escape_html)
|
|||||||
local code_count = 0
|
local code_count = 0
|
||||||
local text = s:gsub("%[code%](.-)%[/code%]", function(code)
|
local text = s:gsub("%[code%](.-)%[/code%]", function(code)
|
||||||
code_count = code_count + 1
|
code_count = code_count + 1
|
||||||
-- strip leading and trailing newlines, preserve others
|
code_blocks[code_count] = code
|
||||||
code_blocks[code_count] = code:gsub("^%s*(.-)%s*$", "%1")
|
|
||||||
return "\1CODE:"..code_count.."\1"
|
return "\1CODE:"..code_count.."\1"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -39,14 +48,14 @@ function babycode.to_html(s, escape_html)
|
|||||||
return url
|
return url
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- normalize newlines, replace them with <br>
|
|
||||||
text = text:gsub("\r?\n\r?\n+", "<br>"):gsub("\r?\n", "<br>")
|
|
||||||
|
|
||||||
-- replace code block placeholders back with their original contents
|
-- replace code block placeholders back with their original contents
|
||||||
text = text:gsub("\1CODE:(%d+)\1", function(n)
|
text = text:gsub("\1CODE:(%d+)\1", function(n)
|
||||||
return "<pre><code>"..code_blocks[tonumber(n)].."</code></pre>"
|
return "<pre><code>"..code_blocks[tonumber(n)].."</code></pre>"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- finally, normalize newlines replace them with <br>
|
||||||
|
text = text:gsub("\r?\n\r?\n+", "<br>"):gsub("\r?\n", "<br>")
|
||||||
|
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,10 +28,6 @@ function Users_mt:is_default_avatar()
|
|||||||
return self.avatar_id == nil
|
return self.avatar_id == nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function Users_mt:is_logged_in()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local ret = {
|
local ret = {
|
||||||
Users = Users,
|
Users = Users,
|
||||||
Topics = Model:extend("topics"),
|
Topics = Model:extend("topics"),
|
||||||
|
223
sass/style.scss
223
sass/style.scss
@ -1,223 +0,0 @@
|
|||||||
/* src: */
|
|
||||||
|
|
||||||
@use "sass:color";
|
|
||||||
|
|
||||||
$accent_color: #c1ceb1;
|
|
||||||
|
|
||||||
$dark_bg: color.scale($accent_color, $lightness: -25%, $saturation: -97%);
|
|
||||||
$dark2: color.scale($accent_color, $lightness: -30%, $saturation: -60%);
|
|
||||||
|
|
||||||
$light: color.scale($accent_color, $lightness: 40%, $saturation: -60%);
|
|
||||||
|
|
||||||
$main_bg: color.scale($accent_color, $lightness: -10%, $saturation: -40%);
|
|
||||||
$button_color: color.adjust($accent_color, $hue: 90);
|
|
||||||
|
|
||||||
%button-base {
|
|
||||||
cursor: default;
|
|
||||||
color: black;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid black;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 5px 20px;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin button($color) {
|
|
||||||
@extend %button-base;
|
|
||||||
background-color: $color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: color.scale($color, $lightness: 20%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: color.scale($color, $lightness: -10%, $saturation: -70%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin navbar($color) {
|
|
||||||
padding: 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: end;
|
|
||||||
background-color: $color;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
margin: 20px;
|
|
||||||
background-color: $main_bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.big {
|
|
||||||
font-size: 1.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#topnav {
|
|
||||||
@include navbar($accent_color);
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bottomnav {
|
|
||||||
@include navbar($dark_bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.darkbg {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
padding-left: 10px;
|
|
||||||
background-color: $dark_bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-actions {
|
|
||||||
display: flex;
|
|
||||||
column-gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-title {
|
|
||||||
display: inline;
|
|
||||||
padding-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thread-title {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 200px 1fr;
|
|
||||||
grid-template-rows: 1fr;
|
|
||||||
gap: 0;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas:
|
|
||||||
"usercard post-content-container";
|
|
||||||
border: 2px outset $dark2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.usercard {
|
|
||||||
grid-area: usercard;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px 10px;
|
|
||||||
border: 4px outset $light;
|
|
||||||
background-color: $dark_bg;
|
|
||||||
border-right: solid 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-content-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 0.2fr 2.5fr;
|
|
||||||
gap: 0px 0px;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas:
|
|
||||||
"post-info"
|
|
||||||
"post-content";
|
|
||||||
grid-area: post-content-container;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-info {
|
|
||||||
grid-area: post-info;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 5px 20px;
|
|
||||||
align-items: center;
|
|
||||||
border-top: 1px solid black;
|
|
||||||
border-bottom: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-content {
|
|
||||||
grid-area: post-content;
|
|
||||||
padding: 5px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-posts {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 200px 1fr;
|
|
||||||
grid-template-rows: 1fr;
|
|
||||||
gap: 0;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas:
|
|
||||||
"user-page-usercard user-posts-container";
|
|
||||||
border: 2px outset $dark2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-page-usercard {
|
|
||||||
grid-area: user-page-usercard;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px 10px;
|
|
||||||
border: 4px outset $light;
|
|
||||||
background-color: $dark_bg;
|
|
||||||
border-right: solid 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-posts-container {
|
|
||||||
grid-area: user-posts-container;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 0.2fr 2.5fr;
|
|
||||||
gap: 0px 0px;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas:
|
|
||||||
"post-info"
|
|
||||||
"post-content";
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 90%;
|
|
||||||
height: 90%;
|
|
||||||
object-fit: contain;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username-link {
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-status {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
button, input[type="submit"], .linkbutton {
|
|
||||||
@include button($button_color);
|
|
||||||
|
|
||||||
&.critical {
|
|
||||||
color: white;
|
|
||||||
@include button(red);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.warn {
|
|
||||||
@include button(#fbfb8d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// not sure why this one has to be separate, but if it's included in the rule above everything breaks
|
|
||||||
input[type="file"]::file-selector-button {
|
|
||||||
@include button($button_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagebutton {
|
|
||||||
@include button($button_color);
|
|
||||||
padding: 5px 5px;
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.currentpage {
|
|
||||||
@extend %button-base;
|
|
||||||
border: none;
|
|
||||||
padding: 5px 5px;
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modform {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
216
static/style.css
216
static/style.css
@ -1,216 +0,0 @@
|
|||||||
/* src: */
|
|
||||||
.currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
|
|
||||||
cursor: default;
|
|
||||||
color: black;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid black;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 5px 20px;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
margin: 20px;
|
|
||||||
background-color: rgb(173.5214173228, 183.6737007874, 161.0262992126);
|
|
||||||
}
|
|
||||||
|
|
||||||
.big {
|
|
||||||
font-size: 1.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#topnav {
|
|
||||||
padding: 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: end;
|
|
||||||
background-color: #c1ceb1;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bottomnav {
|
|
||||||
padding: 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: end;
|
|
||||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
|
||||||
}
|
|
||||||
|
|
||||||
.darkbg {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
padding-left: 10px;
|
|
||||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-actions {
|
|
||||||
display: flex;
|
|
||||||
column-gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-title {
|
|
||||||
display: inline;
|
|
||||||
padding-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thread-title {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 200px 1fr;
|
|
||||||
grid-template-rows: 1fr;
|
|
||||||
gap: 0;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas: "usercard post-content-container";
|
|
||||||
border: 2px outset rgb(135.1928346457, 145.0974015748, 123.0025984252);
|
|
||||||
}
|
|
||||||
|
|
||||||
.usercard {
|
|
||||||
grid-area: usercard;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px 10px;
|
|
||||||
border: 4px outset rgb(217.26, 220.38, 213.42);
|
|
||||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
|
||||||
border-right: solid 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-content-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 0.2fr 2.5fr;
|
|
||||||
gap: 0px 0px;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas: "post-info" "post-content";
|
|
||||||
grid-area: post-content-container;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-info {
|
|
||||||
grid-area: post-info;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 5px 20px;
|
|
||||||
align-items: center;
|
|
||||||
border-top: 1px solid black;
|
|
||||||
border-bottom: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-content {
|
|
||||||
grid-area: post-content;
|
|
||||||
padding: 5px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-posts {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 200px 1fr;
|
|
||||||
grid-template-rows: 1fr;
|
|
||||||
gap: 0;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas: "user-page-usercard user-posts-container";
|
|
||||||
border: 2px outset rgb(135.1928346457, 145.0974015748, 123.0025984252);
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-page-usercard {
|
|
||||||
grid-area: user-page-usercard;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px 10px;
|
|
||||||
border: 4px outset rgb(217.26, 220.38, 213.42);
|
|
||||||
background-color: rgb(143.7039271654, 144.3879625984, 142.8620374016);
|
|
||||||
border-right: solid 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-posts-container {
|
|
||||||
grid-area: user-posts-container;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: 0.2fr 2.5fr;
|
|
||||||
gap: 0px 0px;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-template-areas: "post-info" "post-content";
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
width: 90%;
|
|
||||||
height: 90%;
|
|
||||||
object-fit: contain;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username-link {
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-status {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
button, input[type=submit], .linkbutton {
|
|
||||||
background-color: rgb(177, 206, 204.5);
|
|
||||||
}
|
|
||||||
button:hover, input[type=submit]:hover, .linkbutton:hover {
|
|
||||||
background-color: rgb(192.6, 215.8, 214.6);
|
|
||||||
}
|
|
||||||
button:active, input[type=submit]:active, .linkbutton:active {
|
|
||||||
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
|
|
||||||
}
|
|
||||||
button.critical, input[type=submit].critical, .linkbutton.critical {
|
|
||||||
color: white;
|
|
||||||
background-color: red;
|
|
||||||
}
|
|
||||||
button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:hover {
|
|
||||||
background-color: #ff3333;
|
|
||||||
}
|
|
||||||
button.critical:active, input[type=submit].critical:active, .linkbutton.critical:active {
|
|
||||||
background-color: rgb(149.175, 80.325, 80.325);
|
|
||||||
}
|
|
||||||
button.warn, input[type=submit].warn, .linkbutton.warn {
|
|
||||||
background-color: #fbfb8d;
|
|
||||||
}
|
|
||||||
button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
|
|
||||||
background-color: rgb(251.8, 251.8, 163.8);
|
|
||||||
}
|
|
||||||
button.warn:active, input[type=submit].warn:active, .linkbutton.warn:active {
|
|
||||||
background-color: rgb(198.3813559322, 198.3813559322, 154.4186440678);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=file]::file-selector-button {
|
|
||||||
background-color: rgb(177, 206, 204.5);
|
|
||||||
}
|
|
||||||
input[type=file]::file-selector-button:hover {
|
|
||||||
background-color: rgb(192.6, 215.8, 214.6);
|
|
||||||
}
|
|
||||||
input[type=file]::file-selector-button:active {
|
|
||||||
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagebutton {
|
|
||||||
background-color: rgb(177, 206, 204.5);
|
|
||||||
padding: 5px 5px;
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.pagebutton:hover {
|
|
||||||
background-color: rgb(192.6, 215.8, 214.6);
|
|
||||||
}
|
|
||||||
.pagebutton:active {
|
|
||||||
background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
|
|
||||||
}
|
|
||||||
|
|
||||||
.currentpage {
|
|
||||||
border: none;
|
|
||||||
padding: 5px 5px;
|
|
||||||
margin: 0;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modform {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
3
util.lua
3
util.lua
@ -26,9 +26,6 @@ util.TransientUser = {
|
|||||||
is_logged_in_guest = function (self)
|
is_logged_in_guest = function (self)
|
||||||
return false
|
return false
|
||||||
end,
|
end,
|
||||||
is_logged_in = function (self)
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
username = "Deleted User",
|
username = "Deleted User",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<% if page_title then %>
|
|
||||||
<title>Porom - <%= page_title %></title>
|
|
||||||
<% else %>
|
|
||||||
<title>Porom</title>
|
<title>Porom</title>
|
||||||
<% end %>
|
|
||||||
<% math.randomseed(os.time()) %>
|
|
||||||
<link rel="stylesheet" href="<%= "/static/style.css?" .. math.random(1, 100) %>">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<% content_for("inner") %>
|
<% content_for("inner") %>
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
<% local left_start = math.max(1, current_page - 5) %>
|
|
||||||
<% local right_end = math.min(page_count, current_page + 5) %>
|
|
||||||
|
|
||||||
<div class="pager">
|
|
||||||
<span>Page:</span>
|
|
||||||
<% if current_page > 5 then %>
|
|
||||||
<a href="?page=1" class="pagebutton">1</a>
|
|
||||||
<% if left_start > 2 then %>
|
|
||||||
<span class="currentpage">…</span>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<% for i = left_start, current_page - 1 do%>
|
|
||||||
<a href="?page=<%= i %>" class="pagebutton"><%= i %></a>
|
|
||||||
<% end %>
|
|
||||||
<% if page_count > 0 then %>
|
|
||||||
<span class="currentpage"><%= current_page %></span>
|
|
||||||
<% end %>
|
|
||||||
<% for i = current_page + 1, right_end do %>
|
|
||||||
<a href="?page=<%= i %>" class="pagebutton"><%= i %></a>
|
|
||||||
<% end %>
|
|
||||||
<% if right_end < page_count then %>
|
|
||||||
<% if right_end < page_count - 1 then %>
|
|
||||||
<span class="currentpage">…</span>
|
|
||||||
<% end %>
|
|
||||||
<a href="?page=<%= page_count %>" class="pagebutton"><%= page_count %></a>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
@ -1,13 +0,0 @@
|
|||||||
<nav id="topnav">
|
|
||||||
<span>
|
|
||||||
<h1 class="site-title">Porom</h1>
|
|
||||||
<a href="<%= url_for("all_topics") %>">All topics</a>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<% if me:is_logged_in() then -%>
|
|
||||||
Welcome, <a href="<%= url_for("user", {username = me.username}) %>"><%= me.username %></a>
|
|
||||||
<% else -%>
|
|
||||||
Welcome, guest. Please <a href="<%= url_for("user_signup") %>">sign up</a> or <a href="<%= url_for("user_login") %>">log in</a>
|
|
||||||
<% end -%>
|
|
||||||
</span>
|
|
||||||
</nav>
|
|
@ -1,26 +0,0 @@
|
|||||||
<div class="post" id="post-<%= post.id %>">
|
|
||||||
<div class="usercard">
|
|
||||||
<a href="<%= url_for("user", {username = post.username}) %>" style="display: contents;">
|
|
||||||
<img src="<%= post.avatar_path or "/avatars/default.webp" %>" class="avatar">
|
|
||||||
</a>
|
|
||||||
<a href="<%= url_for("user", {username = post.username}) %>" class="username-link"><%= post.username %></a>
|
|
||||||
<% if post.status ~= "" then %>
|
|
||||||
<em class="user-status"><%= post.status %></em>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<div class="post-content-container"<%= is_latest and 'id=latest-post' or "" %>>
|
|
||||||
<div class="post-info">
|
|
||||||
<div><a href="<%= "#post-" .. post.id %>" title="Permalink"><i>
|
|
||||||
<% if tonumber(post.edited_at) > tonumber(post.created_at) then -%>
|
|
||||||
Edited at <%= os.date("%c", post.edited_at) %>
|
|
||||||
<% else -%>
|
|
||||||
Posted at <%= os.date("%c", post.created_at) %>
|
|
||||||
<% end -%>
|
|
||||||
</i></a></div>
|
|
||||||
<div><button>Reply</button></div>
|
|
||||||
</div>
|
|
||||||
<div class="post-content">
|
|
||||||
<%- post.content %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,22 +1,27 @@
|
|||||||
<% render("views.common.topnav") -%>
|
<h1><%= thread.title %></h1>
|
||||||
<main>
|
<p>Posted under <a href="<%= url_for("topic", {slug = topic.slug}) %>"><%= topic.name %></a>
|
||||||
<nav class="darkbg">
|
<% for _, post in ipairs(posts) do %>
|
||||||
<h1 class="thread-title"><%= thread.title %></h1>
|
<div id="post-<%= post.id %>">
|
||||||
<span>Posted in <a href="<%= url_for("topic", {slug = topic.slug}) %>"><%= topic.name %></a></span>
|
<img src="<%= post.avatar_path or "/avatars/default.webp" %>"><br>
|
||||||
</nav>
|
<a href="<%= url_for("user", {username = post.username}) %>"><%= post.username %></a>
|
||||||
<% for i, post in ipairs(posts) do %>
|
<div><p><%- post.content %></p></div>
|
||||||
<% render("views.threads.post", {post = post, is_latest = i == #posts}) %>
|
<a href="#post-<%= post.id %>">permalink</a>
|
||||||
<% end %>
|
</div>
|
||||||
</main>
|
<% end %>
|
||||||
|
|
||||||
<nav id="bottomnav">
|
<% if not user:is_guest() then %>
|
||||||
<% render("views.common.pagination", {page_count = pages, current_page = page}) %>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<% if not me:is_guest() then %>
|
|
||||||
<h1>Respond to "<%= thread.title %>"</h1>
|
<h1>Respond to "<%= thread.title %>"</h1>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<textarea id="post_content" name="post_content" placeholder="Response body" required></textarea><br>
|
<textarea id="post_content" name="post_content" placeholder="Response body" required></textarea><br>
|
||||||
<input type="submit" value="Reply">
|
<input type="submit" value="Reply">
|
||||||
</form>
|
</form>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<span>
|
||||||
|
<% for i = 1, math.max(pages, 1) do %>
|
||||||
|
<% if i == page then %>
|
||||||
|
<%= tostring(i)%>
|
||||||
|
<% else %>
|
||||||
|
<a href="?page=<%= i %>"><%= tostring(i)%></a>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<p>This topic is locked.</p>
|
<p>This topic is locked.</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if me:is_mod() then %>
|
<% if user:is_mod() then %>
|
||||||
<br>
|
<br>
|
||||||
<a href="<%= url_for("topic_edit", {slug = topic.slug}) %>">Edit topic</a>
|
<a href="<%= url_for("topic_edit", {slug = topic.slug}) %>">Edit topic</a>
|
||||||
<form method="post" action="<%= url_for("topic_edit", {slug = topic.slug}) %>">
|
<form method="post" action="<%= url_for("topic_edit", {slug = topic.slug}) %>">
|
||||||
|
@ -11,6 +11,6 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
<% if me:is_mod() then %>
|
<% if user:is_mod() then %>
|
||||||
<a href="<%= url_for("topic_create") %>">Create new topic</a>
|
<a href="<%= url_for("topic_create") %>">Create new topic</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<h1>Are you sure you want to delete your account, <%= me.username %>?</h1>
|
<h1>Are you sure you want to delete your account, <%= user.username %>?</h1>
|
||||||
<p>This cannot be undone. This will not delete your posts, only anonymize them.</p>
|
<p>This cannot be undone. This will not delete your posts, only anonymize them.</p>
|
||||||
<p>If you are sure, please type your password below.</p>
|
<p>If you are sure, please type your password below.</p>
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
<h2><%= err %></h2>
|
<h2><%= err %></h2>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<form method="post" action="<%= url_for("user_delete", {username = me.username}) %>">
|
<form method="post" action="<%= url_for("user_delete", {username = user.username}) %>">
|
||||||
<input type="password" name="password" id="password" autocomplete="current-password" placeholder="Password" required><br>
|
<input type="password" name="password" id="password" autocomplete="current-password" placeholder="Password" required><br>
|
||||||
<input class="critical" type="submit" value="Delete my account (NO UNDO)">
|
<input type="submit" value="Delete my account (NO UNDO)">
|
||||||
</form>
|
</form>
|
||||||
|
@ -2,19 +2,19 @@
|
|||||||
<% if flash_msg then %>
|
<% if flash_msg then %>
|
||||||
<h2><%= flash_msg %></h2>
|
<h2><%= flash_msg %></h2>
|
||||||
<% end %>
|
<% end %>
|
||||||
<form method="post" action="<%= url_for("user_set_avatar", {username = me.username}) %>" enctype="multipart/form-data">
|
<form method="post" action="<%= url_for("user_set_avatar", {username = user.username}) %>" enctype="multipart/form-data">
|
||||||
<img src="<%= avatar_url(me) %>"><br>
|
<img src="<%= avatar_url(user) %>"><br>
|
||||||
<input id="file" type="file" name="avatar" accept="image/*">
|
<input type="file" name="avatar" accept="image/*"><br>
|
||||||
<input type="submit" value="Update avatar">
|
<input type="submit" value="Update avatar">
|
||||||
<% if not me:is_default_avatar() then %>
|
<% if not user:is_default_avatar() then %>
|
||||||
<input type="submit" value="Clear avatar" formaction="<%= url_for("user_clear_avatar", {username = me.username}) %>">
|
<input type="submit" value="Clear avatar" formaction="<%= url_for("user_clear_avatar", {username = user.username}) %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
<br>
|
<br>
|
||||||
</form>
|
</form>
|
||||||
<form method="post" action="">
|
<form method="post" action="">
|
||||||
<label for="status">Status</label>
|
<label for="status">Status</label>
|
||||||
<input type="text" id="status" name="status" value="<%= me.status %>" maxlength="30"><br>
|
<input type="text" id="status" name="status" value="<%= user.status %>" maxlength="30"><br>
|
||||||
<input type="submit" value="Save status">
|
<input type="submit" value="Save">
|
||||||
</form>
|
</form>
|
||||||
<br>
|
<br>
|
||||||
<a class="linkbutton critical" href="<%= url_for("user_delete_confirm", {username = me.username}) %>">Delete account</a>
|
<a href="<%= url_for("user_delete_confirm", {username = user.username}) %>">Delete account</a>
|
||||||
|
@ -1,74 +1,41 @@
|
|||||||
<% if just_logged_in then %>
|
<% if just_logged_in then %>
|
||||||
<h1>Logged in successfully.</h1>
|
<h1>Logged in successfully.</h1>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% render("views.common.topnav") -%>
|
<img src="<%= avatar_url(user) %>">
|
||||||
<div class="darkbg">
|
<h1><%= user.username %></h1>
|
||||||
<h1 class="thread-title">Latest posts by <i><%= user.username %></i></h1>
|
<h2><%= PermissionLevelString[user.permission] %></h2>
|
||||||
<div>
|
|
||||||
User permission: <i><%= PermissionLevelString[user.permission] %></i>
|
|
||||||
</div>
|
|
||||||
<% if user_is_me then -%>
|
|
||||||
<div class="user-actions">
|
|
||||||
<a class="linkbutton" href="<%= url_for("user_settings", {username = user.username}) %>">Settings</a>
|
|
||||||
<form method="post" action="<%= url_for("user_logout", {user_id = me.id}) %>">
|
|
||||||
<input class="warn" type="submit" value="Log out">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<% --[[ duplicating code, maybe i'll refactor the post subview later to work anywhere <clown emoji>]] %>
|
|
||||||
<% for i, post in ipairs(latest_posts) do %>
|
|
||||||
<div class="user-posts">
|
|
||||||
<div class="user-page-usercard">
|
|
||||||
<img class="avatar" src="<%= avatar_url(user) %>">
|
|
||||||
<b class="big"><%= user.username %></b>
|
|
||||||
<em class="user-status"><%= user.status %></em>
|
|
||||||
</div>
|
|
||||||
<div class="user-posts-container">
|
|
||||||
<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) %>
|
|
||||||
<% else -%>
|
|
||||||
Posted in <%= post.thread_title %> at <%= os.date("%c", post.created_at) %>
|
|
||||||
<% end -%>
|
|
||||||
</i></a></div>
|
|
||||||
</div>
|
|
||||||
<div class="post-content">
|
|
||||||
<%- post.content %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if user:is_guest() and user_is_me then %>
|
<% if user:is_guest() and user_is_me then %>
|
||||||
<h2>You are a guest. A Moderator needs to approve your account before you will be able to post.</h2>
|
<h2>You are a guest. An Moderator needs to approve your account before you will be able to post.</h2>
|
||||||
|
<% end %>
|
||||||
|
<% if user_is_me then %>
|
||||||
|
<a href="<%= url_for("user_settings", {username = user.username}) %>">Settings</a>
|
||||||
|
<form method="post" action="<%= url_for("user_logout", {user_id = me.id}) %>">
|
||||||
|
<input type="submit" value="Log out">
|
||||||
|
</form>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if me:is_mod() and not user:is_system() then %>
|
<% if me:is_mod() and not user:is_system() then %>
|
||||||
<div class="darkbg">
|
|
||||||
<h1>Moderator controls</h2>
|
<h1>Moderator controls</h2>
|
||||||
<% if user:is_guest() then %>
|
<% 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 <%= os.date("%c", user.created_at) %>.</p>
|
||||||
<form class="modform" method="post" action="<%= url_for("confirm_user", {user_id = user.id}) %>">
|
<form method="post" action="<%= url_for("confirm_user", {user_id = user.id}) %>">
|
||||||
<input type="submit" value="Confirm user">
|
<input type="submit" value="Confirm user">
|
||||||
</form>
|
</form>
|
||||||
<% else %> <% --[[ user is not guest ]] %>
|
<% 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 <%= os.date("%c", user.created_at) %> and was confirmed on <%= os.date("%c", user.confirmed_on) %>.</p>
|
||||||
<% if user.permission < me.permission then %>
|
<% if user.id ~= me.id and user.permission < me.permission then %>
|
||||||
<form class="modform" method="post" action="<%= url_for("guest_user", {user_id = user.id}) %>">
|
<form method="post" action="<%= url_for("guest_user", {user_id = user.id}) %>">
|
||||||
<input class="warn" type="submit" value="Demote user to guest (soft ban)">
|
<input type="submit" value="Demote user to guest (soft ban)">
|
||||||
</form>
|
</form>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if me:is_admin() and not user:is_mod() then %>
|
<% if me:is_admin() and not user:is_mod() then %>
|
||||||
<form class="modform" method="post" action="<%= url_for("mod_user", {user_id = user.id}) %>">
|
<form method="post" action="<%= url_for("mod_user", {user_id = user.id}) %>">
|
||||||
<input class="warn" type="submit" value="Promote user to moderator">
|
<input type="submit" value="Promote user to moderator">
|
||||||
</form>
|
</form>
|
||||||
<% elseif user:is_mod() and user.permission < me.permission then %>
|
<% elseif me:is_admin() then %>
|
||||||
<form class="modform" method="post" action="<%= url_for("demod_user", {user_id = user.id}) %>">
|
<form method="post" action="<%= url_for("demod_user", {user_id = user.id}) %>">
|
||||||
<input class="critical" type="submit" value="Demote user to regular user">
|
<input type="submit" value="Demote user to regular user">
|
||||||
</form>
|
</form>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
Loading…
Reference in New Issue
Block a user