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:
Dominik Picheta 2020-03-04 23:57:27 +01:00 • committed by GitHub
commit b91bdeb450
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 48 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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]

View file

@ -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

View file

@ -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.}

View file

@ -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:

View file

@ -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)