return async (env, head, body, scripts) => {
//let cart = await _require('/online_store/cart.jst')
+ let fa_arrow_circle_left = await env.site.get_min_svg('/_svg/fa_arrow-circle-left.svg')
+ let fa_times_circle = await env.site.get_min_svg('/_svg/fa_times-circle.svg')
+ let fa_envelope = await env.site.get_min_svg('/_svg/fa_envelope.svg')
+ let fa_unlock_alt = await env.site.get_min_svg('/_svg/fa_unlock-alt.svg')
let fa_search = await env.site.get_min_svg('/_svg/fa_search.svg')
let get_session = await _require('/_lib/get_session.jst')
//let icon_cart_small = await env.site.get_min_svg('/_svg/icon_cart_small.svg')
+ let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
+ //let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
let logo_large = await env.site.get_min_svg('/_svg/logo_large.svg')
let menu = await env.site.get_menu('/_menu.json')
let page = await _require('/_lib/page.jst')
let transaction = await env.site.database.Transaction()
let signed_in_as
let site_title, copyright
+ let feedback_draft
try {
let root = await transaction.get({})
let globals = await root.get('globals', {})
site_title = await globals.get_json('site_title')
copyright = await globals.get_json('copyright')
+
+ feedback_draft = await session.get_json('feedback_draft')
+ if (feedback_draft === undefined || env.now >= feedback_draft.expires)
+ feedback_draft = null
}
finally {
transaction.rollback()
div.col-md-12 {
div.form-group {
label.form-label(for="navbar-sign-in-email") {'Email'}
- input.form-control#navbar-sign-in-email(type="text" placeholder="Account email address" required="required" maxlength=256) {}
+ input.form-control#navbar-sign-in-email(type="text" placeholder="Account email address" required maxlength=256) {}
}
}
}
div.col-md-12 {
div.form-group {
label.form-label(for="navbar-sign-in-password") {'Password'}
- input.form-control#navbar-sign-in-password(type="password" placeholder="Account password" required="required" minlength=8 maxlength=256) {}
+ input.form-control#navbar-sign-in-password(type="password" placeholder="Account password" required minlength=8 maxlength=256) {}
}
}
}
}
div.modal-footer {
button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
- 'Cancel'
+ div.icon24-outer.mr-2 {
+ div.icon24-inner {_out.push(fa_arrow_circle_left)}
+ }
+ 'Back'
}
button.btn.btn-primary#navbar-sign-in-submit(type="button") {
+ div.icon24-outer.mr-2 {
+ div.icon24-inner {_out.push(fa_unlock_alt)}
+ }
'Sign in'
}
}
p {
'Did you notice something not quite right, or just want to share your impression of this page?'
}
- div.row {
- div.col-md-12 {
- div.form-group {
- label.form-label(for="navbar-feedback-message") {'Message'}
- textarea.form-control#navbar-feedback-message(placeholder="Please tell us your thoughts" required="required" rows=4 maxlength=65536) {}
+
+ form#navbar-feedback-form {
+ div.row {
+ div.col-md-12 {
+ div.form-group {
+ label.form-label(for="navbar-feedback-message1") {'Message'}
+ textarea.form-control#navbar-feedback-message1(placeholder="I noticed that..." required rows=4 maxlength=65536) {
+ if (feedback_draft)
+ `${feedback_draft.message}`
+ }
+ div.invalid-feedback {'Please let us have your thoughts.'}
+ }
}
}
}
+
+ p.'mt-3'.mb-0#navbar-feedback-message(hidden) {}
}
div.modal-footer {
button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
- 'Cancel'
- }
- button.btn.btn-primary#navbar-feedback-submit(type="button") {
- 'Submit'
+ div.icon24-outer.mr-2 {
+ div.icon24-inner {_out.push(fa_arrow_circle_left)}
+ }
+ 'Back'
}
+ if (feedback_draft)
+ button.btn.btn-primary#navbar-feedback-send-message(type="button") {
+ div.icon24-outer.mr-2#navbar-feedback-icon {
+ div.icon24-inner {_out.push(fa_envelope)}
+ }
+ //div.icon24-outer.mr-2#navbar-feedback-tick(hidden) {
+ // div.icon24-inner {_out.push(icon_tick)}
+ //}
+ div.icon24-outer.mr-2#navbar-feedback-cross(hidden) {
+ div.icon24-inner {_out.push(icon_cross)}
+ }
+ div.icon24-outer.mr-2#navbar-feedback-spinner(hidden) {
+ div.icon24-inner {
+ div.spinner-border.spinner-border-sm(role="status") {}
+ }
+ }
+ 'Send message'
+ }
+ else
+ button.btn.btn-primary#navbar-feedback-send-message(type="button" disabled) {
+ div.icon24-outer.mr-2#navbar-feedback-icon {
+ div.icon24-inner {_out.push(fa_envelope)}
+ }
+ //div.icon24-outer.mr-2#navbar-feedback-tick(hidden) {
+ // div.icon24-inner {_out.push(icon_tick)}
+ //}
+ div.icon24-outer.mr-2#navbar-feedback-cross(hidden) {
+ div.icon24-inner {_out.push(icon_cross)}
+ }
+ div.icon24-outer.mr-2#navbar-feedback-spinner(hidden) {
+ div.icon24-inner {
+ div.spinner-border.spinner-border-sm(role="status") {}
+ }
+ }
+ 'Send message'
+ }
}
}
}
}
div.modal-footer {
button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
+ div.icon24-outer.mr-2 {
+ div.icon24-inner {_out.push(fa_times_circle)}
+ }
'Close'
}
}
document.addEventListener(
'DOMContentLoaded',
() => {
+ let id_navbar_feedback_cross = document.getElementById('navbar-feedback-cross')
+ let id_navbar_feedback_form = document.getElementById('navbar-feedback-form')
+ let id_navbar_feedback_icon = document.getElementById('navbar-feedback-icon')
let id_navbar_feedback_message = document.getElementById('navbar-feedback-message')
+ let id_navbar_feedback_message1 = document.getElementById('navbar-feedback-message1')
let id_navbar_feedback_modal = document.getElementById('navbar-feedback-modal')
- let id_navbar_feedback_submit = document.getElementById('navbar-feedback-submit')
+ let id_navbar_feedback_send_message = document.getElementById('navbar-feedback-send-message')
+ let id_navbar_feedback_spinner = document.getElementById('navbar-feedback-spinner')
+ //let id_navbar_feedback_tick = document.getElementById('navbar-feedback-tick')
let id_navbar_give_feedback = document.getElementById('navbar-give-feedback')
let id_navbar_message_modal = document.getElementById('navbar-message-modal')
let id_navbar_message_modal_message = document.getElementById('navbar-message-modal-message')
id_navbar_give_feedback.addEventListener(
'click',
() => {
- id_navbar_feedback_message.value = ''
+ // hack to move cursor to end of textarea
+ let temp = id_navbar_feedback_message1.value
+ id_navbar_feedback_message1.value = ''
+ id_navbar_feedback_message1.value = temp
+
$('#navbar-feedback-modal').modal('show')
return false
}
$('#navbar-feedback-modal').on(
'shown.bs.modal',
- () => {id_navbar_feedback_message.focus()}
+ () => {id_navbar_feedback_message1.focus()}
)
- id_navbar_feedback_submit.addEventListener(
+ let feedback_input_semaphore = new BinarySemaphore(false)
+ ;(
+ async () => {
+ while (true) {
+ await feedback_input_semaphore.acquire()
+ await new Promise(resolve => setTimeout(resolve, 3000))
+ feedback_input_semaphore.try_acquire()
+ await api_call(
+ '/api/feedback/set_draft.json',
+ id_navbar_feedback_message1.value.length === 0 ?
+ null :
+ {
+ message: id_navbar_feedback_message1.value.slice(0, 65536)
+ }
+ )
+ }
+ }
+ )() // ignore returned promise (start thread)
+
+ let feedback_edited = () => {
+ feedback_input_semaphore.release()
+
+ id_navbar_feedback_send_message.disabled =
+ id_navbar_feedback_message1.value.length === 0
+ id_navbar_feedback_icon.hidden = false
+ //id_navbar_feedback_tick.hidden = true
+ id_navbar_feedback_cross.hidden = true
+ id_navbar_feedback_spinner.hidden = true
+ id_navbar_feedback_message.hidden = true
+ }
+
+ id_navbar_feedback_message1.addEventListener(
+ 'input',
+ feedback_edited
+ )
+
+ id_navbar_feedback_send_message.addEventListener(
'click',
async () => {
+ id_navbar_feedback_icon.hidden = false
+ //id_navbar_feedback_tick.hidden = true
+ id_navbar_feedback_cross.hidden = true
+ id_navbar_feedback_spinner.hidden = true
+ // the below causes an ugly flicker, so just keep the message
+ //id_navbar_feedback_message.hidden = true
+
+ if (!id_navbar_feedback_form.checkValidity()) {
+ id_navbar_feedback_form.classList.add('was-validated');
+
+ id_navbar_feedback_icon.hidden = true
+ id_navbar_feedback_cross.hidden = false
+ return
+ }
+ id_navbar_feedback_form.classList.remove('was-validated');
+
+ id_navbar_feedback_icon.hidden = true
+ id_navbar_feedback_spinner.hidden = false
try {
await api_call(
- '/api/feedback.json',
+ '/api/feedback/send_message.json',
location.href,
- id_navbar_feedback_message.value.slice(0, 65536)
+ id_navbar_feedback_message1.value.slice(0, 65536)
)
}
catch (error) {
let problem = Problem.from(error)
- id_navbar_message_modal_message.textContent = problem.detail
- $('#navbar-feedback-modal').modal('hide')
- $('#navbar-message-modal').modal('show')
+ id_navbar_feedback_cross.hidden = false
+ id_navbar_feedback_spinner.hidden = true
+
+ id_navbar_feedback_message.textContent = problem.detail
+ //id_navbar_feedback_message.classList.remove('text-success')
+ id_navbar_feedback_message.classList.add('text-danger')
+ id_navbar_feedback_message.hidden = false
return
}
-
+ //id_navbar_feedback_tick.hidden = false
+ //id_navbar_feedback_spinner.hidden = true
+ //id_navbar_feedback_message.textContent = 'We have received your message. We will be in touch as soon as possible.'
+ //id_navbar_feedback_message.classList.add('text-success')
+ //id_navbar_feedback_message.classList.remove('text-danger')
+ //id_navbar_feedback_message.hidden = false
+
+ id_navbar_feedback_icon.hidden = false
+ id_navbar_feedback_spinner.hidden = true
+ id_navbar_feedback_message.hidden = true
id_navbar_message_modal_message.textContent = 'Thanks! We have received your feedback.'
$('#navbar-feedback-modal').modal('hide')
$('#navbar-message-modal').modal('show')