feat: 1-to-1 message render + web data-lake backend

This commit is contained in:
hh
2026-05-31 01:45:05 +02:00
parent f0afb7ec5b
commit 75425d1bee
110 changed files with 10199 additions and 54 deletions
+32
View File
@@ -0,0 +1,32 @@
const WAVE_DURATION = 700;
export function ripple(node: HTMLElement) {
function onPointerDown(event: PointerEvent) {
if (event.button !== 0) {
return;
}
const rect = node.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
let container = node.querySelector<HTMLElement>(".ripple-container");
if (!container) {
container = document.createElement("div");
container.className = "ripple-container";
node.append(container);
}
const wave = document.createElement("div");
wave.className = "ripple-wave";
wave.style.width = `${size}px`;
wave.style.height = `${size}px`;
wave.style.left = `${event.clientX - rect.left - size / 2}px`;
wave.style.top = `${event.clientY - rect.top - size / 2}px`;
container.append(wave);
setTimeout(() => wave.remove(), WAVE_DURATION);
}
node.addEventListener("pointerdown", onPointerDown);
return {
destroy() {
node.removeEventListener("pointerdown", onPointerDown);
},
};
}
+20
View File
@@ -0,0 +1,20 @@
export function visible(node: HTMLElement, onVisible: () => void) {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
onVisible();
observer.disconnect();
return;
}
}
},
{ rootMargin: "300px" }
);
observer.observe(node);
return {
destroy() {
observer.disconnect();
},
};
}