Download app/src/column-resizer.mjs from Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP: direct link, hf CLI and curl.
- Browser
- Download file 4.23 kB
-
https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/src/column-resizer.mjs
- Command line
-
hf download hf://spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/app/src/column-resizer.mjs
-
curl -L -o column-resizer.mjs https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/src/column-resizer.mjs
4.23 kB
| const STORAGE_KEY = 'pi-column-ratio'; | |
| const DEFAULT_RATIO = 1 / 1.83; | |
| export function createColumnResizer(layout, handle) { | |
| const desktop = matchMedia('(min-width: 851px)'); | |
| const style = getComputedStyle(layout); | |
| const minimumChat = parseFloat(style.getPropertyValue('--conversation-min')); | |
| const minimumWorkspace = parseFloat(style.getPropertyValue('--workspace-min')); | |
| let ratio = DEFAULT_RATIO, drag, frame = 0; | |
| try { | |
| const saved = Number(localStorage.getItem(STORAGE_KEY)); | |
| if (Number.isFinite(saved) && saved > 0 && saved < 1) ratio = saved; | |
| } catch { /* The divider also works when browser storage is unavailable. */ } | |
| function apply() { | |
| if (!desktop.matches) return; | |
| const width = layout.getBoundingClientRect().width; | |
| if (!width) return; | |
| const chat = Math.max(minimumChat, Math.min(width - minimumWorkspace, width * ratio)); | |
| layout.style.setProperty('--conversation-width', `${chat}px`); | |
| const percent = Math.round(chat / width * 100); | |
| handle.setAttribute('aria-valuemin', String(Math.round(minimumChat / width * 100))); | |
| handle.setAttribute('aria-valuemax', String(Math.round((width - minimumWorkspace) / width * 100))); | |
| handle.setAttribute('aria-valuenow', String(percent)); | |
| handle.setAttribute('aria-valuetext', `Chat ${percent}%, workspace ${100 - percent}%`); | |
| } | |
| function save() { try { localStorage.setItem(STORAGE_KEY, String(ratio)); } catch {} } | |
| function setWidth(pixels) { | |
| const width = layout.getBoundingClientRect().width; | |
| ratio = Math.max(minimumChat, Math.min(width - minimumWorkspace, pixels)) / width; | |
| apply(); | |
| } | |
| function flushDrag() { | |
| cancelAnimationFrame(frame); frame = 0; | |
| if (drag) setWidth(drag.x - layout.getBoundingClientRect().left - drag.offset); | |
| } | |
| function finish(commit) { | |
| if (!drag) return; | |
| if (commit) flushDrag(); | |
| else { cancelAnimationFrame(frame); frame = 0; ratio = drag.initialRatio; } | |
| const pointer = drag.pointer; drag = undefined; | |
| if (handle.hasPointerCapture(pointer)) handle.releasePointerCapture(pointer); | |
| document.documentElement.classList.remove('is-resizing-columns'); | |
| apply(); if (commit) save(); | |
| } | |
| function reset() { finish(false); ratio = DEFAULT_RATIO; apply(); save(); } | |
| handle.addEventListener('pointerdown', event => { | |
| if (!desktop.matches || event.button !== 0 || !event.isPrimary || drag) return; | |
| event.preventDefault(); handle.focus({ preventScroll: true }); | |
| const boundary = layout.querySelector('.conversation').getBoundingClientRect().right; | |
| drag = { pointer: event.pointerId, initialRatio: ratio, x: event.clientX, offset: event.clientX - boundary }; | |
| handle.setPointerCapture(event.pointerId); | |
| document.documentElement.classList.add('is-resizing-columns'); | |
| }); | |
| handle.addEventListener('pointermove', event => { | |
| if (!drag || event.pointerId !== drag.pointer) return; | |
| drag.x = event.clientX; | |
| if (!frame) frame = requestAnimationFrame(flushDrag); | |
| }); | |
| handle.addEventListener('pointerup', event => { | |
| if (!drag || event.pointerId !== drag.pointer) return; | |
| drag.x = event.clientX; finish(true); | |
| }); | |
| handle.addEventListener('pointercancel', () => finish(false)); | |
| handle.addEventListener('lostpointercapture', () => finish(false)); | |
| handle.addEventListener('dblclick', reset); | |
| handle.addEventListener('keydown', event => { | |
| if (!desktop.matches) return; | |
| if (event.key === 'Escape' && drag) { event.preventDefault(); finish(false); return; } | |
| if (!['ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter'].includes(event.key)) return; | |
| event.preventDefault(); | |
| if (event.key === 'Enter') { reset(); return; } | |
| finish(false); | |
| const width = layout.querySelector('.conversation').getBoundingClientRect().width; | |
| const step = event.shiftKey ? 48 : 16; | |
| setWidth(event.key === 'Home' ? 0 : event.key === 'End' ? Infinity : width + (event.key === 'ArrowLeft' ? -step : step)); | |
| save(); | |
| }); | |
| window.addEventListener('blur', () => finish(false)); | |
| desktop.addEventListener('change', () => { finish(false); apply(); }); | |
| // Keep the preferred ratio on window resize, clamping only its displayed size. | |
| new ResizeObserver(apply).observe(layout); | |
| apply(); | |
| } | |