Generate Prefs type
This commit is contained in:
		
							parent
							
								
									d05f4fd3ee
								
							
						
					
					
						commit
						16f77223ff
					
				| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
import asyncdispatch, times, macros, tables, xmltree
 | 
			
		||||
import strutils
 | 
			
		||||
import types
 | 
			
		||||
import prefs_impl
 | 
			
		||||
 | 
			
		||||
const hostname {.strdefine.} = "nitter.net"
 | 
			
		||||
export genUpdatePrefs
 | 
			
		||||
 | 
			
		||||
withCustomDb("prefs.db", "", "", ""):
 | 
			
		||||
  try:
 | 
			
		||||
| 
						 | 
				
			
			@ -9,74 +10,6 @@ withCustomDb("prefs.db", "", "", ""):
 | 
			
		|||
  except DbError:
 | 
			
		||||
    discard
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  PrefKind* = enum
 | 
			
		||||
    checkbox, select, input
 | 
			
		||||
 | 
			
		||||
  Pref* = object
 | 
			
		||||
    name*: string
 | 
			
		||||
    label*: string
 | 
			
		||||
    case kind*: PrefKind
 | 
			
		||||
    of checkbox:
 | 
			
		||||
      defaultState*: bool
 | 
			
		||||
    of select:
 | 
			
		||||
      defaultOption*: string
 | 
			
		||||
      options*: seq[string]
 | 
			
		||||
    of input:
 | 
			
		||||
      defaultInput*: string
 | 
			
		||||
      placeholder*: string
 | 
			
		||||
 | 
			
		||||
# TODO: write DSL to simplify this
 | 
			
		||||
