forget-cancellare-vecchi-toot/assets/settings.js

192 lines
6.4 KiB
JavaScript
Raw Normal View History

2017-08-31 18:59:09 +02:00
import Banner from '../components/Banner.html';
(function settings_init(){
2017-08-12 01:04:22 +02:00
if(!('fetch' in window)){
return;
}
let status_timeout = null;
let settings_section = document.querySelector('#settings-section');
2017-09-16 09:28:39 +02:00
let form = document.querySelector('form[name=settings]');
let inputs = Array.from(form.elements)
2017-08-29 18:38:54 +02:00
let backoff_level = 0;
2017-08-12 01:04:22 +02:00
2017-08-31 18:59:09 +02:00
let banner_el = document.querySelector('.main-banner');
banner_el.innerHTML = '';
let banner = new Banner({
target: banner_el,
});
2017-08-12 01:04:22 +02:00
function hide_status(){
status_display.classList.remove('error', 'success', 'saving');
status_display.classList.add('hidden');
status_display.innerHTML='';
}
2017-08-29 18:38:54 +02:00
function show_error(){
2017-08-12 01:04:22 +02:00
hide_status();
status_display.textContent='Could not save. Retrying...';
status_display.classList.add('error');
status_display.classList.remove('hidden');
}
function show_success(){
hide_status();
status_display.textContent='Saved!';
status_display.classList.add('success');
status_display.classList.remove('hidden');
}
2017-08-29 18:38:54 +02:00
function show_still_saving(){
status_display.textContent='Still saving...';
}
2017-08-12 01:04:22 +02:00
function show_saving(){
hide_status();
status_display.textContent='Saving...';
status_display.classList.add('saving');
status_display.classList.remove('hidden');
status_timeout = setTimeout(show_still_saving, 5000);
}
2017-08-19 13:11:16 +02:00
function save(){
2017-08-12 01:04:22 +02:00
hide_status();
clearTimeout(status_timeout);
status_timeout = setTimeout(show_saving, 70);
2017-08-29 18:38:54 +02:00
let promise = send_settings(get_all_inputs())
.then(() => {
2017-08-12 01:04:22 +02:00
show_success();
clearTimeout(status_timeout);
status_timeout = setTimeout(hide_status, 3000);
backoff_level = 0;
2017-08-12 01:52:33 +02:00
});
2017-08-29 18:38:54 +02:00
promise.catch(() => {
show_error();
clearTimeout(status_timeout);
status_timeout = setTimeout(save, Math.pow(2, backoff_level)*1000);
backoff_level += 1;
backoff_level = Math.min(backoff_level, 5);
});
promise.then(fetch_viewer).then(update_viewer);
2017-08-12 01:04:22 +02:00
// remove server-rendered banner
let banner = settings_section.querySelector('.banner');
if(banner){
settings_section.removeChild(banner);
}
}
function get_all_inputs(){
2017-08-29 18:38:54 +02:00
let o = Object();
2017-09-16 09:28:39 +02:00
for(let input of inputs){
2017-08-12 01:04:22 +02:00
if(input.type != 'radio' || input.checked){
o[input.name] = input.value;
}
}
2017-08-29 18:38:54 +02:00
return o;
2017-08-12 01:04:22 +02:00
}
function send_settings(body){
return fetch('/api/settings', {
method:'PUT',
credentials:'same-origin',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(body)
})
.then(resp => {
if(!resp.ok){ return Promise.reject(resp); }
return resp; })
2017-08-12 01:04:22 +02:00
.then(resp => resp.json())
.then(data => {
2017-08-29 18:38:54 +02:00
if(data.status == 'error'){ return Promise.reject(data); }
return data;
2017-08-12 01:04:22 +02:00
});
}
2017-09-16 09:28:39 +02:00
for(let input of inputs){
2017-08-19 13:11:16 +02:00
input.addEventListener('change', save);
2017-08-12 01:04:22 +02:00
}
// remove submit button since we're doing live updates
let submit = form.querySelector('input[type=submit]');
form.removeChild(submit);
2017-09-16 09:28:39 +02:00
inputs.splice(inputs.indexOf(submit), 1);
2017-08-12 01:04:22 +02:00
let status_display = document.createElement('span');
status_display.classList.add('status-display', 'hidden');
settings_section.insertBefore(status_display, settings_section.childNodes[0]);
2017-08-12 01:04:22 +02:00
// silently send_settings in case the user changed settings while the page was loading
send_settings(get_all_inputs());
2017-08-12 01:52:33 +02:00
let viewer_update_interval = 1500;
function fetch_viewer(){
viewer_update_interval *= 2;
viewer_update_interval = Math.min(30000, viewer_update_interval);
2017-08-12 01:52:33 +02:00
return fetch('/api/viewer', {
credentials: 'same-origin',
})
.then(resp => {
if(!resp.ok){
if(resp.status == 403){
// user was logged out in another client
window.location = '/';
}
return Promise.reject(resp);
}
return resp; })
2017-08-12 01:52:33 +02:00
.then(resp => resp.json());
}
2017-08-29 18:38:54 +02:00
let last_viewer = {};
function update_viewer(viewer){
2017-08-31 18:59:09 +02:00
if(last_viewer == JSON.stringify(viewer)){
2017-08-29 18:38:54 +02:00
return;
}
2017-08-31 18:59:09 +02:00
last_viewer = JSON.stringify(viewer);
document.querySelector('#post-count').textContent = viewer.post_count;
document.querySelector('#eligible-estimate').textContent = viewer.eligible_for_delete_estimate;
2017-08-18 22:33:22 +02:00
document.querySelector('#display-name').textContent = viewer.display_name || viewer.screen_name;
2017-08-29 17:06:44 +02:00
document.querySelector('#display-name').title = '@' + viewer.screen_name;
document.querySelector('#avatar').src = viewer.avatar_url;
viewer_update_interval = 1500;
2017-08-31 18:59:09 +02:00
2017-08-31 21:55:26 +02:00
if(viewer.next_delete){
viewer.next_delete = new Date(viewer.next_delete);
}
if(viewer.last_delete){
viewer.last_delete = new Date(viewer.last_delete);
}
2017-08-31 18:59:09 +02:00
banner.set(viewer);
2017-08-12 01:52:33 +02:00
}
2017-08-31 18:59:09 +02:00
update_viewer(JSON.parse(document.querySelector('script[data-viewer]').textContent))
function set_viewer_timeout(){
setTimeout(() => fetch_viewer().then(update_viewer).then(set_viewer_timeout, set_viewer_timeout),
viewer_update_interval);
}
set_viewer_timeout();
2017-08-31 18:59:09 +02:00
banner.on('toggle', enabled => {
send_settings({policy_enabled: enabled}).then(fetch_viewer).then(update_viewer);
2017-08-31 18:59:09 +02:00
// TODO show error or spinner if it takes over a second
})
let reason_banner = document.querySelector('.banner[data-reason]');
if(reason_banner){
let dismiss = reason_banner.querySelector('input[type=submit]');
dismiss.addEventListener('click', e => {
e.preventDefault();
// we don't care if this succeeds or fails. worst
// case scenario the banner appears again on a future page load
fetch('/api/reason', {method: 'DELETE', credentials:'same-origin'});
reason_banner.parentElement.removeChild(reason_banner);
})
}
})();