todoapp: use local storage properly

This commit is contained in:
Andreas Rumpf 2017-04-22 10:45:42 +02:00
commit 6aa87e4b81
3 changed files with 40 additions and 26 deletions

View file

@ -1,5 +1,5 @@
import vdom, karax, karaxdsl, jstrutils, components
import vdom, karax, karaxdsl, jstrutils, components, localstorage
type
Filter = enum
@ -10,36 +10,35 @@ var
filter: Filter
entriesLen: int
proc getItem(key : cstring ): cstring {.importc: "localStorage.getItem"}
proc setItem(key, value : cstring ) {.importc: "localStorage.setItem"}
proc clearEntries() {.importc: "localStorage.clear"}
const
contentSuffix = cstring"content"
completedSuffix = cstring"completed"
lenSuffix = cstring"entriesLen"
proc getEntryCstring(pos: int): cstring =
result = getItem(&pos & cstring"cstring")
proc getEntryContent(pos: int): cstring =
result = getItem(&pos & contentSuffix)
if result == cstring"null":
result = nil
proc isCompleted(pos: int): bool =
var value = getItem(cstring($pos & "bool"))
var value = getItem(&pos & completedSuffix)
result = value == cstring"true"
proc setEntryCstring(pos: int, value: cstring) =
setItem(cstring($pos & "cstring"), value)
proc setEntryContent(pos: int, content: cstring) =
setItem(&pos & contentSuffix, content)
proc markAsCompleted(pos: int, value : bool) =
var val = cstring"true"
if not value:
val = cstring"false"
setItem(cstring($pos & "bool"), val)
proc markAsCompleted(pos: int, completed: bool) =
setItem(&pos & completedSuffix, &completed)
proc addEntry(str: cstring, bval : bool) =
setEntryCstring(entriesLen, str)
markAsCompleted(entriesLen, bval)
proc addEntry(content: cstring, completed: bool) =
setEntryContent(entriesLen, content)
markAsCompleted(entriesLen, completed)
inc entriesLen
setItem(lenSuffix, &entriesLen)
proc updateEntry(pos: int, str: cstring, bval: bool) =
setEntryCstring(pos, str)
markAsCompleted(pos, bval)
proc updateEntry(pos: int, content: cstring, completed: bool) =
setEntryContent(pos, content)
markAsCompleted(pos, completed)
proc onTodoEnter(ev: Event; n: VNode) =
addEntry(n.value, false)
@ -54,7 +53,7 @@ proc editHandler(ev: Event; n: VNode) =
proc focusLost(ev: Event; n: VNode) = selectedEntry = -1
proc editEntry(ev: Event; n: VNode) =
setEntryCstring(n.key, n.value)
setEntryContent(n.key, n.value)
selectedEntry = -1
proc toggleEntry(ev: Event; n: VNode) =
@ -62,12 +61,12 @@ proc toggleEntry(ev: Event; n: VNode) =
markAsCompleted(id, not isCompleted(id))
proc onAllDone(ev: Event; n: VNode) =
clearEntries()
clear()
selectedEntry = -1
proc clearCompleted(ev: Event, n: VNode) =
for i in 0..<entriesLen:
if isCompleted(i): setEntryCstring(i, nil)
if isCompleted(i): setEntryContent(i, nil)
proc toClass(completed: bool): cstring =
(if completed: cstring"completed" else: cstring(nil))
@ -132,8 +131,7 @@ proc createDom(): VNode =
ul(class = "todo-list"):
#for i, d in pairs(entries):
for i in 0..entriesLen-1:
var d0 = getEntryCstring(i)
var d0 = getEntryContent(i)
var d1 = isCompleted(i)
if d0 != nil:
let b = case filter
@ -151,5 +149,9 @@ setOnHashChange(proc(hash: cstring) =
elif hash == "#/completed": filter = completed
elif hash == "#/active": filter = active
)
entriesLen = 0
if hasItem(lenSuffix):
entriesLen = parseInt getItem(lenSuffix)
else:
entriesLen = 0
setRenderer createDom

View file

@ -21,3 +21,5 @@ proc isInt*(s: cstring): bool {.asmNoStackFrame.} =
asm """
return s.match(/^[0-9]+$/);
"""
proc parseInt*(s: cstring): int {.importcpp: "parseInt(#, 10)", nodecl.}

10
src/localstorage.nim Normal file
View file

@ -0,0 +1,10 @@
## Karax -- Single page applications for Nim.
## This module contains wrappers for the HTML 5 local storage.
proc getItem*(key: cstring): cstring {.importc: "localStorage.getItem"}
proc setItem*(key, value: cstring) {.importc: "localStorage.setItem"}
proc hasItem*(key: cstring): bool {.importcpp: "(localStorage.getItem(#) !== null)".}
proc clear*() {.importc: "localStorage.clear"}
proc removeItem*(key: cstring) {.importc: "localStorage.removeItem".}