Module: Preflex::PreferencesHelper

Extended by:
PreferencesHelper
Included in:
PreferencesHelper
Defined in:
app/helpers/preflex/preferences_helper.rb

Instance Method Summary collapse

Instance Method Details

#script_tag(*preference_klasses) ⇒ Object

PREFLEX_PREFERENCE_JS = File.read(Preferences::Preflex::Engine.root.join(“app”, “static”, “preflex_preference.js”))



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/helpers/preflex/preferences_helper.rb', line 6

def script_tag(*preference_klasses)
  return ''.html_safe if preference_klasses.empty?

  base = "    const CSRF_TOKEN = \"\#{Preflex::Current.controller_instance.send(:form_authenticity_token)}\"\n    const UPDATE_PATH = \"\#{Preflex::Engine.routes.url_helpers.preferences_path}\"\n    class PreflexPreference {\n      constructor(klass, data) {\n        this.klass = klass\n        this.localStorageKey = `PreflexPreference-${klass}`\n\n        this.data = data\n        this.dataLocal = JSON.parse(localStorage.getItem(this.localStorageKey) || '{}')\n      }\n\n      get(name) {\n        this.ensurePreferenceExists(name)\n\n        const fromServer = this.data[name]\n        const fromServerUpdatedAt = this.data[`${name}_updated_at_epoch`] || 0\n\n        const fromLocal = this.dataLocal[name]\n        const fromLocalUpdatedAt = this.dataLocal[`${name}_updated_at_epoch`] || 0\n\n        if(fromLocalUpdatedAt > fromServerUpdatedAt) {\n          this.updateOnServer(name, fromLocal)\n          return fromLocal\n        }\n\n        return fromServer\n      }\n\n      set(name, value) {\n        this.ensurePreferenceExists(name)\n\n        this.dataLocal[name] = value\n        this.dataLocal[`${name}_updated_at_epoch`] = Date.now()\n\n        localStorage.setItem(this.localStorageKey, JSON.stringify(this.dataLocal))\n        this.updateOnServer(name, value)\n        document.dispatchEvent(new CustomEvent('preflex:preference-updated', { detail: { klass: this.klass, name, value } }))\n      }\n\n      updateOnServer(name, value) {\n        fetch(UPDATE_PATH, {\n          method: 'POST',\n          headers: {\n            \"Content-Type\": \"application/json\",\n            \"X-CSRF-TOKEN\": CSRF_TOKEN\n          },\n          body: JSON.stringify({ klass: this.klass, name, value })\n        })\n      }\n\n      ensurePreferenceExists(name) {\n        if(!this.data.hasOwnProperty(name)) {\n          throw new Error(`Preference ${name} was not defined.`)\n        }\n      }\n    }\n  JS\n\n  js = [base]\n  js += preference_klasses.map do |klass|\n    raise 'Expected \#{klass} to be a sub-class of Preflex::Preference' unless klass < Preflex::Preference\n\n    \"window['\#{klass.name}'] = new PreflexPreference('\#{klass.name}', \#{klass.current.data_for_js});\"\n  end\n\n  \"<script>\#{js.join(\"\\n\")}</script>\".html_safe\nend\n"