Allow dragging around notices

This commit is contained in:
Ajay 2023-12-22 10:44:21 -05:00
parent 2865ea77fe
commit 5ac19eecd4
3 changed files with 79 additions and 3 deletions

View file

@ -41,6 +41,13 @@ export interface NoticeProps {
children?: React.ReactNode; children?: React.ReactNode;
} }
interface MouseDownInfo {
x: number;
y: number;
right: number;
bottom: number;
}
export interface NoticeState { export interface NoticeState {
maxCountdownTime: () => number; maxCountdownTime: () => number;
@ -50,8 +57,16 @@ export interface NoticeState {
mouseHovering: boolean; mouseHovering: boolean;
startFaded: boolean; startFaded: boolean;
mouseDownInfo: MouseDownInfo | null;
mouseMoved: boolean;
right: number;
bottom: number;
} }
// Limits for dragging notice around
const bounds = [10, 100, 10, 10];
class NoticeComponent extends React.Component<NoticeProps, NoticeState> { class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownInterval: NodeJS.Timeout; countdownInterval: NodeJS.Timeout;
@ -61,6 +76,8 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
parentRef: React.RefObject<HTMLDivElement>; parentRef: React.RefObject<HTMLDivElement>;
handleMouseMoveBinded: (e: MouseEvent) => void = this.handleMouseMove.bind(this);
constructor(props: NoticeProps) { constructor(props: NoticeProps) {
super(props); super(props);
@ -87,7 +104,12 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownMode: CountdownMode.Timer, countdownMode: CountdownMode.Timer,
mouseHovering: false, mouseHovering: false,
startFaded: this.props.startFaded ?? false startFaded: this.props.startFaded ?? false,
mouseDownInfo: null,
mouseMoved: false,
right: bounds[0],
bottom: bounds[1]
} }
} }
@ -98,6 +120,9 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
render(): React.ReactElement { render(): React.ReactElement {
const noticeStyle: React.CSSProperties = { const noticeStyle: React.CSSProperties = {
zIndex: this.props.zIndex || (1000 + this.amountOfPreviousNotices), zIndex: this.props.zIndex || (1000 + this.amountOfPreviousNotices),
right: this.state.right,
bottom: this.state.bottom,
userSelect: this.state.mouseDownInfo && this.state.mouseMoved ? "none" : "auto",
...(this.props.style ?? {}) ...(this.props.style ?? {})
} }
@ -107,7 +132,29 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
+ (this.props.showInSecondSlot ? " secondSkipNotice" : "") + (this.props.showInSecondSlot ? " secondSkipNotice" : "")
+ (this.props.extraClass ? ` ${this.props.extraClass}` : "")} + (this.props.extraClass ? ` ${this.props.extraClass}` : "")}
onMouseEnter={(e) => this.onMouseEnter(e) } onMouseEnter={(e) => this.onMouseEnter(e) }
onMouseLeave={() => this.timerMouseLeave()} onMouseLeave={() => {
this.timerMouseLeave();
}}
onMouseDown={(e) => {
document.addEventListener("mousemove", this.handleMouseMoveBinded);
this.setState({
mouseDownInfo: {
x: e.clientX,
y: e.clientY,
right: this.state.right,
bottom: this.state.bottom
},
mouseMoved: false
});
}}
onMouseUp={() => {
document.removeEventListener("mousemove", this.handleMouseMoveBinded);
this.setState({
mouseDownInfo: null
});
}}
ref={this.parentRef} ref={this.parentRef}
style={noticeStyle} > style={noticeStyle} >
<div className={"sponsorSkipNoticeTableContainer" <div className={"sponsorSkipNoticeTableContainer"
@ -395,6 +442,33 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
getElement(): React.RefObject<HTMLDivElement> { getElement(): React.RefObject<HTMLDivElement> {
return this.parentRef; return this.parentRef;
} }
componentWillUnmount(): void {
document.removeEventListener("mousemove", this.handleMouseMoveBinded);
}
// For dragging around notice
handleMouseMove(e: MouseEvent): void {
if (this.state.mouseDownInfo && e.buttons === 1) {
const [mouseX, mouseY] = [e.clientX, e.clientY];
const deltaX = mouseX - this.state.mouseDownInfo.x;
const deltaY = mouseY - this.state.mouseDownInfo.y;
console.log(deltaX, deltaY)
if (deltaX > 0 || deltaY > 0) this.setState({ mouseMoved: true });
const element = this.parentRef.current;
const parent = element.parentElement.parentElement;
this.setState({
right: Math.min(parent.clientWidth - element.clientWidth - bounds[2], Math.max(bounds[0], this.state.mouseDownInfo.right - deltaX)),
bottom: Math.min(parent.clientHeight - element.clientHeight - bounds[3], Math.max(bounds[1], this.state.mouseDownInfo.bottom - deltaY))
});
} else {
document.removeEventListener("mousemove", this.handleMouseMoveBinded);
}
}
} }
export default NoticeComponent; export default NoticeComponent;

View file

@ -316,6 +316,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
<select id={"sponsorTimeCategories" + this.idSuffix} <select id={"sponsorTimeCategories" + this.idSuffix}
className="sponsorTimeCategories sponsorTimeEditSelector" className="sponsorTimeCategories sponsorTimeEditSelector"
defaultValue={this.segments[0].category} defaultValue={this.segments[0].category}
onMouseDown={(e) => e.stopPropagation()}
ref={this.categoryOptionRef}> ref={this.categoryOptionRef}>
{this.getCategoryOptions()} {this.getCategoryOptions()}

View file

@ -120,7 +120,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
{/* Sponsor Time List */} {/* Sponsor Time List */}
<tr id={"sponsorSkipNoticeMiddleRow" + this.state.idSuffix} <tr id={"sponsorSkipNoticeMiddleRow" + this.state.idSuffix}
className="sponsorTimeMessagesRow" className="sponsorTimeMessagesRow"
style={{maxHeight: (this.contentContainer().v.offsetHeight - 200) + "px"}}> style={{maxHeight: (this.contentContainer().v.offsetHeight - 200) + "px"}}
onMouseDown={(e) => e.stopPropagation()}>
<td style={{width: "100%"}}> <td style={{width: "100%"}}>
{this.getSponsorTimeMessages()} {this.getSponsorTimeMessages()}
</td> </td>