const prefList*: Table[string, seq[Pref]] = {
 | 
			
		||||
  "Privacy": @[
 | 
			
		||||
    Pref(kind: input, name: "replaceTwitter",
 | 
			
		||||
         label: "Replace Twitter links with Nitter (blank to disable)",
 | 
			
		||||
         defaultInput: hostname, placeholder: "Nitter hostname"),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: input, name: "replaceYouTube",
 | 
			
		||||
         label: "Replace YouTube links with Invidious (blank to disable)",
 | 
			
		||||
         defaultInput: "invidio.us", placeholder: "Invidious hostname")
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  "Media": @[
 | 
			
		||||
    Pref(kind: checkbox, name: "videoPlayback",
 | 
			
		||||
         label: "Enable hls.js video playback (requires JavaScript)",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "autoplayGifs", label: "Autoplay gifs",
 | 
			
		||||
         defaultState: true)
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  "Display": @[
 | 
			
		||||
    Pref(kind: checkbox, name: "hideTweetStats",
 | 
			
		||||
         label: "Hide tweet stats (replies, retweets, likes)",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "hideBanner", label: "Hide profile banner",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "stickyProfile",
 | 
			
		||||
         label: "Make profile sidebar stick to top",
 | 
			
		||||
         defaultState: true)
 | 
			
		||||
  ]
 | 
			
		||||
}.toTable
 | 
			
		||||
 | 
			
		||||
iterator allPrefs(): Pref =
 | 
			
		||||
  for k, v in prefList:
 | 
			
		||||
    for pref in v:
 | 
			
		||||
      yield pref
 | 
			
		||||
 | 
			
		||||
macro genDefaultPrefs*(): untyped =
 | 
			
		||||
  result = nnkObjConstr.newTree(ident("Prefs"))
 | 
			
		||||
 | 
			
		||||
  for pref in allPrefs():
 | 
			
		||||
    result.add nnkExprColonExpr.newTree(
 | 
			
		||||
      ident(pref.name),
 | 
			
		||||
      case pref.kind
 | 
			
		||||
      of checkbox: newLit(pref.defaultState)
 | 
			
		||||
      of select: newLit(pref.defaultOption)
 | 
			
		||||
      of input: newLit(pref.defaultInput))
 | 
			
		||||
 | 
			
		||||
proc cache*(prefs: var Prefs) =
 | 
			
		||||
  withCustomDb("prefs.db", "", "", ""):
 | 
			
		||||
    try:
 | 
			
		||||
| 
						 | 
				
			
			@ -101,25 +34,3 @@ proc resetPrefs*(prefs: var Prefs) =
 | 
			
		|||
  defPrefs.id = prefs.id
 | 
			
		||||
  cache(defPrefs)
 | 
			
		||||
  prefs = defPrefs
 | 
			
		||||
 | 
			
		||||
macro genUpdatePrefs*(): untyped =
 | 
			
		||||
  result = nnkStmtList.newTree()
 | 
			
		||||
 | 
			
		||||
  for pref in allPrefs():
 | 
			
		||||
    let ident = ident(pref.name)
 | 
			
		||||
    let value = nnkPrefix.newTree(ident("@"), newLit(pref.name))
 | 
			
		||||
 | 
			
		||||
    case pref.kind
 | 
			
		||||
    of checkbox:
 | 
			
		||||
      result.add quote do: prefs.`ident` = `value` == "on"
 | 
			
		||||
    of input:
 | 
			
		||||
      result.add quote do: prefs.`ident` = xmltree.escape(strip(`value`))
 | 
			
		||||
    of select:
 | 
			
		||||
      let options = pref.options
 | 
			
		||||
      let default = pref.defaultOption
 | 
			
		||||
      result.add quote do:
 | 
			
		||||
        if `value` in `options`: prefs.`ident` = `value`
 | 
			
		||||
        else: prefs.`ident` = `default`
 | 
			
		||||
 | 
			
		||||
  result.add quote do:
 | 
			
		||||
    cache(prefs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
import macros, tables, strutils, xmltree
 | 
			
		||||
 | 
			
		||||
const hostname {.strdefine.} = "nitter.net"
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  PrefKind* = enum
 | 
			
		||||
    checkbox, select, input
 | 
			
		||||
 | 
			
		||||
  Pref* = object
 | 
			
		||||
    name*: string
 | 
			
		||||
    label*: string
 | 
			
		||||
    case kind*: PrefKind
 | 
			
		||||
    of checkbox:
 | 
			
		||||
      defaultState*: bool
 | 
			
		||||
    of select:
 | 
			
		||||
      defaultOption*: string
 | 
			
		||||
      options*: seq[string]
 | 
			
		||||
    of input:
 | 
			
		||||
      defaultInput*: string
 | 
			
		||||
      placeholder*: string
 | 
			
		||||
 | 
			
		||||
# TODO: write DSL to simplify this
 | 
			
		||||
const prefList*: Table[string, seq[Pref]] = {
 | 
			
		||||
  "Privacy": @[
 | 
			
		||||
    Pref(kind: input, name: "replaceTwitter",
 | 
			
		||||
         label: "Replace Twitter links with Nitter (blank to disable)",
 | 
			
		||||
         defaultInput: hostname, placeholder: "Nitter hostname"),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: input, name: "replaceYouTube",
 | 
			
		||||
         label: "Replace YouTube links with Invidious (blank to disable)",
 | 
			
		||||
         defaultInput: "invidio.us", placeholder: "Invidious hostname")
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  "Media": @[
 | 
			
		||||
    Pref(kind: checkbox, name: "videoPlayback",
 | 
			
		||||
         label: "Enable hls.js video playback (requires JavaScript)",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "autoplayGifs", label: "Autoplay gifs",
 | 
			
		||||
         defaultState: true)
 | 
			
		||||
  ],
 | 
			
		||||
 | 
			
		||||
  "Display": @[
 | 
			
		||||
    Pref(kind: checkbox, name: "hideTweetStats",
 | 
			
		||||
         label: "Hide tweet stats (replies, retweets, likes)",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "hideBanner", label: "Hide profile banner",
 | 
			
		||||
         defaultState: false),
 | 
			
		||||
 | 
			
		||||
    Pref(kind: checkbox, name: "stickyProfile",
 | 
			
		||||
         label: "Make profile sidebar stick to top",
 | 
			
		||||
         defaultState: true)
 | 
			
		||||
  ]
 | 
			
		||||
}.toTable
 | 
			
		||||
 | 
			
		||||
iterator allPrefs(): Pref =
 | 
			
		||||
  for k, v in prefList:
 | 
			
		||||
    for pref in v:
 | 
			
		||||
      yield pref
 | 
			
		||||
 | 
			
		||||
macro genDefaultPrefs*(): untyped =
 | 
			
		||||
  result = nnkObjConstr.newTree(ident("Prefs"))
 | 
			
		||||
 | 
			
		||||
  for pref in allPrefs():
 | 
			
		||||
    let default =
 | 
			
		||||
      case pref.kind
 | 
			
		||||
      of checkbox: newLit(pref.defaultState)
 | 
			
		||||
      of select: newLit(pref.defaultOption)
 | 
			
		||||
      of input: newLit(pref.defaultInput)
 | 
			
		||||
 | 
			
		||||
    result.add nnkExprColonExpr.newTree(ident(pref.name), default)
 | 
			
		||||
 | 
			
		||||
macro genUpdatePrefs*(): untyped =
 | 
			
		||||
  result = nnkStmtList.newTree()
 | 
			
		||||
 | 
			
		||||
  for pref in allPrefs():
 | 
			
		||||
    let ident = ident(pref.name)
 | 
			
		||||
    let value = nnkPrefix.newTree(ident("@"), newLit(pref.name))
 | 
			
		||||
 | 
			
		||||
    case pref.kind
 | 
			
		||||
    of checkbox:
 | 
			
		||||
      result.add quote do: prefs.`ident` = `value` == "on"
 | 
			
		||||
    of input:
 | 
			
		||||
      result.add quote do: prefs.`ident` = xmltree.escape(strip(`value`))
 | 
			
		||||
    of select:
 | 
			
		||||
      let options = pref.options
 | 
			
		||||
      let default = pref.defaultOption
 | 
			
		||||
      result.add quote do:
 | 
			
		||||
        if `value` in `options`: prefs.`ident` = `value`
 | 
			
		||||
        else: prefs.`ident` = `default`
 | 
			
		||||
 | 
			
		||||
  result.add quote do:
 | 
			
		||||
    cache(prefs)
 | 
			
		||||
 | 
			
		||||
macro genPrefsType*(): untyped =
 | 
			
		||||
  result = nnkTypeSection.newTree(nnkTypeDef.newTree(
 | 
			
		||||
    nnkPostfix.newTree(ident("*"), ident("Prefs")), newEmptyNode(),
 | 
			
		||||
    nnkObjectTy.newTree(newEmptyNode(), newEmptyNode(), nnkRecList.newTree())))
 | 
			
		||||
 | 
			
		||||
  result[0][2][2].add nnkIdentDefs.newTree(
 | 
			
		||||
    nnkPostfix.newTree(ident("*"), ident("id")), ident("int"), newEmptyNode())
 | 
			
		||||
 | 
			
		||||
  for pref in allPrefs():
 | 
			
		||||
    result[0][2][2].add nnkIdentDefs.newTree(
 | 
			
		||||
      nnkPostfix.newTree(ident("*"), ident(pref.name)),
 | 
			
		||||
      (case pref.kind
 | 
			
		||||
       of checkbox: ident("bool")
 | 
			
		||||
       of input, select: ident("string")),
 | 
			
		||||
      newEmptyNode())
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import times, sequtils, options
 | 
			
		||||
import norm/sqlite
 | 
			
		||||
import prefs_impl
 | 
			
		||||
 | 
			
		||||
export sqlite, options
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,14 +50,7 @@ db("cache.db", "", "", ""):
 | 
			
		|||
          formatIt: dbValue($it)
 | 
			
		||||
        .}: VideoType
 | 
			
		||||
 | 
			
		||||
    Prefs* = object
 | 
			
		||||
      videoPlayback*: bool
 | 
			
		||||
      autoplayGifs*: bool
 | 
			
		||||
      hideTweetStats*: bool
 | 
			
		||||
      hideBanner*: bool
 | 
			
		||||
      stickyProfile*: bool
 | 
			
		||||
      replaceYouTube*: string
 | 
			
		||||
      replaceTwitter*: string
 | 
			
		||||
  genPrefsType()
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  QueryKind* = enum
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import tables, macros, strformat, xmltree
 | 
			
		||||
import karax/[karaxdsl, vdom, vstyles]
 | 
			
		||||
 | 
			
		||||
import ../types, ../prefs
 | 
			
		||||
import ../types, ../prefs_impl
 | 
			
		||||
 | 
			
		||||
proc genCheckbox(pref, label: string; state: bool): VNode =
 | 
			
		||||
  buildHtml(tdiv(class="pref-group")):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue