philomena/assets/js/misc.ts

98 lines
2.8 KiB
TypeScript
Raw Normal View History

2019-10-05 02:09:52 +02:00
/**
* Misc
*/
import store from './utils/store';
import { $, $$, hideEl, showEl } from './utils/dom';
import { assertNotNull, assertType } from './utils/assert';
2024-06-23 19:59:06 +02:00
import '../types/ujs';
2019-10-05 02:09:52 +02:00
let touchMoved = false;
2024-07-04 02:27:59 +02:00
function formResult({ target, detail }: FetchcompleteEvent) {
const elements: Record<string, string> = {
2019-10-05 02:09:52 +02:00
'#description-form': '.image-description',
2024-07-04 02:27:59 +02:00
'#uploader-form': '.image_uploader',
2019-10-05 02:09:52 +02:00
};
function showResult(formEl: HTMLFormElement, resultEl: HTMLElement, response: string) {
2019-10-05 02:09:52 +02:00
resultEl.innerHTML = response;
hideEl(formEl);
showEl(resultEl);
2024-06-23 19:59:06 +02:00
$$<HTMLInputElement | HTMLButtonElement>('input[type="submit"],button', formEl).forEach(button => {
button.disabled = false;
});
2019-10-05 02:09:52 +02:00
}
2024-07-04 02:27:59 +02:00
for (const [formSelector, resultSelector] of Object.entries(elements)) {
if (target.matches(formSelector)) {
const form = assertType(target, HTMLFormElement);
const result = assertNotNull($<HTMLElement>(resultSelector));
detail.text().then(text => showResult(form, result, text));
2024-06-23 19:59:06 +02:00
}
2019-10-05 02:09:52 +02:00
}
}
2024-06-23 19:59:06 +02:00
function revealSpoiler(event: MouseEvent | TouchEvent) {
const target = assertNotNull(event.target) as HTMLElement;
2019-10-05 02:09:52 +02:00
const spoiler = target.closest('.spoiler');
const showContainer = target.closest('.image-show-container');
2024-06-23 19:59:06 +02:00
let imgspoiler = target.closest('.spoiler .imgspoiler, .spoiler-revealed .imgspoiler');
2019-10-05 02:09:52 +02:00
// Prevent reveal if touchend came after touchmove event
if (touchMoved) {
touchMoved = false;
return;
}
if (spoiler) {
if (showContainer) {
2024-06-23 19:59:06 +02:00
const imageShow = assertNotNull(showContainer.querySelector('.image-show'));
2019-10-05 02:09:52 +02:00
if (!imageShow.classList.contains('hidden') && imageShow.classList.contains('spoiler-pending')) {
imageShow.classList.remove('spoiler-pending');
return;
}
}
spoiler.classList.remove('spoiler');
spoiler.classList.add('spoiler-revealed');
// Prevent click-through to links on mobile platforms
if (event.type === 'touchend') event.preventDefault();
if (!imgspoiler) {
imgspoiler = spoiler.querySelector('.imgspoiler');
}
}
if (imgspoiler) {
imgspoiler.classList.remove('imgspoiler');
imgspoiler.classList.add('imgspoiler-revealed');
2024-06-23 19:59:06 +02:00
2019-10-05 02:09:52 +02:00
if (event.type === 'touchend' && !event.defaultPrevented) {
event.preventDefault();
}
}
}
2024-06-23 19:59:06 +02:00
export function setupEvents() {
const extrameta = $<HTMLElement>('#extrameta');
if (extrameta && store.get('hide_uploader')) {
hideEl(extrameta);
2024-06-23 19:59:06 +02:00
}
2019-10-05 02:09:52 +02:00
2020-12-16 15:35:58 +01:00
if (store.get('hide_score')) {
$$<HTMLElement>('.upvotes,.score,.downvotes').forEach(s => hideEl(s));
2020-12-16 15:35:58 +01:00
}
2019-10-05 02:09:52 +02:00
document.addEventListener('fetchcomplete', formResult);
document.addEventListener('click', revealSpoiler);
document.addEventListener('touchend', revealSpoiler);
2024-07-04 02:27:59 +02:00
document.addEventListener('touchmove', () => {
touchMoved = true;
});
2019-10-05 02:09:52 +02:00
}