[RAPID-fix] 캡처 속도/화질 개선 + 드래그 커서 4방향 화살표로 변경 - 오버레이 마운트 시점에 미리 캡처 시작 → mouseup 즉시 크롭 - scale: max(dpr, 2)로 화질 2배 향상 - 캡처 준비 중 wait 커서 표시 - 메신저 헤더 드래그 커서 cursor-grab → cursor-move (4방향 화살표) [RAPID-micro] 캡처 버튼 헤더 → 입력창 첨부파일 좌측으로 이동 [RAPID-micro] 채팅방 선택 시 스크롤 하단 이동 수정 [RAPID] 메신저 3가지 수정: 스크롤 버튼, DM 상대방 이름, 캡처 속도 개선 [RAPID-fix] 스크롤/캡처 3가지 수정 - 스크롤 하단 이동: useLayoutEffect → useEffect+rAF (이미지 레이아웃 완료 후 스크롤) - 스크롤 버튼: 리스너 deps를 room.id로 변경 (room 없을 때 미연결 문제 해결) - 캡처 속도: domToPng(느림) → getDisplayMedia 네이티브 API(즉시 캡처) [RAPID-fix] 메신저 3가지 수정 - 최신 메시지 버튼: 스크롤 컨테이너 밖으로 이동, 입력창 위 중앙 고정 - 스크롤 하단: rAF + 600ms 지연 2회 (이미지 비동기 로드 대응) - 캡처: 버튼 클릭 즉시 오버레이 + domToPng 병렬 실행, mouseup에서 await (font:false 최적화) [RAPID-micro] 채팅방 열 때 스크롤 점프 제거 [RAPID-fix] 캡처 오버레이 렌더 후 domToPng 시작으로 mousedown 딜레이 개선 [RAPID-fix] 캡처 프리캐싱: 메신저 열릴 때 백그라운드 domToPng → 버튼 클릭 즉시 오버레이 [RAPID-fix] 캡처 worker 추가: 리소스 fetch를 Web Worker로 오프로드 [RAPID-fix] 캡처 방식 변경: domToPng 제거 → getDisplayMedia (즉시 캡처, 프리캐싱 제거) [RAPID-micro] 화면 캡처 버튼 제거 (Cmd+V 붙여넣기로 대체)
58 lines
1.4 KiB
TypeScript
58 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { apiClient } from "@/lib/api/client";
|
|
import { ImageLightbox } from "./ImageLightbox";
|
|
|
|
interface AuthImageProps {
|
|
src: string;
|
|
alt?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function AuthImage({ src, alt, className }: AuthImageProps) {
|
|
const [blobUrl, setBlobUrl] = useState<string | null>(null);
|
|
const [lightboxOpen, setLightboxOpen] = useState(false);
|
|
|
|
useEffect(() => {
|
|
let objectUrl: string | null = null;
|
|
const path = src.replace(apiClient.defaults.baseURL ?? "", "");
|
|
apiClient
|
|
.get(path, { responseType: "blob" })
|
|
.then((res) => {
|
|
objectUrl = URL.createObjectURL(res.data);
|
|
setBlobUrl(objectUrl);
|
|
})
|
|
.catch(() => setBlobUrl(null));
|
|
|
|
return () => {
|
|
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
};
|
|
}, [src]);
|
|
|
|
if (!blobUrl) {
|
|
return (
|
|
<div className={`bg-muted animate-pulse rounded ${className ?? "w-40 h-40"}`} />
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<img
|
|
src={blobUrl}
|
|
alt={alt || "이미지"}
|
|
className={`${className ?? ""} cursor-pointer`}
|
|
onClick={() => setLightboxOpen(true)}
|
|
/>
|
|
{lightboxOpen && (
|
|
<ImageLightbox
|
|
src={blobUrl}
|
|
alt={alt}
|
|
downloadHref={blobUrl}
|
|
onClose={() => setLightboxOpen(false)}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|