Show comments

Show comments on a story's short description, and automatically load
comments when reading a story.
This commit is contained in:
Robin Malley 2023-03-01 00:41:51 +00:00
parent 443a6331e6
commit 652e673d39
9 changed files with 108 additions and 75 deletions

View File

@ -5,7 +5,6 @@ Notably, holds a connection to the open sqlite3 database in .conn
local sql = require("lsqlite3")
local queries = require("queries")
local util = require("util")
local config = require("config")
local db = {}
@ -16,7 +15,11 @@ message on fail, and returns true on success.
]]
function db.sqlassert(r, errcode, err)
if not r then
error(string.format("%d: %s",errcode, err))
if err then
error(string.format("%d: %s",errcode, err))
elseif errcode then
error(string.format("%d: %s",errcode, db.conn:errmsg()))
end
end
return r
end

View File

@ -15,21 +15,21 @@ local stmnt_index, stmnt_author, stmnt_author_bio
local oldconfigure = configure
function configure(...)
stmnt_index = assert(db.conn:prepare(queries.select_site_index))
stmnt_index = db.sqlassert(db.conn:prepare(queries.select_site_index))
--TODO: actually let authors edit their bio
stmnt_author_bio = assert(db.conn:prepare([[
stmnt_author_bio = db.sqlassert(db.conn:prepare([[
SELECT authors.biography FROM authors WHERE authors.name = :author;
]]))
stmnt_author = assert(db.conn:prepare(queries.select_author_index))
stmnt_author = db.sqlassert(db.conn:prepare(queries.select_author_index))
return oldconfigure(...)
end
local function get_site_home(req, loggedin)
log(LOG_DEBUG,"Cache miss, rendering site index")
stmnt_index:bind_names{}
stmnt_index:bind_names{offset=0}
local latest = {}
for idr, title, iar, dater, author, hits in db.sql_rows(stmnt_index) do
table.insert(latest,{
for idr, title, iar, dater, author, hits, cmts in db.sql_rows(stmnt_index) do
local story = {
url = util.encode_id(idr),
title = title,
isanon = tonumber(iar) == 1,
@ -37,12 +37,19 @@ local function get_site_home(req, loggedin)
author = author,
tags = libtags.get(idr),
hits = hits,
})
ncomments = cmts
}
table.insert(latest,story)
end
return pages.index{
domain = config.domain,
stories = latest,
loggedin = loggedin
loggedin = loggedin,
extra_load = {
'<script src="/_js/index_scroll.js"></script>'
}
}
end
local function get_author_home(req, loggedin)
@ -71,7 +78,7 @@ local function get_author_home(req, loggedin)
stmnt_author_bio:reset()
stmnt_author:bind_names{author=subdomain}
local stories = {}
for id, title, time, hits, unlisted, hash in db.sql_rows(stmnt_author) do
for id, title, time, hits, unlisted, hash, cmts in db.sql_rows(stmnt_author) do
if unlisted == 1 and author == subdomain then
local url = util.encode_id(id) .. "?pwd=" .. util.encode_unlisted(hash)
table.insert(stories,{
@ -82,6 +89,7 @@ local function get_author_home(req, loggedin)
tags = libtags.get(id),
hits = hits,
unlisted = true,
ncomments = cmts
})
elseif unlisted == 0 then
table.insert(stories,{
@ -92,6 +100,7 @@ local function get_author_home(req, loggedin)
tags = libtags.get(id),
hits = hits,
unlisted = false,
ncomments = cmts
})
end
end

View File

@ -24,6 +24,7 @@ local function preview_post(req)
idp = "preview",
text = parsed,
tags = tags,
comments = {}
}
http_response(req,200,ret)
end

View File

@ -73,24 +73,6 @@ local function populate_ps_story(req,ps)
return true
end
--[[
Get the comments for a story
]]
local function get_comments(req,ps)
stmnt_comments:bind_names{
id = ps.storyid
}
local comments = {}
for com_author, com_isanon, com_text in db.sql_rows(stmnt_comments) do
table.insert(comments,{
author = com_author,
isanon = com_isanon == 1, --int to boolean
text = com_text
})
end
return comments
end
local function read_get(req)
--Pages settings
local ps = {
@ -130,9 +112,9 @@ local function read_get(req)
--If we need to show comments
http_request_populate_qs(req)
ps.show_comments = http_argument_get_string(req,"comments")
ps.show_comments = true
if ps.show_comments then
ps.comments = get_comments(req,ps)
ps.comments = util.get_comments(ps.storyid)
end
--If this post is unlisted, get the hash

View File

@ -2,8 +2,19 @@
local sql = require("lsqlite3")
local config = require("config")
local types = require("types")
local db = require("db")
local queries = require("queries")
local util = {}
local stmnt_comments
local oldconfigure = configure
function configure(...)
stmnt_comments = assert(db.conn:prepare(queries.select_comments))
return oldconfigure(...)
end
--see https://perishablepress.com/stop-using-unsafe-characters-in-urls/
--no underscore because we use that for our operative pages
local url_characters =
@ -147,6 +158,32 @@ function util.parse_tags(str)
return tags
end
--[[
Get the comments for a story
Comments are a table with the structure:
comment :: table {
author :: string - The author's text name
isanon :: boolean - True if the author is anon (author string will be "Anonymous")
text :: string - The text of the comment
}
]]
function util.get_comments(sid)
stmnt_comments:bind_names{
id = sid
}
local comments = {}
for com_author, com_isanon, com_text in db.sql_rows(stmnt_comments) do
table.insert(comments,{
author = com_author,
isanon = com_isanon == 1, --int to boolean
text = com_text
})
end
return comments
end
if config.debugging then
function util.checktypes(...)
local args = {...}

View File

@ -15,6 +15,8 @@
<% end %>
</td><td>
<%= story.hits %> hits
</td><td>
<%= story.ncomments %> comments
</td><td>
<ul class="row tag-list">
<% for i = 1,math.min(#story.tags, 5) do %>

View File

@ -35,7 +35,7 @@
<hr/>
<p><%= views %> Hits</p>
<p><%= views %> Hits, <%= #comments %> Comments</p>
<div class="row">
<% for _, spec in ipairs(api.get.page_reader(getfenv(1))) do %>
@ -49,46 +49,36 @@
<% end %>
</div>
<% if not show_comments then -%>
<form action="https://<%= domain %>/<%= short %>"><fieldset>
<input type="hidden" name="comments" value="1">
<% if unlisted then %>
<input type="hidden" name="pwd" value="<%= hashstr %>"/>
<% end %>
<input type="submit" value="load comments" class="button">
</fieldset></form>
<% else %>
<form action="https://<%= domain %>/<%= short %>" method="POST">
<% if unlisted then %>
<input type="hidden" name="pwd" value="<%= hashstr %>"/>
<% end %>
<textarea name="text" cols=60 rows=10 class="column"></textarea>
</div><% if iam then %>
<select id="postas" name="postas">
<option value="Anonymous">Anonymous</option>
<option value="<%= iam %>"><%= iam %></option>
</select>
<input type="submit" value="post" class="button">
<% else %>
<input type="hidden" name="postas" value="Anonymous">
<input type="submit" value="post" class="button">
<% end %>
</form>
<% if comments and #comments == 0 then %>
<p><i>No comments yet</i></p>
<% else %>
<section>
<% for _,comment in pairs(comments) do %>
<article>
<% if comment.isanon then %>
<p><b>Anonymous</b></p>
<% else %>
<p><b><%= comment.author %></b></p>
<% end %>
<p><%= comment.text %></p>
</article>
<% end %>
</section>
<form action="https://<%= domain %>/<%= short %>" method="POST">
<% if unlisted then %>
<input type="hidden" name="pwd" value="<%= hashstr %>"/>
<% end %>
<textarea name="text" cols=60 rows=10 class="column"></textarea>
</div><% if iam then %>
<select id="postas" name="postas">
<option value="Anonymous">Anonymous</option>
<option value="<%= iam %>"><%= iam %></option>
</select>
<input type="submit" value="post" class="button">
<% else %>
<input type="hidden" name="postas" value="Anonymous">
<input type="submit" value="post" class="button">
<% end %>
</form>
<% if comments and #comments == 0 then %>
<p><i>No comments yet</i></p>
<% else %>
<section>
<% for _,comment in pairs(comments) do %>
<article>
<% if comment.isanon then %>
<p><b>Anonymous</b></p>
<% else %>
<p><b><%= comment.author %></b></p>
<% end %>
<p><%= comment.text %></p>
</article>
<% end %>
</section>
<% end %>
<{system cat src/pages/parts/footer.etlua}>

View File

@ -6,13 +6,17 @@ SELECT
posts.post_time,
posts.views,
posts.unlisted,
posts.hash
posts.hash,
COUNT(comments.id)
FROM
posts,
authors
LEFT JOIN comments ON comments.postid = posts.id
WHERE
posts.isanon = 0 AND
posts.authorid = authors.id AND
authors.name = :author
GROUP BY
posts.id
ORDER BY
posts.post_time DESC

View File

@ -5,13 +5,18 @@ SELECT
posts.isanon,
posts.post_time,
authors.name,
posts.views
posts.views,
COUNT(comments.id)
FROM
posts,
authors
LEFT JOIN comments ON comments.postid = posts.id
WHERE
posts.authorid = authors.id AND
posts.unlisted = 0
GROUP BY
posts.id
ORDER BY
posts.post_time DESC
LIMIT 50;
LIMIT 50
OFFSET :offset;