Add expanded version of category drop down and add it to categories page
This commit is contained in:
parent
38a21f34e6
commit
f3396777fb
5 changed files with 55 additions and 18 deletions
|
|
@ -122,6 +122,19 @@ $logo-height: $navbar-height - 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.category-description {
|
||||||
|
opacity: 0.6;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-status {
|
||||||
|
.topic-count {
|
||||||
|
margin-left: 5px;
|
||||||
|
opacity: 0.7;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,23 @@ type
|
||||||
CategoryList* = ref object
|
CategoryList* = ref object
|
||||||
categories*: seq[Category]
|
categories*: seq[Category]
|
||||||
|
|
||||||
|
const categoryDescriptionCharLimit = 250
|
||||||
|
|
||||||
proc cmpNames*(cat1: Category, cat2: Category): int =
|
proc cmpNames*(cat1: Category, cat2: Category): int =
|
||||||
cat1.name.cmp(cat2.name)
|
cat1.name.cmp(cat2.name)
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
include karax/prelude
|
include karax/prelude
|
||||||
import karax / [vstyles]
|
import karax / [vstyles]
|
||||||
|
import karaxutils
|
||||||
|
|
||||||
proc render*(category: Category): VNode =
|
proc render*(category: Category, compact=false): VNode =
|
||||||
result = buildHtml():
|
if category.name.len == 0:
|
||||||
if category.name.len >= 0:
|
return buildHtml():
|
||||||
|
span()
|
||||||
|
|
||||||
|
result = buildhtml(tdiv):
|
||||||
|
tdiv(class="category-status"):
|
||||||
tdiv(class="category",
|
tdiv(class="category",
|
||||||
title=category.description,
|
title=category.description,
|
||||||
"data-color"="#" & category.color):
|
"data-color"="#" & category.color):
|
||||||
|
|
@ -28,6 +35,11 @@ when defined(js):
|
||||||
(StyleAttr.border,
|
(StyleAttr.border,
|
||||||
kstring"0.3rem solid #" & category.color)
|
kstring"0.3rem solid #" & category.color)
|
||||||
))
|
))
|
||||||
text category.name
|
span(class="category-name"):
|
||||||
else:
|
text category.name
|
||||||
span()
|
if not compact:
|
||||||
|
span(class="topic-count"):
|
||||||
|
text "× " & $category.numTopics
|
||||||
|
if not compact:
|
||||||
|
tdiv(class="category-description"):
|
||||||
|
text category.description.limit(categoryDescriptionCharLimit)
|
||||||
|
|
@ -155,7 +155,7 @@ when defined(js):
|
||||||
state.onAddCategoryClick()):
|
state.onAddCategoryClick()):
|
||||||
text "Add"
|
text "Add"
|
||||||
|
|
||||||
proc render*(state: CategoryPicker, currentUser: Option[User]): VNode =
|
proc render*(state: CategoryPicker, currentUser: Option[User], compact=false): VNode =
|
||||||
let loggedIn = currentUser.isSome()
|
let loggedIn = currentUser.isSome()
|
||||||
let currentAdmin =
|
let currentAdmin =
|
||||||
loggedIn and currentUser.get().rank == Admin
|
loggedIn and currentUser.get().rank == Admin
|
||||||
|
|
@ -178,7 +178,7 @@ when defined(js):
|
||||||
tdiv(class="dropdown"):
|
tdiv(class="dropdown"):
|
||||||
a(class="btn btn-link dropdown-toggle", tabindex="0"):
|
a(class="btn btn-link dropdown-toggle", tabindex="0"):
|
||||||
tdiv(class="selected-category d-inline-block"):
|
tdiv(class="selected-category d-inline-block"):
|
||||||
render(selectedCategory)
|
render(selectedCategory, compact=true)
|
||||||
text " "
|
text " "
|
||||||
italic(class="fas fa-caret-down")
|
italic(class="fas fa-caret-down")
|
||||||
ul(class="menu"):
|
ul(class="menu"):
|
||||||
|
|
@ -186,6 +186,6 @@ when defined(js):
|
||||||
li(class="menu-item"):
|
li(class="menu-item"):
|
||||||
a(class="category-" & $category.id & " " & category.name.slug,
|
a(class="category-" & $category.id & " " & category.name.slug,
|
||||||
onClick=onCategoryClick(state, category)):
|
onClick=onCategoryClick(state, category)):
|
||||||
render(category)
|
render(category, compact)
|
||||||
if state.addEnabled:
|
if state.addEnabled:
|
||||||
genAddCategory(state)
|
genAddCategory(state)
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,22 @@ import user
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
include karax/prelude
|
include karax/prelude
|
||||||
import karax / [vstyles, kajax, kdom]
|
import karax / [kdom]
|
||||||
|
|
||||||
import karaxutils, error, user
|
import karaxutils, user, categorypicker, category
|
||||||
|
|
||||||
let buttons = [
|
let buttons = [
|
||||||
(name: "Latest", url: makeUri("/"), id: "latest-btn"),
|
(name: "Latest", url: makeUri("/"), id: "latest-btn"),
|
||||||
(name: "Categories", url: makeUri("/categories"), id: "categories-btn"),
|
(name: "Categories", url: makeUri("/categories"), id: "categories-btn"),
|
||||||
]
|
]
|
||||||
|
|
||||||
proc renderMainButtons*(currentUser: Option[User]): VNode =
|
proc onSelectedCategoryChanged(oldCategory: Category, newCategory: Category) =
|
||||||
|
let uri = makeUri("/c/" & $newCategory.id)
|
||||||
|
navigateTo(uri)
|
||||||
|
|
||||||
|
let catPicker = newCategoryPicker(onCategoryChange=onSelectedCategoryChanged)
|
||||||
|
|
||||||
|
proc renderMainButtons*(currentUser: Option[User], categoryId = -1): VNode =
|
||||||
result = buildHtml():
|
result = buildHtml():
|
||||||
section(class="navbar container grid-xl", id="main-buttons"):
|
section(class="navbar container grid-xl", id="main-buttons"):
|
||||||
section(class="navbar-section"):
|
section(class="navbar-section"):
|
||||||
|
|
@ -23,6 +29,9 @@ when defined(js):
|
||||||
ul(class="menu"):
|
ul(class="menu"):
|
||||||
li: text "community"
|
li: text "community"
|
||||||
li: text "dev" ]#
|
li: text "dev" ]#
|
||||||
|
if categoryId != -1:
|
||||||
|
catPicker.selectedCategoryID = categoryId
|
||||||
|
render(catPicker, currentUser)
|
||||||
|
|
||||||
for btn in buttons:
|
for btn in buttons:
|
||||||
let active = btn.url == window.location.href
|
let active = btn.url == window.location.href
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ when defined(js):
|
||||||
else:
|
else:
|
||||||
return $duration.inSeconds & "s"
|
return $duration.inSeconds & "s"
|
||||||
|
|
||||||
proc genThread(thread: Thread, isNew: bool, noBorder: bool): VNode =
|
proc genThread(thread: Thread, isNew: bool, noBorder: bool, displayCategory=true): VNode =
|
||||||
let isOld = (getTime() - thread.creation.fromUnix).inWeeks > 2
|
let isOld = (getTime() - thread.creation.fromUnix).inWeeks > 2
|
||||||
let isBanned = thread.author.rank.isBanned()
|
let isBanned = thread.author.rank.isBanned()
|
||||||
result = buildHtml():
|
result = buildHtml():
|
||||||
|
|
@ -109,8 +109,9 @@ when defined(js):
|
||||||
a(href=makeUri("/t/" & $thread.id),
|
a(href=makeUri("/t/" & $thread.id),
|
||||||
onClick=anchorCB):
|
onClick=anchorCB):
|
||||||
text thread.topic
|
text thread.topic
|
||||||
td():
|
if displayCategory:
|
||||||
render(thread.category)
|
td():
|
||||||
|
render(thread.category, compact=true)
|
||||||
genUserAvatars(thread.users)
|
genUserAvatars(thread.users)
|
||||||
td(): text $thread.replies
|
td(): text $thread.replies
|
||||||
td(class=class({
|
td(class=class({
|
||||||
|
|
@ -193,7 +194,8 @@ when defined(js):
|
||||||
thead():
|
thead():
|
||||||
tr:
|
tr:
|
||||||
th(text "Topic")
|
th(text "Topic")
|
||||||
th(text "Category")
|
if categoryId == -1:
|
||||||
|
th(text "Category")
|
||||||
th(style=style((StyleAttr.width, kstring"8rem"))): text "Users"
|
th(style=style((StyleAttr.width, kstring"8rem"))): text "Users"
|
||||||
th(text "Replies")
|
th(text "Replies")
|
||||||
th(text "Views")
|
th(text "Views")
|
||||||
|
|
@ -206,7 +208,8 @@ when defined(js):
|
||||||
let isLastThread = i+1 == list.threads.len
|
let isLastThread = i+1 == list.threads.len
|
||||||
let (isLastUnseen, isNew) = getInfo(list.threads, i, currentUser)
|
let (isLastUnseen, isNew) = getInfo(list.threads, i, currentUser)
|
||||||
genThread(thread, isNew,
|
genThread(thread, isNew,
|
||||||
noBorder=isLastUnseen or isLastThread)
|
noBorder=isLastUnseen or isLastThread,
|
||||||
|
displayCategory=categoryId == -1)
|
||||||
if isLastUnseen and (not isLastThread):
|
if isLastUnseen and (not isLastThread):
|
||||||
tr(class="last-visit-separator"):
|
tr(class="last-visit-separator"):
|
||||||
td(colspan="6"):
|
td(colspan="6"):
|
||||||
|
|
@ -224,5 +227,5 @@ when defined(js):
|
||||||
|
|
||||||
proc renderThreadList*(currentUser: Option[User], categoryId = -1): VNode =
|
proc renderThreadList*(currentUser: Option[User], categoryId = -1): VNode =
|
||||||
result = buildHtml(tdiv):
|
result = buildHtml(tdiv):
|
||||||
renderMainButtons(currentUser)
|
renderMainButtons(currentUser, categoryId=categoryId)
|
||||||
genThreadList(currentUser, categoryId)
|
genThreadList(currentUser, categoryId)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue