({ project }: { project: Project })
| 10 | * 用于提示用户在不同位置释放有不同的效果 |
| 11 | */ |
| 12 | export const DropWindowCover = ({ project }: { project: Project }) => { |
| 13 | const fadeOutMs = 700; |
| 14 | const [dropMouseLocation, setDropMouseLocation] = useState<"top" | "middle" | "bottom" | "notInWindowZone">( |
| 15 | "notInWindowZone", |
| 16 | ); |
| 17 | const [isFadingOut, setIsFadingOut] = useState(false); |
| 18 | const isDraft = project.isDraft; |
| 19 | |
| 20 | const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); |
| 21 | const rafRef = useRef<number | null>(null); |
| 22 | |
| 23 | useEffect(() => { |
| 24 | const cancelAnimation = () => { |
| 25 | if (hideTimerRef.current) clearTimeout(hideTimerRef.current); |
| 26 | if (rafRef.current) cancelAnimationFrame(rafRef.current); |
| 27 | hideTimerRef.current = null; |
| 28 | rafRef.current = null; |
| 29 | }; |
| 30 | |
| 31 | const unlistenPromise = getCurrentWindow().onDragDropEvent(async (event) => { |
| 32 | const size = await getCurrentWindow().outerSize(); |
| 33 | const logicalHeight = isMac ? size.height / (await getCurrentWindow().scaleFactor()) : size.height; |
| 34 | const getDropLocation = (y: number) => |
| 35 | y <= logicalHeight / 3 ? "top" : y <= (logicalHeight / 3) * 2 ? "middle" : "bottom"; |
| 36 | |
| 37 | if (event.payload.type === "over") { |
| 38 | cancelAnimation(); |
| 39 | setIsFadingOut(false); |
| 40 | setDropMouseLocation(getDropLocation(event.payload.position.y)); |
| 41 | } else if (event.payload.type === "leave") { |
| 42 | cancelAnimation(); |
| 43 | setIsFadingOut(false); |
| 44 | setDropMouseLocation("notInWindowZone"); |
| 45 | } else if (event.payload.type === "drop") { |
| 46 | cancelAnimation(); |
| 47 | const dropLocation = getDropLocation(event.payload.position.y); |
| 48 | setIsFadingOut(false); |
| 49 | setDropMouseLocation(dropLocation); |
| 50 | rafRef.current = requestAnimationFrame(() => { |
| 51 | setIsFadingOut(true); |
| 52 | }); |
| 53 | hideTimerRef.current = setTimeout(() => { |
| 54 | setDropMouseLocation("notInWindowZone"); |
| 55 | setIsFadingOut(false); |
| 56 | }, fadeOutMs); |
| 57 | |
| 58 | if (dropLocation === "top") { |
| 59 | DragFileIntoStageEngine.handleDrop(project, event.payload.paths); |
| 60 | } else if (dropLocation === "middle") { |
| 61 | DragFileIntoStageEngine.handleDropFileRelativePath(project, event.payload.paths); |
| 62 | } else { |
| 63 | DragFileIntoStageEngine.handleDropFileAbsolutePath(project, event.payload.paths); |
| 64 | } |
| 65 | } |
| 66 | }); |
| 67 | |
| 68 | return () => { |
| 69 | cancelAnimation(); |
nothing calls this directly
no test coverage detected