userscript...

This commit is contained in:
Gabe Yuan
2023-08-06 21:12:01 +08:00
parent 063d7c9ff0
commit fef4d50977
14 changed files with 456 additions and 102 deletions

View File

@@ -0,0 +1,72 @@
import { useEffect, useState } from "react";
import { limitNumber } from "../../libs/utils";
export default function Draggable(props) {
const [origin, setOrigin] = useState(null);
const [position, setPosition] = useState({
x: props.left,
y: props.top,
});
const handlePointerDown = (e) => {
e.target.setPointerCapture(e.pointerId);
props?.onStart();
setOrigin({
x: position.x,
y: position.y,
px: e.clientX,
py: e.clientY,
});
};
const handlePointerMove = (e) => {
props?.onMove();
if (origin) {
const dx = e.clientX - origin.px;
const dy = e.clientY - origin.py;
let x = origin.x + dx;
let y = origin.y + dy;
const { w, h } = props.windowSize;
x = limitNumber(x, 0, w - props.width);
y = limitNumber(y, 0, h - props.height);
setPosition({ x, y });
}
};
const handlePointerUp = (e) => {
setOrigin(null);
};
const handleClick = (e) => {
e.stopPropagation();
};
useEffect(() => {
const { w, h } = props.windowSize;
setPosition(({ x, y }) => ({
x: limitNumber(x, 0, w - props.width),
y: limitNumber(y, 0, h - props.height),
}));
}, [props.windowSize, props.width, props.height]);
return (
<div
style={{
position: "fixed",
left: position.x,
top: position.y,
zIndex: 2147483647,
}}
onClick={handleClick}
>
<div
onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
>
{props.handler}
</div>
<div>{props.children}</div>
</div>
);
}

View File

@@ -1,16 +1,132 @@
import Paper from "@mui/material/Paper";
import Box from "@mui/material/Box";
import Fab from "@mui/material/Fab";
import AddIcon from "@mui/icons-material/Add";
import ThemeProvider from "../../hooks/Theme";
import Draggable from "./Draggable";
import IconButton from "@mui/material/IconButton";
import CloseIcon from "@mui/icons-material/Close";
import Stack from "@mui/material/Stack";
import { useEffect, useState, useMemo, useCallback } from "react";
import { StoragesProvider } from "../../hooks/Storage";
import Popup from "../Popup";
export default function Action() {
const fabWidth = 56;
const [showPopup, setShowPopup] = useState(false);
const [windowSize, setWindowSize] = useState({
w: window.innerWidth,
h: window.innerHeight,
});
const [moved, setMoved] = useState(false);
const handleWindowResize = (e) => {
setWindowSize({
w: window.innerWidth,
h: window.innerHeight,
});
};
const handleWindowClick = (e) => {
setShowPopup(false);
};
const handleStart = useCallback(() => {
setMoved(false);
}, []);
const handleMove = useCallback(() => {
setMoved(true);
}, []);
useEffect(() => {
window.addEventListener("resize", handleWindowResize);
window.addEventListener("click", handleWindowClick);
return () => {
window.removeEventListener("resize", handleWindowResize);
window.removeEventListener("click", handleWindowClick);
};
}, []);
const popProps = useMemo(() => {
const width = Math.min(windowSize.w, 300);
const height = Math.min(windowSize.h, 386);
const left = (windowSize.w - width) / 2;
const top = (windowSize.h - height) / 2;
return {
windowSize,
width,
height,
left,
top,
};
}, [windowSize]);
const fabProps = {
windowSize,
width: fabWidth,
height: fabWidth,
left: window.innerWidth - fabWidth - fabWidth,
top: window.innerHeight - fabWidth - fabWidth,
};
return (
<ThemeProvider>
<Box style={{ position: "fixed", top: 16, right: 16, zIndex: 10001 }}>
<Fab color="primary">
<AddIcon />
</Fab>
</Box>
</ThemeProvider>
<StoragesProvider>
<ThemeProvider>
{showPopup ? (
<Draggable
key="pop"
{...popProps}
onStart={handleStart}
onMove={handleMove}
handler={
<Paper style={{ cursor: "move" }} elevation={3}>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
spacing={2}
>
<Box style={{ marginLeft: 16 }}>
{process.env.REACT_APP_NAME}
</Box>
<IconButton
onClick={() => {
setShowPopup(false);
}}
>
<CloseIcon />
</IconButton>
</Stack>
</Paper>
}
>
<Paper>
<Popup />
</Paper>
</Draggable>
) : (
<Draggable
key="fab"
{...fabProps}
onStart={handleStart}
onMove={handleMove}
handler={
<Fab
color="primary"
onClick={(e) => {
if (!moved) {
setShowPopup((pre) => !pre);
}
}}
>
<AddIcon />
</Fab>
}
/>
)}
</ThemeProvider>
</StoragesProvider>
);
}