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_raw(*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_raw(*preference_klasses)
  return ''.html_safe if preference_klasses.empty?

  base = <<~JS
    const CSRF_TOKEN = "#{Preflex::Current.controller_instance.send(:form_authenticity_token)}"
    const UPDATE_PATH = "#{Preflex::Engine.routes.url_helpers.preferences_path}"
    class PreflexPreference {
      constructor(klass, data) {
        this.klass = klass
        this.localStorageKey = `PreflexPreference-${klass}`

        this.data = data
        this.dataLocal = JSON.parse(localStorage.getItem(this.localStorageKey) || '{}')
      }

      get(name) {
        this.ensurePreferenceExists(name)

        const fromServer = this.data[name]
        const fromServerUpdatedAt = this.data[`${name}_updated_at_epoch`] || 0

        const fromLocal = this.dataLocal[name]
        const fromLocalUpdatedAt = this.dataLocal[`${name}_updated_at_epoch`] || 0

        if(fromLocalUpdatedAt > fromServerUpdatedAt) {
          this.updateOnServer(name, fromLocal)
          return fromLocal
        }

        return fromServer
      }

      set(name, value) {
        this.ensurePreferenceExists(name)

        this.dataLocal[name] = value
        this.dataLocal[`${name}_updated_at_epoch`] = Date.now()

        localStorage.setItem(this.localStorageKey, JSON.stringify(this.dataLocal))
        this.updateOnServer(name, value)
        document.dispatchEvent(new CustomEvent('preflex:preference-updated', { detail: { klass: this.klass, name, value } }))
      }

      updateOnServer(name, value) {
        fetch(UPDATE_PATH, {
          method: 'POST',
          headers: {
            "Content-Type": "application/json",
            "X-CSRF-TOKEN": CSRF_TOKEN
          },
          body: JSON.stringify({ klass: this.klass, name, value })
        })
      }

      ensurePreferenceExists(name) {
        if(!this.data.hasOwnProperty(name)) {
          throw new Error(`Preference ${name} was not defined.`)
        }
      }
    }
  JS

  js = [base]
  js += preference_klasses.map do |klass|
    raise 'Expected #{klass} to be a sub-class of Preflex::Preference' unless klass < Preflex::Preference

    "window['#{klass.name}'] = new PreflexPreference('#{klass.name}', #{klass.current.data_for_js});"
  end

  js.join("\n")
end

#script_tag(*preference_klasses) ⇒ Object



78
79
80
81
82
# File 'app/helpers/preflex/preferences_helper.rb', line 78

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

  "<script data-turbo-eval=\"false\">#{script_raw(*preference_klasses)}</script>".html_safe
end