mirror of
https://github.com/hkalexling/Mango.git
synced 2025-08-02 10:55:30 -04:00
162 lines
3.7 KiB
JavaScript
162 lines
3.7 KiB
JavaScript
$(() => {
|
|
getPages();
|
|
|
|
$('#page-select').change(() => {
|
|
const p = parseInt($('#page-select').val());
|
|
toPage(p);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Set an alpine.js property
|
|
*
|
|
* @function setProp
|
|
* @param {string} key - Key of the data property
|
|
* @param {*} prop - The data property
|
|
*/
|
|
const setProp = (key, prop) => {
|
|
$('#root').get(0).__x.$data[key] = prop;
|
|
};
|
|
|
|
/**
|
|
* Get dimension of the pages in the entry from the API and update the view
|
|
*/
|
|
const getPages = () => {
|
|
$.get(`${base_url}api/dimensions/${tid}/${eid}`)
|
|
.then(data => {
|
|
if (!data.success && data.error)
|
|
throw new Error(resp.error);
|
|
const dimensions = data.dimensions;
|
|
|
|
const items = dimensions.map((d, i) => {
|
|
return {
|
|
id: i + 1,
|
|
url: `${base_url}api/page/${tid}/${eid}/${i+1}`,
|
|
width: d.width,
|
|
height: d.height
|
|
};
|
|
});
|
|
|
|
setProp('items', items);
|
|
setProp('loading', false);
|
|
|
|
waitForPage(items.length, () => {
|
|
toPage(page);
|
|
setupScroller();
|
|
});
|
|
})
|
|
.catch(e => {
|
|
const errMsg = `Failed to get the page dimensions. ${e}`;
|
|
console.error(e);
|
|
setProp('alertClass', 'uk-alert-danger');
|
|
setProp('msg', errMsg);
|
|
})
|
|
};
|
|
|
|
/**
|
|
* Jump to a specific page
|
|
*
|
|
* @function toPage
|
|
* @param {number} idx - One-based index of the page
|
|
*/
|
|
const toPage = (idx) => {
|
|
$(`#${idx}`).get(0).scrollIntoView(true);
|
|
UIkit.modal($('#modal-sections')).hide();
|
|
};
|
|
|
|
/**
|
|
* Check if a page exists every 100ms. If so, invoke the callback function.
|
|
*
|
|
* @function waitForPage
|
|
* @param {number} idx - One-based index of the page
|
|
* @param {function} cb - Callback function
|
|
*/
|
|
const waitForPage = (idx, cb) => {
|
|
if ($(`#${idx}`).length > 0) return cb();
|
|
setTimeout(() => {
|
|
waitForPage(idx, cb)
|
|
}, 100);
|
|
};
|
|
|
|
/**
|
|
* Show the control modal
|
|
*
|
|
* @function showControl
|
|
* @param {object} event - The onclick event that triggers the function
|
|
*/
|
|
const showControl = (event) => {
|
|
const idx = parseInt($(event.currentTarget).attr('id'));
|
|
const pageCount = $('#page-select > option').length;
|
|
const progressText = `Progress: ${idx}/${pageCount} (${(idx/pageCount * 100).toFixed(1)}%)`;
|
|
$('#progress-label').text(progressText);
|
|
$('#page-select').val(idx);
|
|
UIkit.modal($('#modal-sections')).show();
|
|
}
|
|
|
|
/**
|
|
* Redirect to a URL
|
|
*
|
|
* @function redirect
|
|
* @param {string} url - The target URL
|
|
*/
|
|
const redirect = (url) => {
|
|
window.location.replace(url);
|
|
}
|
|
|
|
/**
|
|
* Replace the address bar history and save th ereading progress if necessary
|
|
*
|
|
* @function replaceHistory
|
|
* @param {number} idx - One-based index of the current page
|
|
*/
|
|
const replaceHistory = (idx) => {
|
|
const ary = window.location.pathname.split('/');
|
|
ary[ary.length - 1] = idx;
|
|
ary.shift(); // remove leading `/`
|
|
ary.unshift(window.location.origin);
|
|
const url = ary.join('/');
|
|
saveProgress(idx);
|
|
history.replaceState(null, "", url);
|
|
}
|
|
|
|
/**
|
|
* Set up the scroll handler that calls `replaceHistory` when an image
|
|
* enters the view port
|
|
*
|
|
* @function setupScroller
|
|
*/
|
|
const setupScroller = () => {
|
|
$('#root img').each((idx, el) => {
|
|
$(el).on('inview', (event, inView) => {
|
|
if (inView) {
|
|
const current = $(event.currentTarget).attr('id');
|
|
replaceHistory(current);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
let lastSavedPage = page;
|
|
|
|
/**
|
|
* Update the backend reading progress if the current page is more than
|
|
* five pages away from the last saved page
|
|
*
|
|
* @function saveProgress
|
|
* @param {number} idx - One-based index of the page
|
|
*/
|
|
const saveProgress = (idx) => {
|
|
if (Math.abs(idx - lastSavedPage) < 5) return;
|
|
lastSavedPage = idx;
|
|
|
|
const url = `${base_url}api/progress/${tid}/${idx}?${$.param({entry: eid})}`;
|
|
$.post(url)
|
|
.then(data => {
|
|
if (data.error) throw new Error(data.error);
|
|
})
|
|
.catch(e => {
|
|
console.error(e);
|
|
alert('danger', e);
|
|
});
|
|
};
|