Implement draft updating thread in /my_account/sign_up/index.html.jst (avoids possibi...
authorNick Downing <nick@ndcode.org>
Tue, 25 Jan 2022 00:47:10 +0000 (11:47 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 25 Jan 2022 00:47:18 +0000 (11:47 +1100)
_lib/navbar.jst
contact/index.html.jst
js/api_call.js.min [deleted file]
js/utils.js.min [new file with mode: 0644]
my_account/index.html.jst
my_account/password_reset/index.html.jst
my_account/send_verification_email/index.html.jst
my_account/sign_up/index.html.jst
my_account/verify_email/index.html.jst
my_account/verify_password/index.html.jst

index 7ec7234..c3e7c18 100644 (file)
@@ -310,7 +310,7 @@ return async (env, head, body, scripts) => {
     },
     // scripts
     async _out => {
-      script(src="/js/api_call.js") {}
+      script(src="/js/utils.js") {}
 
       script {
         // this function can be overridden in a further script
index a6b78a8..fd46d2f 100644 (file)
@@ -142,7 +142,7 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
         let draft_timeout_running = false
diff --git a/js/api_call.js.min b/js/api_call.js.min
deleted file mode 100644 (file)
index bde4a54..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Problem = class {
-  constructor(title, detail, status) {
-    this.title = title
-    this.detail = detail
-    this.status = status
-  }
-
-  static from(error) {
-    return (
-      error instanceof Problem ?
-        error :
-        new Problem('Bad request', (error.stack || error.message), 400)
-    )
-  }
-}
-
-api_call = async (endpoint, ...args) => {
-  let response = await fetch(
-    endpoint,
-    {method: 'POST', body: JSON.stringify(args)}
-  )
-  let result = await response.json()
-  if (!response.ok)
-    throw new Problem(result.title, result.detail, result.status)
-  return result
-}
diff --git a/js/utils.js.min b/js/utils.js.min
new file mode 100644 (file)
index 0000000..b7dd5d2
--- /dev/null
@@ -0,0 +1,93 @@
+Mutex = class {
+  constructor() {
+    this.done = null
+  }
+
+  async acquire() {
+    while (this.done !== null)
+      await this.done.promise
+    let done = {}
+    done.promise = new Promise(
+      (resolve, reject) => {done.resolve = resolve}
+    )
+    this.done = done
+  }
+
+  release() {
+    let done = this.done
+    assert(done !== null)
+    this.done = null
+    done.resolve()
+  }
+}
+
+BinarySemaphore = class {
+  constructor(value) {
+    if (value)
+      this.done = null
+    else {
+      let done = {}
+      done.promise = new Promise(
+        (resolve, reject) => {done.resolve = resolve}
+      )
+      this.done = done
+    }
+  }
+
+  async acquire() {
+    while (this.done !== null)
+      await this.done.promise
+    let done = {}
+    done.promise = new Promise(
+      (resolve, reject) => {done.resolve = resolve}
+    )
+    this.done = done
+  }
+
+  try_acquire() {
+    if (this.done !== null)
+      return false
+    let done = {}
+    done.promise = new Promise(
+      (resolve, reject) => {done.resolve = resolve}
+    )
+    this.done = done
+    return true
+  }
+
+  release() {
+    let done = this.done
+    if (done === null)
+      return false
+    this.done = null
+    done.resolve()
+    return true
+  }
+}
+
+Problem = class {
+  constructor(title, detail, status) {
+    this.title = title
+    this.detail = detail
+    this.status = status
+  }
+
+  static from(error) {
+    return (
+      error instanceof Problem ?
+        error :
+        new Problem('Bad request', (error.stack || error.message), 400)
+    )
+  }
+}
+
+api_call = async (endpoint, ...args) => {
+  let response = await fetch(
+    endpoint,
+    {method: 'POST', body: JSON.stringify(args)}
+  )
+  let result = await response.json()
+  if (!response.ok)
+    throw new Problem(result.title, result.detail, result.status)
+  return result
+}
index 765aaa6..724ed5c 100644 (file)
@@ -207,7 +207,7 @@ return async env => {
       }
 
       if (signed_in_as !== undefined) {
-        //script(src="/js/api_call.js") {}
+        //script(src="/js/utils.js") {}
 
         script {
           let step_1_dirty = ${JSON.stringify(draft_details !== null)}
index b788899..f0ee4cf 100644 (file)
@@ -96,7 +96,7 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
         let step_1 = async () => {
index 03ffbd6..c9fe99b 100644 (file)
@@ -88,7 +88,7 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
         let step_1 = async () => {
index 339458e..060cee5 100644 (file)
@@ -154,29 +154,28 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
-        let draft_timeout_running = false
-        let draft_timeout_handler = async () => {
-          draft_timeout_running = false
-          await api_call(
-            '/api/account/sign_up/set_draft.json',
-            {
-              email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
-              given_names: document.getElementById('given-names').value.slice(0, 256),
-              family_name: document.getElementById('family-name').value.slice(0, 256),
-              contact_me: document.getElementById('contact-me').checked ? true : false
+        let input_semaphore = new BinarySemaphore(false)
+        ;(
+          async () => {
+            while (true) {
+              await input_semaphore.acquire()
+              await new Promise(resolve => setTimeout(resolve, 3000))
+              input_semaphore.try_acquire()
+              await api_call(
+                '/api/account/sign_up/set_draft.json',
+                {
+                  email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
+                  given_names: document.getElementById('given-names').value.slice(0, 256),
+                  family_name: document.getElementById('family-name').value.slice(0, 256),
+                  contact_me: document.getElementById('contact-me').checked ? true : false
+                }
+              )
             }
-          )
-          //console.log('draft', await api_call('/api/account/sign_up/get_draft.json'))
-        }
-        let draft_change_handler = () => {
-          if (!draft_timeout_running) {
-            draft_timeout_running = true
-            setTimeout(draft_timeout_handler, 5000)
           }
-        }
+        )() // ignore returned promise (start thread)
 
         let details
         let card_1 = async () => {
@@ -271,25 +270,29 @@ return async env => {
           'DOMContentLoaded',
           () => {
             document.getElementById('given-names').addEventListener(
-              'change',
-              draft_change_handler
+              'input',
+              () => {input_semaphore.release()}
             )
             document.getElementById('family-name').addEventListener(
-              'change',
-              draft_change_handler
+              'input',
+              () => {input_semaphore.release()}
             )
             document.getElementById('email').addEventListener(
-              'change',
-              draft_change_handler
-            )
-            document.getElementById('password').addEventListener(
-              'change',
-              draft_change_handler
+              'input',
+              () => {input_semaphore.release()}
             )
+            //document.getElementById('password').addEventListener(
+            //  'input',
+            //  () => {input_semaphore.release()}
+            //)
             document.getElementById('contact-me').addEventListener(
-              'change',
-              draft_change_handler
+              'input',
+              () => {input_semaphore.release()}
             )
+            //document.getElementById('verification-code').addEventListener(
+            //  'input',
+            //  () => {input_semaphore.release()}
+            //)
 
             let image_seq = 1
             document.getElementById('card-1-new-code').addEventListener(
index 417dc33..e9b335a 100644 (file)
@@ -102,7 +102,7 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
         let step_1 = async () => {
index 52944be..a7c9925 100644 (file)
@@ -102,7 +102,7 @@ return async env => {
     },
     // scripts
     async _out => {
-      //script(src="/js/api_call.js") {}
+      //script(src="/js/utils.js") {}
 
       script {
         let step_1 = async () => {