mirror of
https://github.com/Equicord/Equicord.git
synced 2025-02-25 09:38:52 -05:00
feat(ImagePreview): fix positioning & add preview (WxH) (#60)
* yes * forgot zoom factor * lint -_- fr * remove comments and fix loading spinner and check for mouseOnlyMode
This commit is contained in:
parent
39909d95c4
commit
7220b98b3e
3 changed files with 96 additions and 26 deletions
|
@ -24,17 +24,22 @@ let isDragging: boolean = false;
|
|||
let shouldKeepPreviewOpenTimeout: NodeJS.Timeout | null = null;
|
||||
let shouldKeepPreviewOpen: boolean = false;
|
||||
let hoverDelayTimeout: NodeJS.Timeout | null = null;
|
||||
let lastMouseEvent: MouseEvent | null = null;
|
||||
|
||||
let observer: MutationObserver | null = null;
|
||||
|
||||
function deleteCurrentPreview() {
|
||||
if (!currentPreview || !currentPreviewFile || !currentPreviewFileSize || !currentPreviewType) return;
|
||||
if (!currentPreview || !currentPreviewFile || !currentPreviewFileSize || !currentPreviewType || !loadingSpinner) return;
|
||||
|
||||
currentPreview.remove();
|
||||
loadingSpinner = null;
|
||||
lastMouseEvent = null;
|
||||
currentPreview = null;
|
||||
currentPreviewFile = null;
|
||||
currentPreviewFileSize = null;
|
||||
currentPreviewType = null;
|
||||
lastMouseEvent = null;
|
||||
loadingSpinner = null;
|
||||
zoomLevel = 1;
|
||||
}
|
||||
|
||||
|
@ -126,9 +131,19 @@ function loadImagePreview(url: string) {
|
|||
|
||||
const fileName = document.createElement("span");
|
||||
const fileSize = document.createElement("span");
|
||||
fileSize.className = "file-size";
|
||||
const fileSizeSpan = document.createElement("p");
|
||||
const showingSize = document.createElement("p");
|
||||
const mimeTypeSpan = document.createElement("span");
|
||||
|
||||
const updatePositionAfterLoad = () => {
|
||||
if (lastMouseEvent && currentPreview) {
|
||||
updatePreviewPosition(lastMouseEvent, currentPreview);
|
||||
}
|
||||
};
|
||||
|
||||
fileName.textContent = url.split("/").pop()?.split("?")[0] || "";
|
||||
|
||||
mimeTypeSpan.textContent = mimeType;
|
||||
|
||||
if (currentPreviewType === "video") {
|
||||
|
@ -146,11 +161,25 @@ function loadImagePreview(url: string) {
|
|||
|
||||
video.onloadeddata = () => {
|
||||
currentPreviewFileSize = [video.videoWidth, video.videoHeight];
|
||||
fileSize.textContent = `${currentPreviewFileSize[0]}x${currentPreviewFileSize[1]}`;
|
||||
fileSizeSpan.textContent = `${currentPreviewFileSize[0]}x${currentPreviewFileSize[1]}`;
|
||||
fileSize.appendChild(fileSizeSpan);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (!currentPreviewFileSize) return;
|
||||
const showingMediaSize = [video.clientWidth, video.clientHeight];
|
||||
if (showingMediaSize[0] !== currentPreviewFileSize[0] && showingMediaSize[1] !== currentPreviewFileSize[1]) {
|
||||
showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : "";
|
||||
fileSize.appendChild(showingSize);
|
||||
}
|
||||
});
|
||||
|
||||
if (loadingSpinner) loadingSpinner.remove();
|
||||
video.style.display = "block";
|
||||
|
||||
updatePositionAfterLoad();
|
||||
};
|
||||
|
||||
|
||||
preview.appendChild(video);
|
||||
currentPreviewFile = video;
|
||||
} else {
|
||||
|
@ -159,10 +188,25 @@ function loadImagePreview(url: string) {
|
|||
img.className = "preview-media";
|
||||
img.onload = () => {
|
||||
currentPreviewFileSize = [img.naturalWidth, img.naturalHeight];
|
||||
fileSize.textContent = `${currentPreviewFileSize[0]}x${currentPreviewFileSize[1]}`;
|
||||
fileSizeSpan.textContent = `${currentPreviewFileSize[0]}x${currentPreviewFileSize[1]}`;
|
||||
fileSize.appendChild(fileSizeSpan);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (!currentPreviewFileSize) return;
|
||||
|
||||
const showingMediaSize = [img.clientWidth, img.clientHeight];
|
||||
if (showingMediaSize[0] !== currentPreviewFileSize[0] && showingMediaSize[1] !== currentPreviewFileSize[1]) {
|
||||
showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : "";
|
||||
fileSize.appendChild(showingSize);
|
||||
}
|
||||
});
|
||||
|
||||
if (loadingSpinner) loadingSpinner.remove();
|
||||
img.style.display = "block";
|
||||
|
||||
updatePositionAfterLoad();
|
||||
};
|
||||
|
||||
preview.appendChild(img);
|
||||
currentPreviewFile = img;
|
||||
}
|
||||
|
@ -172,6 +216,7 @@ function loadImagePreview(url: string) {
|
|||
fileInfo.appendChild(fileSize);
|
||||
preview.appendChild(fileInfo);
|
||||
|
||||
if (settings.store.mouseOnlyMode) {
|
||||
currentPreviewFile.addEventListener("mouseover", () => {
|
||||
if (currentPreview && !isCtrlHeld) {
|
||||
shouldKeepPreviewOpen = true;
|
||||
|
@ -185,13 +230,15 @@ function loadImagePreview(url: string) {
|
|||
shouldKeepPreviewOpen = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
currentPreview.addEventListener("wheel", (event: WheelEvent) => {
|
||||
const zoomSpeed = 0.0005;
|
||||
const [{ zoomFactor }, zoomSpeed] = [settings.store, 0.0005];
|
||||
|
||||
if (isCtrlHeld || event.target === currentPreview || event.target === currentPreviewFile) {
|
||||
event.preventDefault();
|
||||
zoomLevel += event.deltaY * -zoomSpeed;
|
||||
|
||||
zoomLevel += event.deltaY * -zoomSpeed * zoomFactor;
|
||||
|
||||
zoomLevel = Math.min(Math.max(zoomLevel, 0.5), 10);
|
||||
|
||||
|
@ -210,6 +257,7 @@ function loadImagePreview(url: string) {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
currentPreview.addEventListener("mousedown", (event: MouseEvent) => {
|
||||
if ((isCtrlHeld || shouldKeepPreviewOpen) && currentPreview) {
|
||||
isDragging = true;
|
||||
|
@ -244,9 +292,12 @@ function updatePreviewPosition(mouseEvent: MouseEvent, element: HTMLElement) {
|
|||
|
||||
if (top + previewHeight > window.innerHeight) {
|
||||
top = mouseEvent.pageY - previewHeight - padding;
|
||||
|
||||
if (top < padding) {
|
||||
top = window.innerHeight - previewHeight - padding;
|
||||
top = window.innerHeight - previewHeight - padding * 2;
|
||||
}
|
||||
} else {
|
||||
top = Math.min(top, window.innerHeight - previewHeight - padding * 2);
|
||||
}
|
||||
|
||||
currentPreview.style.left = `${left}px`;
|
||||
|
@ -263,10 +314,8 @@ function updatePreviewPosition(mouseEvent: MouseEvent, element: HTMLElement) {
|
|||
function addHoverListener(element: Element) {
|
||||
element.setAttribute("data-processed", "true");
|
||||
|
||||
let lastMouseEvent: MouseEvent | null = null;
|
||||
|
||||
element.addEventListener("mouseover", event => {
|
||||
if (currentPreview) {
|
||||
if (currentPreview || loadingSpinner) {
|
||||
if (isCtrlHeld) return;
|
||||
|
||||
deleteCurrentPreview();
|
||||
|
@ -334,12 +383,10 @@ function addHoverListener(element: Element) {
|
|||
}
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
if (event.key === "Control") {
|
||||
if (event.key === "Control" && currentPreview) {
|
||||
isCtrlHeld = true;
|
||||
if (currentPreview) {
|
||||
currentPreview.classList.add("allow-zoom-and-drag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyup(event: KeyboardEvent) {
|
||||
|
@ -373,6 +420,7 @@ function removeHoverListeners() {
|
|||
processedElements.forEach(element => {
|
||||
const clone = element.cloneNode(true);
|
||||
element.replaceWith(clone);
|
||||
element.removeAttribute("data-processed");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ const settings = definePluginSettings({
|
|||
default: 0.5,
|
||||
markers: [0, 1, 2, 3, 4, 5],
|
||||
},
|
||||
zoomFactor: {
|
||||
type: OptionType.SLIDER,
|
||||
description: "Speed at which the image zooms in",
|
||||
default: 1.5,
|
||||
markers: [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5],
|
||||
},
|
||||
});
|
||||
|
||||
const mimeTypes = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.image-preview {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
pointer-events: auto;
|
||||
pointer-events: none;
|
||||
border: 2px solid var(--background-secondary);
|
||||
background-color: var(--background-primary);
|
||||
border-radius: 4px;
|
||||
|
@ -16,6 +16,7 @@
|
|||
.image-preview.allow-zoom-and-drag {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.image-preview .file-info {
|
||||
|
@ -40,6 +41,21 @@
|
|||
border: 1px solid var(--background-secondary);
|
||||
}
|
||||
|
||||
.file-size {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.image-preview .file-info span p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.image-preview .file-info span p:last-child:not(:first-child) {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.image-preview.allow-zoom-and-drag .file-info {
|
||||
display: none;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue