Remove reloading and fix issues with state not being refreshed (#232)
* Remove reloading and fix issues with state not being refreshed * Fix PR comments * Remove unnecessary closure * Change proc to anonymous proc * categoryIdOption -> categoryId
This commit is contained in:
parent
7a7a7145ee
commit
b91bdeb450
7 changed files with 50 additions and 48 deletions
|
|
@ -13,6 +13,7 @@ when defined(js):
|
|||
State = ref object
|
||||
list: Option[CategoryList]
|
||||
loading: bool
|
||||
mainButtons: MainButtons
|
||||
status: HttpCode
|
||||
addCategoryModal: AddCategoryModal
|
||||
|
||||
|
|
@ -22,6 +23,7 @@ when defined(js):
|
|||
State(
|
||||
list: none[CategoryList](),
|
||||
loading: false,
|
||||
mainButtons: newMainButtons(),
|
||||
status: Http200,
|
||||
addCategoryModal: newAddCategoryModal(
|
||||
onAddCategory=
|
||||
|
|
@ -99,5 +101,5 @@ when defined(js):
|
|||
|
||||
proc renderCategoryList*(currentUser: Option[User]): VNode =
|
||||
result = buildHtml(tdiv):
|
||||
renderMainButtons(currentUser)
|
||||
state.mainButtons.render(currentUser)
|
||||
renderCategories(currentUser)
|
||||
|
|
|
|||
|
|
@ -105,8 +105,7 @@ when defined(js):
|
|||
render(state.addCategoryModal)
|
||||
|
||||
proc render*(state: CategoryPicker, currentUser: Option[User], compact=true): VNode =
|
||||
if currentUser.isAdmin():
|
||||
state.setAddEnabled(true)
|
||||
state.setAddEnabled(currentUser.isAdmin())
|
||||
|
||||
if state.status != Http200:
|
||||
return renderError("Couldn't retrieve categories.", state.status)
|
||||
|
|
|
|||
|
|
@ -57,10 +57,6 @@ proc onPopState(event: dom.Event) =
|
|||
state = newState() # Reload the state to remove stale data.
|
||||
state.url = copyLocation(window.location)
|
||||
|
||||
# For some reason this is needed so that the back/forward buttons reload
|
||||
# the post list when different categories are selected
|
||||
window.location.reload()
|
||||
|
||||
redraw()
|
||||
|
||||
type Params = Table[string, string]
|
||||
|
|
|
|||
|
|
@ -32,41 +32,36 @@ when defined(js):
|
|||
var
|
||||
state = newState()
|
||||
|
||||
proc getStatus(logout=false, reload=false)
|
||||
proc getStatus(logout=false)
|
||||
proc newState(): State =
|
||||
State(
|
||||
data: none[UserStatus](),
|
||||
loading: false,
|
||||
status: Http200,
|
||||
loginModal: newLoginModal(
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus(reload=true)),
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus()),
|
||||
() => state.signupModal.show()
|
||||
),
|
||||
signupModal: newSignupModal(
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus(reload=true)),
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus()),
|
||||
() => state.loginModal.show()
|
||||
),
|
||||
userMenu: newUserMenu(
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus(logout=true, reload=true))
|
||||
() => (state.lastUpdate = fromUnix(0); getStatus(logout=true))
|
||||
)
|
||||
)
|
||||
|
||||
proc onStatus(reload: bool=false): proc (httpStatus: int, response: kstring) =
|
||||
result =
|
||||
proc (httpStatus: int, response: kstring) =
|
||||
state.loading = false
|
||||
state.status = httpStatus.HttpCode
|
||||
if state.status != Http200: return
|
||||
proc onStatus(httpStatus: int, response: kstring) =
|
||||
state.loading = false
|
||||
state.status = httpStatus.HttpCode
|
||||
if state.status != Http200: return
|
||||
|
||||
let parsed = parseJson($response)
|
||||
state.data = some(to(parsed, UserStatus))
|
||||
let parsed = parseJson($response)
|
||||
state.data = some(to(parsed, UserStatus))
|
||||
|
||||
state.lastUpdate = getTime()
|
||||
state.lastUpdate = getTime()
|
||||
|
||||
if reload:
|
||||
window.location.reload()
|
||||
|
||||
proc getStatus(logout=false, reload=false) =
|
||||
proc getStatus(logout=false) =
|
||||
if state.loading: return
|
||||
let diff = getTime() - state.lastUpdate
|
||||
if diff.inMinutes < 5:
|
||||
|
|
@ -74,7 +69,7 @@ when defined(js):
|
|||
|
||||
state.loading = true
|
||||
let uri = makeUri("status.json", [("logout", $logout)])
|
||||
ajaxGet(uri, @[], onStatus(reload))
|
||||
ajaxGet(uri, @[], onStatus)
|
||||
|
||||
proc getLoggedInUser*(): Option[User] =
|
||||
state.data.map(x => x.user).flatten
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ when defined(js):
|
|||
let url = n.getAttr("href")
|
||||
|
||||
navigateTo(url)
|
||||
window.location.href = url
|
||||
|
||||
proc newFormData*(form: dom.Element): FormData
|
||||
{.importcpp: "new FormData(@)", constructor.}
|
||||
|
|
|
|||
|
|
@ -17,17 +17,20 @@ when defined(js):
|
|||
navigateTo(uri)
|
||||
|
||||
type
|
||||
State = ref object
|
||||
MainButtons* = ref object
|
||||
categoryPicker: CategoryPicker
|
||||
onCategoryChange*: CategoryChangeEvent
|
||||
|
||||
proc newState(): State =
|
||||
State(
|
||||
categoryPicker: newCategoryPicker(onCategoryChange=onSelectedCategoryChanged),
|
||||
proc newMainButtons*(onCategoryChange: CategoryChangeEvent = onSelectedCategoryChanged): MainButtons =
|
||||
new result
|
||||
result.onCategoryChange = onCategoryChange
|
||||
result.categoryPicker = newCategoryPicker(
|
||||
onCategoryChange = proc (oldCategory, newCategory: Category) =
|
||||
onSelectedCategoryChanged(oldCategory, newCategory)
|
||||
result.onCategoryChange(oldCategory, newCategory)
|
||||
)
|
||||
|
||||
let state = newState()
|
||||
|
||||
proc renderMainButtons*(currentUser: Option[User], categoryIdOption = none(int)): VNode =
|
||||
proc render*(state: MainButtons, currentUser: Option[User], categoryId = none(int)): VNode =
|
||||
result = buildHtml():
|
||||
section(class="navbar container grid-xl", id="main-buttons"):
|
||||
section(class="navbar-section"):
|
||||
|
|
@ -38,8 +41,8 @@ when defined(js):
|
|||
ul(class="menu"):
|
||||
li: text "community"
|
||||
li: text "dev" ]#
|
||||
if categoryIdOption.isSome:
|
||||
state.categoryPicker.selectedCategoryID = categoryIdOption.get()
|
||||
if categoryId.isSome:
|
||||
state.categoryPicker.selectedCategoryID = categoryId.get()
|
||||
render(state.categoryPicker, currentUser, compact=false)
|
||||
|
||||
for btn in buttons:
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ proc isModerated*(thread: Thread): bool =
|
|||
thread.author.rank <= Moderated
|
||||
|
||||
when defined(js):
|
||||
import sugar
|
||||
include karax/prelude
|
||||
import karax / [vstyles, kajax, kdom]
|
||||
|
||||
|
|
@ -34,18 +35,25 @@ when defined(js):
|
|||
type
|
||||
State = ref object
|
||||
list: Option[ThreadList]
|
||||
refreshList: bool
|
||||
loading: bool
|
||||
status: HttpCode
|
||||
mainButtons: MainButtons
|
||||
|
||||
var state: State
|
||||
|
||||
proc newState(): State =
|
||||
State(
|
||||
list: none[ThreadList](),
|
||||
loading: false,
|
||||
status: Http200
|
||||
status: Http200,
|
||||
mainButtons: newMainButtons(
|
||||
onCategoryChange =
|
||||
(oldCategory: Category, newCategory: Category) => (state.list = none[ThreadList]())
|
||||
)
|
||||
)
|
||||
|
||||
var
|
||||
state = newState()
|
||||
state = newState()
|
||||
|
||||
proc visibleTo*[T](thread: T, user: Option[User]): bool =
|
||||
## Determines whether the specified thread (or post) should be
|
||||
|
|
@ -147,11 +155,11 @@ when defined(js):
|
|||
else:
|
||||
state.list = some(list)
|
||||
|
||||
proc onLoadMore(ev: Event, n: VNode, categoryIdOption: Option[int]) =
|
||||
proc onLoadMore(ev: Event, n: VNode, categoryId: Option[int]) =
|
||||
state.loading = true
|
||||
let start = state.list.get().threads.len
|
||||
if categoryIdOption.isSome:
|
||||
ajaxGet(makeUri("threads.json?start=" & $start & "&categoryId=" & $categoryIdOption.get()), @[], onThreadList)
|
||||
if categoryId.isSome:
|
||||
ajaxGet(makeUri("threads.json?start=" & $start & "&categoryId=" & $categoryId.get()), @[], onThreadList)
|
||||
else:
|
||||
ajaxGet(makeUri("threads.json?start=" & $start), @[], onThreadList)
|
||||
|
||||
|
|
@ -178,15 +186,15 @@ when defined(js):
|
|||
isNew: thread.creation > previousVisitAt
|
||||
)
|
||||
|
||||
proc genThreadList(currentUser: Option[User], categoryIdOption: Option[int]): VNode =
|
||||
proc genThreadList(currentUser: Option[User], categoryId: Option[int]): VNode =
|
||||
if state.status != Http200:
|
||||
return renderError("Couldn't retrieve threads.", state.status)
|
||||
|
||||
if state.list.isNone:
|
||||
if not state.loading:
|
||||
state.loading = true
|
||||
if categoryIdOption.isSome:
|
||||
ajaxGet(makeUri("threads.json?categoryId=" & $categoryIdOption.get()), @[], onThreadList)
|
||||
if categoryId.isSome:
|
||||
ajaxGet(makeUri("threads.json?categoryId=" & $categoryId.get()), @[], onThreadList)
|
||||
else:
|
||||
ajaxGet(makeUri("threads.json"), @[], onThreadList)
|
||||
|
||||
|
|
@ -229,10 +237,10 @@ when defined(js):
|
|||
tdiv(class="loading loading-lg")
|
||||
else:
|
||||
td(colspan="6",
|
||||
onClick = (ev: Event, n: VNode) => (onLoadMore(ev, n, categoryIdOption))):
|
||||
onClick = (ev: Event, n: VNode) => (onLoadMore(ev, n, categoryId))):
|
||||
span(text "load more threads")
|
||||
|
||||
proc renderThreadList*(currentUser: Option[User], categoryIdOption = none(int)): VNode =
|
||||
proc renderThreadList*(currentUser: Option[User], categoryId = none(int)): VNode =
|
||||
result = buildHtml(tdiv):
|
||||
renderMainButtons(currentUser, categoryIdOption=categoryIdOption)
|
||||
genThreadList(currentUser, categoryIdOption)
|
||||
state.mainButtons.render(currentUser, categoryId=categoryId)
|
||||
genThreadList(currentUser, categoryId)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue