todoapp: use local storage properly
This commit is contained in:
parent
00354cfc18
commit
6aa87e4b81
3 changed files with 40 additions and 26 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import vdom, karax, karaxdsl, jstrutils, components
|
import vdom, karax, karaxdsl, jstrutils, components, localstorage
|
||||||
|
|
||||||
type
|
type
|
||||||
Filter = enum
|
Filter = enum
|
||||||
|
|
@ -10,36 +10,35 @@ var
|
||||||
filter: Filter
|
filter: Filter
|
||||||
entriesLen: int
|
entriesLen: int
|
||||||
|
|
||||||
proc getItem(key : cstring ): cstring {.importc: "localStorage.getItem"}
|
const
|
||||||
proc setItem(key, value : cstring ) {.importc: "localStorage.setItem"}
|
contentSuffix = cstring"content"
|
||||||
proc clearEntries() {.importc: "localStorage.clear"}
|
completedSuffix = cstring"completed"
|
||||||
|
lenSuffix = cstring"entriesLen"
|
||||||
|
|
||||||
proc getEntryCstring(pos: int): cstring =
|
proc getEntryContent(pos: int): cstring =
|
||||||
result = getItem(&pos & cstring"cstring")
|
result = getItem(&pos & contentSuffix)
|
||||||
if result == cstring"null":
|
if result == cstring"null":
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc isCompleted(pos: int): bool =
|
proc isCompleted(pos: int): bool =
|
||||||
var value = getItem(cstring($pos & "bool"))
|
var value = getItem(&pos & completedSuffix)
|
||||||
result = value == cstring"true"
|
result = value == cstring"true"
|
||||||
|
|
||||||
proc setEntryCstring(pos: int, value: cstring) =
|
proc setEntryContent(pos: int, content: cstring) =
|
||||||
setItem(cstring($pos & "cstring"), value)
|
setItem(&pos & contentSuffix, content)
|
||||||
|
|
||||||
proc markAsCompleted(pos: int, value : bool) =
|
proc markAsCompleted(pos: int, completed: bool) =
|
||||||
var val = cstring"true"
|
setItem(&pos & completedSuffix, &completed)
|
||||||
if not value:
|
|
||||||
val = cstring"false"
|
|
||||||
setItem(cstring($pos & "bool"), val)
|
|
||||||
|
|
||||||
proc addEntry(str: cstring, bval : bool) =
|
proc addEntry(content: cstring, completed: bool) =
|
||||||
setEntryCstring(entriesLen, str)
|
setEntryContent(entriesLen, content)
|
||||||
markAsCompleted(entriesLen, bval)
|
markAsCompleted(entriesLen, completed)
|
||||||
inc entriesLen
|
inc entriesLen
|
||||||
|
setItem(lenSuffix, &entriesLen)
|
||||||
|
|
||||||
proc updateEntry(pos: int, str: cstring, bval: bool) =
|
proc updateEntry(pos: int, content: cstring, completed: bool) =
|
||||||
setEntryCstring(pos, str)
|
setEntryContent(pos, content)
|
||||||
markAsCompleted(pos, bval)
|
markAsCompleted(pos, completed)
|
||||||
|
|
||||||
proc onTodoEnter(ev: Event; n: VNode) =
|
proc onTodoEnter(ev: Event; n: VNode) =
|
||||||
addEntry(n.value, false)
|
addEntry(n.value, false)
|
||||||
|
|
@ -54,7 +53,7 @@ proc editHandler(ev: Event; n: VNode) =
|
||||||
proc focusLost(ev: Event; n: VNode) = selectedEntry = -1
|
proc focusLost(ev: Event; n: VNode) = selectedEntry = -1
|
||||||
|
|
||||||
proc editEntry(ev: Event; n: VNode) =
|
proc editEntry(ev: Event; n: VNode) =
|
||||||
setEntryCstring(n.key, n.value)
|
setEntryContent(n.key, n.value)
|
||||||
selectedEntry = -1
|
selectedEntry = -1
|
||||||
|
|
||||||
proc toggleEntry(ev: Event; n: VNode) =
|
proc toggleEntry(ev: Event; n: VNode) =
|
||||||
|
|
@ -62,12 +61,12 @@ proc toggleEntry(ev: Event; n: VNode) =
|
||||||
markAsCompleted(id, not isCompleted(id))
|
markAsCompleted(id, not isCompleted(id))
|
||||||
|
|
||||||
proc onAllDone(ev: Event; n: VNode) =
|
proc onAllDone(ev: Event; n: VNode) =
|
||||||
clearEntries()
|
clear()
|
||||||
selectedEntry = -1
|
selectedEntry = -1
|
||||||
|
|
||||||
proc clearCompleted(ev: Event, n: VNode) =
|
proc clearCompleted(ev: Event, n: VNode) =
|
||||||
for i in 0..<entriesLen:
|
for i in 0..<entriesLen:
|
||||||
if isCompleted(i): setEntryCstring(i, nil)
|
if isCompleted(i): setEntryContent(i, nil)
|
||||||
|
|
||||||
proc toClass(completed: bool): cstring =
|
proc toClass(completed: bool): cstring =
|
||||||
(if completed: cstring"completed" else: cstring(nil))
|
(if completed: cstring"completed" else: cstring(nil))
|
||||||
|
|
@ -132,8 +131,7 @@ proc createDom(): VNode =
|
||||||
ul(class = "todo-list"):
|
ul(class = "todo-list"):
|
||||||
#for i, d in pairs(entries):
|
#for i, d in pairs(entries):
|
||||||
for i in 0..entriesLen-1:
|
for i in 0..entriesLen-1:
|
||||||
|
var d0 = getEntryContent(i)
|
||||||
var d0 = getEntryCstring(i)
|
|
||||||
var d1 = isCompleted(i)
|
var d1 = isCompleted(i)
|
||||||
if d0 != nil:
|
if d0 != nil:
|
||||||
let b = case filter
|
let b = case filter
|
||||||
|
|
@ -151,5 +149,9 @@ setOnHashChange(proc(hash: cstring) =
|
||||||
elif hash == "#/completed": filter = completed
|
elif hash == "#/completed": filter = completed
|
||||||
elif hash == "#/active": filter = active
|
elif hash == "#/active": filter = active
|
||||||
)
|
)
|
||||||
entriesLen = 0
|
|
||||||
|
if hasItem(lenSuffix):
|
||||||
|
entriesLen = parseInt getItem(lenSuffix)
|
||||||
|
else:
|
||||||
|
entriesLen = 0
|
||||||
setRenderer createDom
|
setRenderer createDom
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,5 @@ proc isInt*(s: cstring): bool {.asmNoStackFrame.} =
|
||||||
asm """
|
asm """
|
||||||
return s.match(/^[0-9]+$/);
|
return s.match(/^[0-9]+$/);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
proc parseInt*(s: cstring): int {.importcpp: "parseInt(#, 10)", nodecl.}
|
||||||
|
|
|
||||||
10
src/localstorage.nim
Normal file
10
src/localstorage.nim
Normal 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".}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue