Notes/src/public/app/widgets/mobile_widgets/sidebar_container.js

98 lines
3.1 KiB
JavaScript
Raw Normal View History

import FlexContainer from "../containers/flex_container.js";
2025-01-04 00:20:22 +02:00
const DRAG_STATE_NONE = 0;
const DRAG_STATE_INITIAL_DRAG = 1;
const DRAG_STATE_DRAGGING = 2;
export default class SidebarContainer extends FlexContainer {
constructor(screenName, direction) {
super(direction);
this.screenName = screenName;
this.currentTranslate = -100;
2025-01-04 00:20:22 +02:00
this.dragState = DRAG_STATE_NONE;
}
doRender() {
super.doRender();
this.$widget.on("click", () => {
this.triggerCommand('setActiveScreen', {
screen: "detail"
});
});
2025-01-04 00:22:16 +02:00
document.addEventListener("touchstart", (e) => this.#onDragStart(e));
document.addEventListener("touchmove", (e) => this.#onDragMove(e), { passive: false });
document.addEventListener("touchend", (e) => this.#onDragEnd(e));
}
#onDragStart(e) {
if (!this.sidebarContainer) {
this.sidebarContainer = document.getElementById("mobile-sidebar-container");
this.sidebarWrapper = document.getElementById("mobile-sidebar-wrapper");
}
const x = e.touches ? e.touches[0].clientX : e.clientX;
2025-01-04 00:25:59 +02:00
if (x > 30 && this.currentTranslate === -100) {
return;
}
this.startX = x;
2025-01-04 00:20:22 +02:00
this.dragState = DRAG_STATE_INITIAL_DRAG;
}
#onDragMove(e) {
2025-01-04 00:20:22 +02:00
if (this.dragState === DRAG_STATE_NONE) {
return;
}
const x = e.touches ? e.touches[0].clientX : e.clientX;
const deltaX = x - this.startX;
2025-01-04 00:20:22 +02:00
if (this.dragState === DRAG_STATE_INITIAL_DRAG) {
2025-01-04 00:25:59 +02:00
if (Math.abs(deltaX) > 5) {
2025-01-04 00:20:22 +02:00
this.sidebarContainer.style.zIndex = 1000;
this.originalTransition = this.sidebarWrapper.style.transition;
this.sidebarWrapper.style.transition = "none";
this.dragState = DRAG_STATE_DRAGGING;
}
} else if (this.dragState === DRAG_STATE_DRAGGING) {
const width = this.sidebarWrapper.offsetWidth;
const translatePercentage = Math.min(0, Math.max(this.currentTranslate + (deltaX / width) * 100, -100));
this.translatePercentage = translatePercentage;
this.sidebarWrapper.style.transform = `translateX(${translatePercentage}%)`;
}
e.preventDefault();
}
#onDragEnd(e) {
2025-01-04 00:20:22 +02:00
if (this.dragState === DRAG_STATE_NONE) {
return;
}
const isOpen = this.translatePercentage > -50;
this.sidebarWrapper.classList.toggle("show", isOpen);
this.sidebarWrapper.style.transform = isOpen ? 'translateX(0)' : 'translateX(-100%)';
this.sidebarWrapper.style.transition = this.originalTransition;
this.currentTranslate = isOpen ? 0 : -100;
if (!isOpen) {
this.sidebarContainer.style.zIndex = -1000;
}
2025-01-04 00:20:22 +02:00
this.dragState = DRAG_STATE_NONE;
}
activeScreenChangedEvent({activeScreen}) {
if (activeScreen === this.screenName) {
this.$widget.addClass('show');
} else {
this.$widget.removeClass('show');
}
}
}