Implements edit history.
This commit is contained in:
parent
8acaca298b
commit
d5f1c674c5
5 changed files with 73 additions and 9 deletions
43
forum.nim
43
forum.nim
|
|
@ -889,14 +889,14 @@ proc selectUser(userRow: seq[string], avatarSize: int=80): User =
|
|||
)
|
||||
|
||||
proc selectPost(postRow: seq[string], skippedPosts: seq[int],
|
||||
replyingTo: Option[PostLink]): Post =
|
||||
replyingTo: Option[PostLink], history: seq[PostInfo]): Post =
|
||||
return Post(
|
||||
id: postRow[0].parseInt,
|
||||
replyingTo: replyingTo,
|
||||
author: selectUser(@[postRow[5], postRow[6], postRow[7], postRow[8]]),
|
||||
likes: @[], # TODO:
|
||||
seen: false, # TODO:
|
||||
history: @[], # TODO:
|
||||
history: history,
|
||||
info: PostInfo(
|
||||
creation: postRow[2].parseInt,
|
||||
content: postRow[1].rstToHtml()
|
||||
|
|
@ -926,6 +926,20 @@ proc selectReplyingTo(replyingTo: string): Option[PostLink] =
|
|||
author: some(selectUser(@[row[3], row[4], row[5], row[6]]))
|
||||
))
|
||||
|
||||
proc selectHistory(postId: int): seq[PostInfo] =
|
||||
const historyQuery = sql"""
|
||||
select strftime('%s', creation), content from postRevision
|
||||
where original = ?
|
||||
order by creation asc;
|
||||
"""
|
||||
|
||||
result = @[]
|
||||
for row in getAllRows(db, historyQuery, $postId):
|
||||
result.add(PostInfo(
|
||||
creation: row[0].parseInt(),
|
||||
content: row[1].rstToHtml()
|
||||
))
|
||||
|
||||
proc selectThread(threadRow: seq[string]): Thread =
|
||||
const postsQuery =
|
||||
sql"""select count(*), strftime('%s', creation) from post
|
||||
|
|
@ -1032,7 +1046,15 @@ proc updatePost(c: TForumData, postId: int, content: string,
|
|||
raise newForumError("Message needs to be valid RST", @["msg"])
|
||||
|
||||
# Update post.
|
||||
exec(db, crud(crUpdate, "post", "content"), content, $postId)
|
||||
# - We create a new postRevision entry for our edit.
|
||||
exec(
|
||||
db,
|
||||
crud(crCreate, "postRevision", "content", "original"),
|
||||
content,
|
||||
$postId
|
||||
)
|
||||
# - We set the FTS to the latest content as searching for past edits is not
|
||||
# supported.
|
||||
exec(db, crud(crUpdate, "post_fts", "content"), content, $postId)
|
||||
# Check if post is the first post of the thread.
|
||||
if subject.isSome():
|
||||
|
|
@ -1234,7 +1256,8 @@ routes:
|
|||
|
||||
if addDetail:
|
||||
let replyingTo = selectReplyingTo(rows[i][4])
|
||||
let post = selectPost(rows[i], skippedPosts, replyingTo)
|
||||
let history = selectHistory(rows[i][0].parseInt())
|
||||
let post = selectPost(rows[i], skippedPosts, replyingTo, history)
|
||||
list.posts.add(post)
|
||||
skippedPosts = @[]
|
||||
else:
|
||||
|
|
@ -1261,7 +1284,8 @@ routes:
|
|||
var list: seq[Post] = @[]
|
||||
|
||||
for row in db.getAllRows(postsQuery):
|
||||
list.add(selectPost(row, @[], selectReplyingTo(row[4])))
|
||||
let history = selectHistory(row[0].parseInt())
|
||||
list.add(selectPost(row, @[], selectReplyingTo(row[4]), history))
|
||||
|
||||
resp $(%list), "application/json"
|
||||
|
||||
|
|
@ -1271,10 +1295,15 @@ routes:
|
|||
cond postId != -1
|
||||
|
||||
let postQuery = sql"""
|
||||
select content from post where id = ?;
|
||||
select content from (
|
||||
select content, creation from post where id = ?
|
||||
union
|
||||
select content, creation from postRevision where original = ?
|
||||
)
|
||||
order by creation desc limit 1;
|
||||
"""
|
||||
|
||||
let content = getValue(db, postQuery, postId)
|
||||
let content = getValue(db, postQuery, postId, postId)
|
||||
if content.len == 0:
|
||||
resp Http404, "Post not found"
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ when defined(js):
|
|||
(s: int, r: kstring) => onEditPost(s, r, state))
|
||||
|
||||
proc render*(state: EditBox, post: Post): VNode =
|
||||
if state.status != Http200:
|
||||
return renderError("Couldn't retrieve raw post")
|
||||
|
||||
if state.rawContent.isNone() or state.post.id != post.id:
|
||||
state.post = post
|
||||
state.rawContent = none[kstring]()
|
||||
|
|
|
|||
|
|
@ -317,6 +317,19 @@ $views-color: #545d70;
|
|||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.post-history {
|
||||
display: inline-block;
|
||||
margin-right: $control-padding-x;
|
||||
|
||||
i {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.edit-count {
|
||||
margin-right: $control-padding-x-sm/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ type
|
|||
postId*: int
|
||||
author*: Option[User] ## Only used for `replyingTo`.
|
||||
|
||||
proc lastEdit*(post: Post): PostInfo =
|
||||
post.history[^1]
|
||||
|
||||
proc isModerated*(post: Post): bool =
|
||||
## Determines whether the specified thread is under moderation.
|
||||
post.author.rank <= Moderated
|
||||
|
|
|
|||
|
|
@ -119,7 +119,10 @@ when defined(js):
|
|||
let list = state.list.get()
|
||||
for i in 0 ..< list.posts.len:
|
||||
if list.posts[i].id == id:
|
||||
list.posts[i].info.content = content
|
||||
list.posts[i].history.add(PostInfo(
|
||||
creation: getTime().toUnix(),
|
||||
content: content
|
||||
))
|
||||
break
|
||||
|
||||
proc onReplyClick(e: Event, n: VNode, p: Option[Post]) =
|
||||
|
|
@ -219,6 +222,14 @@ when defined(js):
|
|||
a(href=renderPostUrl(replyingTo)):
|
||||
italic(class="fas fa-reply")
|
||||
renderUserMention(replyingTo.author.get())
|
||||
if post.history.len > 0:
|
||||
let title = post.lastEdit.creation.fromUnix().local.
|
||||
format("'Last modified' MMM d, yyyy HH:mm")
|
||||
tdiv(class="post-history", title=title):
|
||||
span(class="edit-count"):
|
||||
text $post.history.len
|
||||
italic(class="fas fa-pencil-alt")
|
||||
|
||||
let title = post.info.creation.fromUnix().local.
|
||||
format("MMM d, yyyy HH:mm")
|
||||
a(href=renderPostUrl(post, thread), title=title):
|
||||
|
|
@ -227,7 +238,12 @@ when defined(js):
|
|||
if state.editing.isSome() and state.editing.get() == post:
|
||||
render(state.editBox, postCopy)
|
||||
else:
|
||||
verbatim(post.info.content)
|
||||
let content =
|
||||
if post.history.len > 0:
|
||||
post.lastEdit.content
|
||||
else:
|
||||
post.info.content
|
||||
verbatim(content)
|
||||
|
||||
genPostButtons(postCopy, currentUser)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue