nimpkgs/src/pages/search.nim

107 lines
3.2 KiB
Nim

import std/[algorithm, strutils, sequtils, dom]
import karax/[kbase, karax, karaxdsl, vdom, jstrutils, kdom]
import ../[packages, context]
import ../components/[package, search]
import ../utils
type
SortMethod = enum
smAlphabetical, smCommitAge, smVersionAge
PageContext = object
sortMethod: SortMethod = smAlphabetical
filteredPackages: seq[NimPackage]
search: kstring
var pgCtx = PageContext()
proc scrollToAnchor(a: string): proc() =
result = proc() =
let d = getVNodeById(a)
scrollIntoView(d.dom)
proc letterlink(activeLinks: seq[char]): VNode = buildHtml:
tdiv(
class = "flex flex-wrap md:text-xl text-lg capitalize w-full justify-evenly gap-x-2 md:gap-x-auto"
):
for l in LowercaseLetters:
tdiv(class = "w-5"):
if l in activeLinks:
span(
class = "link underline decoration-dotted",
onClick = scrollToAnchor($l)
): text l.jss
else: span(class = "text-ctp-crust"): text l.jss
proc startChar(p: NimPackage): char =
p.name[0].toLowerAscii
proc alphabeticalPackageList(pkgs: seq[NimPackage]): VNode =
var charPackages: OrderedTable[char, seq[NimPackage]]
for pkg in pkgs:
let c = pkg.startChar
if c in charPackages:
charPackages[c].add pkg
else:
charPackages[c] = @[pkg]
result = buildHtml(tdiv):
letterlink(charPackages.keys.toSeq)
for c, packages in charPackages:
tdiv(`id` = c.jss)
for pkg in packages:
pkg.card
proc selectSortMethod() =
let v = getVNodeById("sort-select").getInputText
pgCtx.sortMethod = SortMethod(parseInt(v))
proc sortSelector(): VNode =
buildHtml(tdiv(class = "flex items-center")):
label(`for` = "sort-select"): text "sort:"
select(class = "bg-ctp-crust rounded p-3", name = "sort",
`id` = "sort-select", onChange = selectSortMethod):
for i, msg in ["alphabetical", "recent commit", "recent version"]:
if i == ord(pgCtx.sortMethod):
option(value = ($i).cstring, selected = ""): text msg
else:
option(value = ($i).cstring): text msg
proc filteredPackagesDom(): VNode =
if pgCtx.filteredPackages.len == 0:
return buildHtml(): text "no match...try a different query"
else:
case pgCtx.sortMethod:
of smAlphabetical:
pgCtx.filteredPackages.sort(sortAlphabetical)
of smCommitAge:
pgCtx.filteredPackages.sort(sortCommit, order = Descending)
of smVersionAge:
pgCtx.filteredPackages.sort(sortVersion, order = Descending)
result = buildHtml(tdiv):
tdiv(class = "text-ctp-surfacetwo"):
text ($pgCtx.filteredPackages.len & "/" & $ctx.nimpkgs.packages.len) & " packages"
case pgCtx.sortMethod:
of smAlphabetical:
pgCtx.filteredPackages.alphabeticalPackageList
else:
for pkg in pgCtx.filteredPackages:
pkg.card
proc update(pgCtx: var PageContext) =
pgCtx.filteredPackages = ctx.nimpkgs.packages.values().toSeq()
pgCtx.search = getSearchFromUri()
pgCtx.filteredPackages = searchPackages(parseQuery(pgCtx.search))
proc render*(): VNode =
pgCtx.update
result =
buildHtml(tdiv):
tdiv(class = "flex md:flex-row md: space-x-5"):
searchBar(value = pgCtx.search)
sortSelector()
filteredPackagesDom()