Add frontend category picker and enable categories in threadlist

This commit is contained in:
Joey Yakimowich-Payne 2018-08-06 16:22:32 +09:00
commit 7cda14e9fe
4 changed files with 113 additions and 10 deletions

View file

@ -206,6 +206,14 @@ $threads-meta-color: #545d70;
display: inline-block;
}
.square {
width: 0;
height: 0;
border: 0.3rem solid #98c766;
display: inline-block;
margin-right: 5px;
}
.load-more-separator {
text-align: center;
color: darken($label-color, 35%);
@ -711,10 +719,8 @@ hr {
#threads-list.table {
tr > th:nth-child(2), tr > td:nth-child(2) {
display: none;
}
}
.category, div.flag-button {
display: none;
}
}

View file

@ -6,6 +6,8 @@ type
description*: string
color*: string
CategoryList* = ref object
categories*: seq[Category]
when defined(js):
include karax/prelude
@ -17,12 +19,13 @@ when defined(js):
result = buildHtml():
if category.name.len >= 0:
tdiv(class="category",
title=category.description,
"data-color"="#" & category.color):
tdiv(class="triangle",
tdiv(class="square",
style=style(
(StyleAttr.borderBottom,
kstring"0.6rem solid #" & category.color)
(StyleAttr.border,
kstring"0.3rem solid #" & category.color)
))
text category.name
else:
span()
span()

View file

@ -0,0 +1,88 @@
when defined(js):
import sugar, httpcore, options, json
import dom except Event
include karax/prelude
import karax / [kajax, kdom, vstyles, vdom]
import error, replybox, threadlist, post, category
import category, karaxutils
type
CategoryPicker* = ref object of VComponent
list: Option[CategoryList]
selectedCategoryID*: int
loading: bool
status: HttpCode
proc getSelectedCategory*(state: CategoryPicker): Option[Category] =
if state.list.isSome:
return some(state.list.get().categories[state.selectedCategoryID])
return none[Category]()
proc onCategoryList(state: CategoryPicker): proc (httpStatus: int, response: kstring) =
return proc (httpStatus: int, response: kstring) =
state.loading = false
state.status = httpStatus.HttpCode
if state.status != Http200: return
let parsed = parseJson($response)
let list = parsed.to(CategoryList)
if state.list.isSome:
state.list.get().categories.add(list.categories)
else:
state.list = some(list)
if state.selectedCategoryID > state.list.get().categories.len():
state.selectedCategoryID = 0
proc loadCategories(state: CategoryPicker) =
if not state.loading:
state.loading = true
ajaxGet(makeUri("categories.json"), @[], onCategoryList(state))
proc newCategoryPicker*(): CategoryPicker =
result = CategoryPicker(
list: none[CategoryList](),
selectedCategoryID: 0,
loading: false,
status: Http200
)
proc onCategoryClick(state: CategoryPicker, category: Category): proc (ev: Event, n: VNode) =
# this is necessary to capture the right value
let cat = category
return proc (ev: Event, n: VNode) =
state.selectedCategoryID = cat.id
state.markDirty()
proc render*(state: CategoryPicker): VNode =
if state.status != Http200:
return renderError("Couldn't retrieve categories.", state.status)
if state.list.isNone:
state.loadCategories()
return buildHtml(tdiv(class="loading loading-lg"))
let list = state.list.get().categories
let selectedCategory = list[state.selectedCategoryID]
result = buildHtml():
tdiv(id="category-selection", class="input-group"):
label(class="d-inline-block form-label"):
text "Category"
tdiv(class="dropdown"):
a(class="btn btn-link dropdown-toggle", tabindex="0"):
tdiv(class="d-inline-block"):
render(selectedCategory)
text " "
italic(class="fas fa-caret-down")
ul(class="menu"):
for category in list:
li(class="menu-item"):
a(onClick=onCategoryClick(state, category)):
render(category)

View file

@ -5,8 +5,8 @@ when defined(js):
include karax/prelude
import karax / [kajax, kdom]
import error, replybox, threadlist, post
import karaxutils
import error, replybox, threadlist, post, category
import karaxutils, categorypicker
type
NewThread* = ref object
@ -14,11 +14,13 @@ when defined(js):
error: Option[PostError]
replyBox: ReplyBox
subject: kstring
categoryPicker: CategoryPicker
proc newNewThread*(): NewThread =
NewThread(
replyBox: newReplyBox(nil),
subject: ""
subject: "",
categoryPicker: newCategoryPicker()
)
proc onSubjectChange(e: Event, n: VNode, state: NewThread) =
@ -37,8 +39,11 @@ when defined(js):
let uri = makeUri("newthread")
# TODO: This is a hack, karax should support this.
let formData = newFormData()
let categoryID = state.categoryPicker.selectedCategoryID
formData.append("subject", state.subject)
formData.append("msg", state.replyBox.getText())
formData.append("categoryId", $categoryID)
ajaxPost(uri, @[], cast[cstring](formData),
(s: int, r: kstring) => onCreatePost(s, r, state))
@ -55,6 +60,7 @@ when defined(js):
if state.error.isSome():
p(class="text-error"):
text state.error.get().message
render(state.categoryPicker)
renderContent(state.replyBox, none[Thread](), none[Post]())
tdiv(class="footer"):