mirror of
https://github.com/ClaperCo/Claper.git
synced 2026-07-10 04:24:14 +02:00
commit7db48f592fAuthor: Alex Lion <dev@alexandrelion.com> Date: Fri Jun 5 10:16:10 2026 +0200 Update changelog commit3039b70edcAuthor: Peter Rundqvist <47314226+pete1854@users.noreply.github.com> Date: Fri Jun 5 10:11:07 2026 +0200 Add swedish translation (#228) * Initial translation * Initial error msg translation * Fixes suggested by Copilot. * Fixed spacing before ! and ? * Added missing provider translation. * Upddated translation for "Unpin" * Added missing Content-Type header. commitd18e5d7c32Author: fgallarday <fgallarday@users.noreply.github.com> Date: Fri Jun 5 03:07:25 2026 -0500 Add PageUp and PageDown slide navigation support (#227) commit24e18c2764Author: Alex Lion <dev@alexandrelion.com> Date: Fri Jun 5 10:06:54 2026 +0200 Bump version to 2.5.2 commitd5df9a73f8Author: Alex Lion <dev@alexandrelion.com> Date: Fri May 8 22:42:04 2026 +0200 Fix form submissions losing values when field names contain spaces or non-word characters commit57596952d4Author: Alex Lion <dev@alexandrelion.com> Date: Fri May 8 14:50:33 2026 +0200 Update package-lock.json: add asset name, upgrade dependencies, and remove unused packages commite246530c23Author: Alex Lion <dev@alexandrelion.com> Date: Fri May 8 14:34:53 2026 +0200 Bump version to 2.5.1 commit534d915782Author: Alex Lion <dev@alexandrelion.com> Date: Fri May 8 10:55:38 2026 +0200 Handle Ecto.NoResultsError in event retrieval and redirect with error message commitb762e21325Author: Alex Lion <dev@alexandrelion.com> Date: Fri May 8 10:47:01 2026 +0200 Fix crash on event manager pages when an event has multiple activity leaders commit153cadb42bAuthor: alxlion <dev@alexandrelion.com> Date: Wed Apr 29 13:42:05 2026 +0000 Fix presentation views without slide count commit3cfb3cab7fAuthor: alxlion <dev@alexandrelion.com> Date: Wed Apr 29 13:16:48 2026 +0000 Fix event code normalization validation
186 lines
5.2 KiB
JavaScript
186 lines
5.2 KiB
JavaScript
import { tns } from "tiny-slider";
|
|
|
|
export class Manager {
|
|
constructor(context) {
|
|
this.context = context;
|
|
this.currentPage = parseInt(context.el.dataset.currentPage);
|
|
this.maxPage = parseInt(context.el.dataset.maxPage);
|
|
|
|
localStorage.setItem("slide-position", this.currentPage);
|
|
}
|
|
|
|
init() {
|
|
this.context.handleEvent("page-manage", (data) => {
|
|
var el = document.getElementById("slide-preview-" + data.current_page);
|
|
|
|
if (el) {
|
|
setTimeout(
|
|
() => {
|
|
const slidesLayout = document.getElementById("slides-layout");
|
|
const layoutWidth = slidesLayout.clientWidth;
|
|
const elementWidth = el.children[0].scrollWidth;
|
|
const scrollPosition =
|
|
el.children[0].offsetLeft - layoutWidth / 2 + elementWidth / 2;
|
|
|
|
slidesLayout.scrollTo({
|
|
left: scrollPosition,
|
|
});
|
|
},
|
|
data.timeout ? data.timeout : 0
|
|
);
|
|
}
|
|
});
|
|
|
|
window.addEventListener("keydown", (e) => {
|
|
if ((e.target.tagName || "").toLowerCase() != "input") {
|
|
|
|
switch (e.key) {
|
|
case "ArrowLeft":
|
|
case "PageUp":
|
|
e.preventDefault();
|
|
this.prevPage();
|
|
break;
|
|
case "ArrowRight":
|
|
case "PageDown":
|
|
e.preventDefault();
|
|
this.nextPage();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
this.initPreview();
|
|
}
|
|
|
|
initPreview() {
|
|
var preview = document.getElementById("preview");
|
|
|
|
if (preview) {
|
|
let isDragging = false;
|
|
let startX, startY;
|
|
|
|
let originalSnap = localStorage.getItem("preview-position");
|
|
if (originalSnap) {
|
|
let snaps = originalSnap.split(":");
|
|
const windowWidth = window.innerWidth;
|
|
const windowHeight = window.innerHeight;
|
|
const previewWidth = preview.offsetWidth;
|
|
const previewHeight = preview.offsetHeight;
|
|
|
|
const left = Math.min(Math.max(parseInt(snaps[0]), 0), windowWidth - previewWidth);
|
|
const top = Math.min(Math.max(parseInt(snaps[1]), 0), windowHeight - previewHeight);
|
|
|
|
preview.style.left = `${left}px`;
|
|
preview.style.top = `${top}px`;
|
|
}
|
|
|
|
const startDrag = (e) => {
|
|
isDragging = true;
|
|
startX = (e.clientX || e.touches[0].clientX) - preview.offsetLeft;
|
|
startY = (e.clientY || e.touches[0].clientY) - preview.offsetTop;
|
|
};
|
|
|
|
const drag = (e) => {
|
|
if (!isDragging) return;
|
|
|
|
e.preventDefault();
|
|
|
|
const clientX = e.clientX || e.touches[0].clientX;
|
|
const clientY = e.clientY || e.touches[0].clientY;
|
|
|
|
const newX = clientX - startX;
|
|
const newY = clientY - startY;
|
|
|
|
preview.style.left = `${newX}px`;
|
|
preview.style.top = `${newY}px`;
|
|
};
|
|
|
|
const endDrag = () => {
|
|
if (!isDragging) return;
|
|
isDragging = false;
|
|
|
|
const windowWidth = window.innerWidth;
|
|
const windowHeight = window.innerHeight;
|
|
const previewRect = preview.getBoundingClientRect();
|
|
const padding = 20; // Add 20px padding
|
|
|
|
let snapX, snapY;
|
|
|
|
if (previewRect.left < windowWidth / 2) {
|
|
snapX = padding;
|
|
} else {
|
|
snapX = windowWidth - previewRect.width - padding;
|
|
}
|
|
|
|
if (previewRect.top < windowHeight / 2) {
|
|
snapY = padding;
|
|
} else {
|
|
snapY = windowHeight - previewRect.height - padding;
|
|
}
|
|
|
|
preview.style.transition = "left 0.3s ease-out, top 0.3s ease-out";
|
|
preview.style.left = `${snapX}px`;
|
|
preview.style.top = `${snapY}px`;
|
|
|
|
localStorage.setItem("preview-position", `${snapX}:${snapY}`);
|
|
|
|
// Remove the transition after it's complete
|
|
setTimeout(() => {
|
|
preview.style.transition = "";
|
|
}, 300);
|
|
};
|
|
|
|
preview.addEventListener("mousedown", startDrag);
|
|
preview.addEventListener("touchstart", startDrag);
|
|
|
|
document.addEventListener("mousemove", drag);
|
|
document.addEventListener("touchmove", drag);
|
|
|
|
document.addEventListener("mouseup", endDrag);
|
|
document.addEventListener("touchend", endDrag);
|
|
}
|
|
}
|
|
|
|
update() {
|
|
this.currentPage = parseInt(this.context.el.dataset.currentPage);
|
|
var el = document.getElementById("slide-preview-" + this.currentPage);
|
|
|
|
if (el) {
|
|
setTimeout(() => {
|
|
const slidesLayout = document.getElementById("slides-layout");
|
|
const layoutWidth = slidesLayout.clientWidth;
|
|
const elementWidth = el.children[0].scrollWidth;
|
|
const scrollPosition =
|
|
el.children[0].offsetLeft - layoutWidth / 2 + elementWidth / 2;
|
|
|
|
slidesLayout.scrollTo({
|
|
left: scrollPosition,
|
|
behavior: "smooth",
|
|
});
|
|
}, 50);
|
|
}
|
|
|
|
this.initPreview();
|
|
}
|
|
|
|
nextPage() {
|
|
if (this.currentPage == this.maxPage - 1) return;
|
|
|
|
this.currentPage += 1;
|
|
localStorage.setItem("slide-position", this.currentPage);
|
|
this.context.pushEventTo(this.context.el, "current-page", {
|
|
page: this.currentPage.toString(),
|
|
});
|
|
}
|
|
|
|
prevPage() {
|
|
if (this.currentPage == 0) return;
|
|
|
|
this.currentPage -= 1;
|
|
localStorage.setItem("slide-position", this.currentPage);
|
|
this.context.pushEventTo(this.context.el, "current-page", {
|
|
page: this.currentPage.toString(),
|
|
});
|
|
}
|
|
}
|