File Property reorder autoscroll.

This commit is contained in:
Robin E. R. Davies
2025-06-23 22:33:35 -04:00
parent 130cda3773
commit 78539c1795
5 changed files with 341 additions and 141 deletions
+3 -1
View File
@@ -1,7 +1,9 @@
window.addEventListener .... done wrong everywhere!
touch scroll in file propertty dialog.
channel bindings help dialog. <ChannelBindingHelpDialog channel bindings help dialog. <ChannelBindingHelpDialog
Tooltips on touch ui?
draggable UI: scrolloffset!? draggable UI: scrolloffset!?
-3
View File
@@ -19,9 +19,6 @@ div {
min-width: 0; min-width: 0;
} }
.draggable-button-base {
touch-action: none;
}
@media not all /* seems to be ok in current chrome (prefers-color-scheme: light) */{ @media not all /* seems to be ok in current chrome (prefers-color-scheme: light) */{
input[type="number"].scrollMod::-webkit-outer-spin-button, input[type="number"].scrollMod::-webkit-outer-spin-button,
+133 -60
View File
@@ -26,10 +26,11 @@ import ButtonBase, { ButtonBaseProps } from "@mui/material/ButtonBase";
export interface DraggableButtonBaseProps extends ButtonBaseProps { export interface DraggableButtonBaseProps extends ButtonBaseProps {
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void; onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
onLongPressStart?: (currentTarget: HTMLButtonElement, e: React.PointerEvent<HTMLButtonElement>) => boolean; onLongPressStart?: (currentTarget: HTMLButtonElement, e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>) => boolean;
onLongPressMove?: (e: React.PointerEvent<HTMLButtonElement>) => void; onLongPressMove?: (e: React.PointerEvent<HTMLButtonElement>) => void;
onLongPressEnd?: (e: React.PointerEvent<HTMLButtonElement>) => void; onLongPressEnd?: (e: React.PointerEvent<HTMLButtonElement>| React.MouseEvent<HTMLButtonElement>) => void;
longPressDelay? : number; instantMouseLongPress?: boolean;
longPressDelay?: number;
} }
interface Point { interface Point {
@@ -58,37 +59,43 @@ function screenToClient(e: React.PointerEvent): Point {
export default function DraggableButtonBase(props: DraggableButtonBaseProps) { export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
// Ensure that the props are spread correctly // Ensure that the props are spread correctly
const { onClick, onLongPressStart, onLongPressEnd,longPressDelay, ...rest } = props; const { onClick, onLongPressStart, onLongPressMove:
doLongPressMove,onLongPressEnd, longPressDelay,instantMouseLongPress, ...rest } = props;
let [hTimeout, setHTimeout] = React.useState<number | null>(null); let [hTimeout, setHTimeout] = React.useState<number | null>(null);
let [pointerId, setPointerId] = React.useState<number | null>(null); let [pointerId, setPointerId] = React.useState<number | null>(null);
let [longPressed, setLongPressed] = React.useState<boolean>(false); let [longPressed, setLongPressed] = React.useState<boolean>(false);
let [clickSuppressed, setClickSuppressed] = React.useState<boolean>(false); let [clickSuppressed, setClickSuppressed] = React.useState<boolean>(false);
let [pointerDownPoint, setPointerDownPoint] = React.useState<Point >({x: 0, y: 0}); let [pointerDownPoint, setPointerDownPoint] = React.useState<Point>({ x: 0, y: 0 });
let [ longPressedElement, setLongPressedElement ] = React.useState<HTMLButtonElement | null>(null);
function handleSuppressClick(e: MouseEvent) { function handleSuppressClick(e: MouseEvent) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
setSuppressClick(false); setSuppressClick(false);
} }
function setSuppressClick(value: boolean) { function setSuppressClick(value: boolean) {
setClickSuppressed(value);
if (value !== clickSuppressed) { }
setClickSuppressed(value); function startLongPress(currentTarget: HTMLButtonElement, e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>)
if (value) { {
window.addEventListener( if (hTimeout !== null) {
"click", window.clearTimeout(hTimeout);
handleSuppressClick, setHTimeout(null);
{ }
once: true, if (props.onLongPressStart) {
capture: true if (!props.onLongPressStart(currentTarget, e)) {
}); return;
} else {
window.removeEventListener("click", handleSuppressClick);
} }
} }
setLongPressedElement(currentTarget);
setLongPressed(true);
setSuppressClick(true);
currentTarget.style.touchAction = "none"; // prevent scrolling.
// console.log("DraggableButtonBase: long press started");
} }
function cancelLongPress() { function cancelLongPress() {
@@ -99,23 +106,106 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
setPointerId(null); setPointerId(null);
setLongPressed(false); setLongPressed(false);
setSuppressClick(false); setSuppressClick(false);
if (longPressedElement) {
longPressedElement.style.touchAction = "";
setLongPressedElement(null);
}
if (longPressed) {
// console.log("DraggableButtonBase: long press canceled");
}
} }
function stopLongPress(e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>) {
if (longPressed) {
if (props.onLongPressEnd) {
props.onLongPressEnd(e);
}
}
cancelLongPress();
}
const handleTouchMove = (e: TouchEvent) => {
if (longPressed) {
e.preventDefault(); // Prevent scrolling during long press
e.stopPropagation();
}
}
const handleTouchstart = (e: TouchEvent) => {
if (longPressed) {
e.preventDefault(); // Prevent default touch behavior during long press
e.stopPropagation();
}
}
useEffect(() => { useEffect(() => {
let hTouchMove = (e: TouchEvent) => {
handleTouchMove(e);
}
addEventListener("touchmove", hTouchMove, { passive: false, capture: true });
let hTouchStart = (e: TouchEvent) => {
handleTouchstart(e);
}
addEventListener("touchstart", hTouchStart, { passive: false, capture: true });
return () => { return () => {
removeEventListener("touchmove", hTouchMove, { capture: true });
removeEventListener("touchstart", hTouchStart, { capture: true });
setSuppressClick(false); setSuppressClick(false);
cancelLongPress(); cancelLongPress();
}; };
}, []); }, []);
useEffect(() => {
if (clickSuppressed) {
let hclick = (e: MouseEvent) => {
handleSuppressClick(e);
};
window.addEventListener("click",hclick, { capture: true });
let hTimeout: number | null = null;
hTimeout = window.setTimeout(() => {
setSuppressClick(false);
hTimeout = null;
}, 100);
return () => {
if (hTimeout !== null) {
window.clearTimeout(hTimeout);
}
window.removeEventListener("click", hclick, { capture: true });
}
} else {
return ()=>{};
}
}, [clickSuppressed]);
useEffect(() => {
if (longPressed) {
const suppressTouchMove = (e: TouchEvent) => {
e.preventDefault();
}
window.addEventListener("touchmove", suppressTouchMove, { capture: true, passive: false } );
return () => {
window.removeEventListener("touchmove", suppressTouchMove, {capture: true})
}
}
else {
return () => {
};
}
}, [longPressed]);
return ( return (
<ButtonBase <ButtonBase
{...rest} {...rest}
className="draggable-button-base" style={{ touchAction: longPressed ? "none" : undefined, ...props.style }}
onContextMenu={(e) => { onContextMenu={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (e.button === -1) { // touch long press
startLongPress(e.currentTarget as HTMLButtonElement,e);
}
return false; return false;
}} }}
onPointerDown={(e) => { onPointerDown={(e) => {
@@ -130,19 +220,14 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
setPointerDownPoint(screenToClient(e)); setPointerDownPoint(screenToClient(e));
let currentTarget = e.currentTarget as HTMLButtonElement; let currentTarget = e.currentTarget as HTMLButtonElement;
if (longPressDelay === undefined || longPressDelay >= 0) if (longPressDelay === undefined || longPressDelay >= 0) {
{ let delay = longPressDelay ?? 1250;
if (instantMouseLongPress === true && e.pointerType === "mouse") {
delay = 0;
}
setHTimeout(window.setTimeout(() => { setHTimeout(window.setTimeout(() => {
setHTimeout(null); startLongPress(currentTarget, e);
if (props.onLongPressStart) { }, delay));
if (!props.onLongPressStart(currentTarget,e))
{
return;
}
}
setLongPressed(true);
setSuppressClick(true);
}, longPressDelay??1250));
} }
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@@ -150,17 +235,17 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
}} }}
onPointerMove={(e) => { onPointerMove={(e) => {
if (e.pointerId === pointerId) { if (e.pointerId === pointerId) {
if(longPressed) { if (longPressed) {
if (props.onLongPressMove) { if (doLongPressMove) {
props.onLongPressMove(e); doLongPressMove(e);
} }
} else { } else {
let clientPoint = screenToClient(e); let clientPoint = screenToClient(e);
let dx = pointerDownPoint.x- clientPoint.x; let dx = pointerDownPoint.x - clientPoint.x;
let dy = pointerDownPoint.y - clientPoint.y; let dy = pointerDownPoint.y - clientPoint.y;
if (Math.abs(dx) > 5 || Math.abs(dy) > 5) { if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
cancelLongPress(); stopLongPress(e);
} }
} }
} }
@@ -171,14 +256,8 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
onPointerUp={(e) => { onPointerUp={(e) => {
if (e.pointerId === pointerId) { if (e.pointerId === pointerId) {
e.currentTarget.releasePointerCapture(e.pointerId); e.currentTarget.releasePointerCapture(e.pointerId);
setPointerId(null); stopLongPress(e);
if (longPressed) { if (e.isPropagationStopped() || e.isDefaultPrevented()) {
if (props.onLongPressEnd) {
props.onLongPressEnd(e);
}
}
cancelLongPress();
if (e.isPropagationStopped()) {
setSuppressClick(true); // only way to cancel the click setSuppressClick(true); // only way to cancel the click
return; return;
} }
@@ -187,30 +266,24 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
} }
}} }}
// onTouchStart={(e)=> { onTouchStart={(e)=> {
// //e.preventDefault(); //e.preventDefault();
// }} }}
// onTouchMove={(e)=> {
// //e.preventDefault();
// }}
onClick={(e) => { onClick={(e) => {
if (clickSuppressed) { if (clickSuppressed) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
setSuppressClick(false); setSuppressClick(false);
} else { } else {
if (props.onClick) { if (onClick) {
props.onClick(e); onClick(e);
} }
} }
}} }}
onPointerCancelCapture={(e) => { onPointerCancelCapture={(e) => {
if (pointerId !== null) { if (pointerId !== null) {
e.currentTarget.releasePointerCapture(e.pointerId); e.currentTarget.releasePointerCapture(e.pointerId);
if (longPressed && props.onLongPressEnd) { stopLongPress(e);
props.onLongPressEnd(e)
}
cancelLongPress();
} }
}}> }}>
{props.children} {props.children}
+195 -67
View File
@@ -63,6 +63,13 @@ import HomeIcon from '@mui/icons-material/Home';
import FilePropertyDirectorySelectDialog from './FilePropertyDirectorySelectDialog'; import FilePropertyDirectorySelectDialog from './FilePropertyDirectorySelectDialog';
import { getAlbumArtUri, getTrackTitle } from './AudioFileMetadata'; import { getAlbumArtUri, getTrackTitle } from './AudioFileMetadata';
const AUTOSCROLL_TICK_DELAY = 30;
const AUTOSCROLL_THRESHOLD = 48;
const AUTOSCROLL_SCROLL_PER_SECOND = 500;
const AUTOSCROLL_SCROLL_RATE = AUTOSCROLL_SCROLL_PER_SECOND * AUTOSCROLL_TICK_DELAY / 1000;
interface Point { interface Point {
x: number; x: number;
y: number; y: number;
@@ -93,7 +100,7 @@ const audioFileExtensions: { [name: string]: boolean } = {
".ra": true ".ra": true
}; };
function screenToClient(currentTarget: HTMLElement, e: React.PointerEvent): Point { function screenToClient(currentTarget: HTMLElement, e: React.PointerEvent | React.MouseEvent): Point {
let rect = currentTarget.getBoundingClientRect(); let rect = currentTarget.getBoundingClientRect();
const x = e.clientX + rect.left; const x = e.clientX + rect.left;
const y = e.clientY + rect.right; const y = e.clientY + rect.right;
@@ -157,11 +164,14 @@ export interface FilePropertyDialogState {
}; };
class DragState { interface DragState {
activeItem: string = ""; activeItem: string;
height: number = 0; height: number;
from: number = 0; dragElement: HTMLElement;
to: number = 0; dragElementDy: number;
from: number;
to: number;
lastMousePoint: Point;
}; };
export default withStyles( export default withStyles(
@@ -323,8 +333,6 @@ export default withStyles(
longPressStartPoint: Point | null = null; longPressStartPoint: Point | null = null;
dragFromPosition: number = -1;
dragToPosition: number = -1;
maxPosition: number = 0; maxPosition: number = 0;
handleMultisSelectClose() { handleMultisSelectClose() {
@@ -336,24 +344,29 @@ export default withStyles(
handleLongPressStart( handleLongPressStart(
currentTarget: HTMLButtonElement, currentTarget: HTMLButtonElement,
e: React.PointerEvent<HTMLButtonElement>, e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>,
fileEntry: FileEntry): boolean { fileEntry: FileEntry): boolean {
if (this.state.reordering) { if (this.state.reordering) {
if (!this.isTracksDirectory()) { if (!this.isTracksDirectory()) {
return false; return false;
} }
this.dragFromPosition = parseInt(currentTarget.getAttribute("data-position") as string, 10);
this.dragToPosition = this.dragToPosition;
let element = currentTarget; let element = currentTarget;
element.style.position = "relative"; let index = parseInt(element.getAttribute("data-position") as string, 10);
element.style.zIndex = "1000";
element.style.top = "5px";
element.style.left = "5px";
element.style.background = isDarkMode() ? "#555" : "#EEF" // xxx: dark mode.
if (this.listContainerElementRef) { if (this.listContainerElementRef) {
this.longPressStartPoint = screenToClient(currentTarget,e); this.longPressStartPoint = screenToClient(currentTarget, e);
let dragState: DragState = {
activeItem: fileEntry.pathname,
dragElement: element,
height: element.clientHeight,
dragElementDy: 0,
from: index,
to: index,
lastMousePoint: {...this.longPressStartPoint}
};
this.setState({ dragState: dragState });
} }
return true; return true;
} else if (!this.state.multiSelect) { } else if (!this.state.multiSelect) {
if (fileEntry.isProtected) { if (fileEntry.isProtected) {
@@ -370,6 +383,48 @@ export default withStyles(
return false; return false;
} }
dragTarget: HTMLButtonElement | null = null;
updateReorderPosition(element: HTMLButtonElement, point: Point) {
if (this.longPressStartPoint) {
let dragDy = point.y - this.longPressStartPoint.y;
let height = element.clientHeight;
let dragFromPosition = parseInt(element.getAttribute("data-position") as string, 10);
let elementOffset = dragFromPosition * height;
let newOffset = elementOffset + dragDy;
if (newOffset < 0) {
dragDy = -elementOffset;
newOffset = 0;
}
let maxOffset = (this.maxPosition - 1) * height;
if (newOffset > maxOffset) {
dragDy = maxOffset - elementOffset;
newOffset = maxOffset;
}
let toPosition = Math.floor((newOffset + height / 2) / height);
if (toPosition < 0) {
toPosition = 0;
}
if (toPosition > this.maxPosition) {
toPosition = this.maxPosition;
}
// console.log("drag from " + dragFromPosition + " to " + toPosition + " dy: " + dragDy);
this.setState({
dragState: {
activeItem: element.getAttribute("data-pathname") || "",
dragElement: element,
height: height,
dragElementDy: dragDy,
from: dragFromPosition,
to: toPosition,
lastMousePoint: point
}
});
}
}
handleLongPressMove(e: React.PointerEvent<HTMLButtonElement>) { handleLongPressMove(e: React.PointerEvent<HTMLButtonElement>) {
if (this.state.reordering) { if (this.state.reordering) {
if (!this.isTracksDirectory()) { if (!this.isTracksDirectory()) {
@@ -377,37 +432,10 @@ export default withStyles(
} }
if (this.listContainerElementRef) { if (this.listContainerElementRef) {
let element = e.target as HTMLButtonElement; let element = e.target as HTMLButtonElement;
let point = screenToClient(e.currentTarget,e); let point = screenToClient(e.currentTarget, e);
if (this.longPressStartPoint) { this.updateReorderPosition(element, point);
let dy = point.y - this.longPressStartPoint.y; this.startAutoScroll()
element.style.left = (5) + "px";
element.style.top = (5 + dy) + "px";
let height = element.clientHeight;
let positionChange_: number = 0;
if (dy > 0) {
positionChange_ = Math.floor((dy + height / 2) / height);
} else {
positionChange_ = Math.ceil((dy - height / 2) / height)
}
let toPosition = this.dragFromPosition + positionChange_;
if (toPosition < 0) {
toPosition = 0;
}
if (toPosition > this.maxPosition) {
toPosition = this.maxPosition;
}
if (toPosition !== this.dragToPosition) {
this.dragToPosition = toPosition;
this.setState({
dragState: {
activeItem: element.getAttribute("data-pathname") || "",
height: height,
from: this.dragFromPosition,
to: toPosition
}
});
}
}
} }
} }
} }
@@ -457,7 +485,7 @@ export default withStyles(
this.model.moveAudioFile( this.model.moveAudioFile(
this.state.currentDirectory, from, to); this.state.currentDirectory, from, to);
} }
handleLongPressEnd(e: React.PointerEvent<HTMLButtonElement>, fileEntry: FileEntry) { handleLongPressEnd(e: React.PointerEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>, fileEntry: FileEntry) {
if (this.state.reordering) { if (this.state.reordering) {
if (!this.isTracksDirectory()) { if (!this.isTracksDirectory()) {
return; return;
@@ -471,14 +499,8 @@ export default withStyles(
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
let element = e.currentTarget as HTMLButtonElement;
element.style.position = "";
element.style.zIndex = "";
element.style.top = "";
element.style.left = "";
element.style.background = ""; // xxx: dark mode.
this.setState({ dragState: null }); this.setState({ dragState: null });
this.stopAutoScroll();
} else if (!this.state.multiSelect) { } else if (!this.state.multiSelect) {
let selectedFile = fileEntry.pathname; let selectedFile = fileEntry.pathname;
if (selectedFile === "") { if (selectedFile === "") {
@@ -526,6 +548,7 @@ export default withStyles(
this.requestScroll = true; this.requestScroll = true;
} }
componentWillUnmount() { componentWillUnmount() {
this.stopAutoScroll();
this.cancelProgressTimeout(); this.cancelProgressTimeout();
super.componentWillUnmount(); super.componentWillUnmount();
@@ -925,7 +948,98 @@ export default withStyles(
return (<InsertDriveFileIcon style={style} />); return (<InsertDriveFileIcon style={style} />);
} }
listContainerElementRef: HTMLDivElement | null = null; private listContainerElementRef: HTMLDivElement | null = null;
private scrollContainerElementRef: HTMLDivElement | null = null;
private autoScrollTimer: number | null = null;
handleAutoScrollTick() {
let dragState = this.state.dragState;
if (!dragState) return;
let scrollContainer = this.scrollContainerElementRef;
if (!scrollContainer) {
return;
}
let scrollBounds_ = scrollContainer.getBoundingClientRect();
let scrollClientTop = scrollBounds_.top;
let scrollClientBottom = scrollClientTop + scrollContainer.clientHeight;
let dragBounds = dragState.dragElement?.getBoundingClientRect();
let dy = 0;
let y = scrollContainer.scrollTop;
if (dragBounds.top < scrollClientTop + AUTOSCROLL_THRESHOLD) {
dy = -AUTOSCROLL_SCROLL_RATE;
y = scrollContainer.scrollTop + dy;
if (y < 0) y = 0;
dy = y - scrollContainer.scrollTop;
} else if (dragBounds.bottom > scrollClientBottom - AUTOSCROLL_THRESHOLD) {
dy = AUTOSCROLL_SCROLL_RATE;
y = scrollContainer.scrollTop + dy;
let maxScrollTop = scrollContainer.scrollHeight - scrollContainer.clientHeight;
if (y > maxScrollTop) {
y = maxScrollTop;
}
dy = y - scrollContainer.scrollTop;
} else {
return;
}
if (this.longPressStartPoint === null) {
return;
}
if (dy === 0) {
return;
}
this.longPressStartPoint = {
x: this.longPressStartPoint.x,
y: this.longPressStartPoint.y - dy
};
let dragElementDy = dragState.lastMousePoint.y - this.longPressStartPoint.y;
let originalY = dragState.from * dragState.height;
let newY = originalY + dragElementDy;
if (newY < 0)
{
newY = 0;
dragElementDy = -originalY;
}
let maxDy = (this.maxPosition - 1) * dragState.height;
if (newY > maxDy) {
newY = maxDy;
dragElementDy = maxDy - originalY;
}
let newTo = Math.floor((newY + dragState.height / 2) / dragState.height);
let newDragState = { ...dragState };
newDragState.dragElementDy = dragElementDy;
newDragState.to = newTo;
// console.log("autoscroll from " + dragState.from + " to " + newTo + " dy: " + dragElementDy);
// avoid jitter.
newDragState.dragElement.style.top = (newDragState.dragElementDy + 5) + "px";
this.setState({ dragState: newDragState });
scrollContainer.scrollTo({ left: 0, top: y, behavior: "instant" });
this.startAutoScroll();
}
stopAutoScroll() {
if (this.autoScrollTimer !== null) {
clearTimeout(this.autoScrollTimer);
this.autoScrollTimer = null;
}
}
startAutoScroll() {
this.stopAutoScroll();
this.autoScrollTimer = setTimeout(
() => { this.handleAutoScrollTick() }, AUTOSCROLL_TICK_DELAY);
}
render() { render() {
const isTracksDirectory = this.isTracksDirectory(); const isTracksDirectory = this.isTracksDirectory();
@@ -1146,7 +1260,9 @@ export default withStyles(
<DialogContent style={{ <DialogContent style={{
paddingLeft: 0, paddingRight: 0, paddingTop: 0, colorScheme: (isDarkMode() ? "dark" : "light"), paddingLeft: 0, paddingRight: 0, paddingTop: 0, colorScheme: (isDarkMode() ? "dark" : "light"),
position: "relative" position: "relative"
}}> }}
ref={(element: HTMLDivElement | null) => { this.scrollContainerElementRef = element; }}
>
<div style={{ <div style={{
paddingLeft: 16, paddingRight: 16, paddingTop: 8, paddingBottom: 8, paddingLeft: 16, paddingRight: 16, paddingTop: 8, paddingBottom: 8,
@@ -1210,7 +1326,10 @@ export default withStyles(
scrollRef = (element) => { this.onScrollRef(element) }; scrollRef = (element) => { this.onScrollRef(element) };
} }
let dragOffset = 0; let dragOffset = 0;
let dragLeft = 0;
let dragState = this.state.dragState; let dragState = this.state.dragState;
let zIndex: number | undefined = undefined;
let background: string | undefined = undefined;
if (dragState && value.metadata) { if (dragState && value.metadata) {
if (myTrackPosition !== dragState.from) { if (myTrackPosition !== dragState.from) {
if (myTrackPosition >= dragState.to && myTrackPosition < dragState.from) { if (myTrackPosition >= dragState.to && myTrackPosition < dragState.from) {
@@ -1218,21 +1337,31 @@ export default withStyles(
} else if (myTrackPosition > dragState.from && myTrackPosition <= dragState.to) { } else if (myTrackPosition > dragState.from && myTrackPosition <= dragState.to) {
dragOffset = -dragState.height; dragOffset = -dragState.height;
} }
} else {
dragOffset = dragState.dragElementDy + 5;
dragLeft = 5;
zIndex = 1000;
background = isDarkMode() ? "#555" : "#EEF";
} }
} }
let dragButtonStyle: React.CSSProperties = {
width: columnWidth, flex: "0 0 auto", height: (value.metadata && !compactVertical) ? 64 : 48,
position: "relative",
top: dragOffset,
left: dragLeft,
zIndex: zIndex,
background: background,
};
return ( return (
<DraggableButtonBase key={value.pathname} <DraggableButtonBase key={value.pathname}
longPressDelay={this.state.reordering ? 0 : undefined} longPressDelay={this.state.reordering ? 300 : undefined}
data-position={dataPosition} data-position={dataPosition}
data-pathname={ data-pathname={
value.metadata ? value.metadata.fileName : null value.metadata ? value.metadata.fileName : null
} }
instantMouseLongPress={this.state.reordering}
style={{ style={dragButtonStyle}
width: columnWidth, flex: "0 0 auto", height: (value.metadata && !compactVertical) ? 64 : 48,
position: "relative",
top: dragOffset + "px",
}}
onClick={(e) => this.handleFileClick(e, value)} onClick={(e) => this.handleFileClick(e, value)}
onDoubleClick={() => { this.onDoubleClickValue(value.pathname); }} onDoubleClick={() => { this.onDoubleClickValue(value.pathname); }}
@@ -1559,7 +1688,7 @@ export default withStyles(
await this.model.renameFilePropertyFile(oldFilePath, newFilePath, this.props.fileProperty); await this.model.renameFilePropertyFile(oldFilePath, newFilePath, this.props.fileProperty);
let index = newFileList.indexOf(file); let index = newFileList.indexOf(file);
if (index !== -1) { if (index !== -1) {
newFileList.splice(index,1); newFileList.splice(index, 1);
} }
} }
@@ -1570,8 +1699,7 @@ export default withStyles(
if (!this.mounted) { if (!this.mounted) {
return; return;
} }
if (newFileList.length === 0 ) if (newFileList.length === 0) {
{
this.setState({ this.setState({
multiSelect: false, multiSelect: false,
selectedFiles: [] selectedFiles: []
+10 -10
View File
@@ -81,7 +81,7 @@ function ToolTipEx(props: ToolTipExProps) {
if (valueTooltip === undefined) // no timeout if there's a value tooltip if (valueTooltip === undefined) // no timeout if there's a value tooltip
{ {
if (t > 0) { if (t > 0) {
console.log("ToolTipEx: starting timeout for ", t); // console.log("ToolTipEx: starting timeout for ", t);
handle = window.setTimeout(() => { handle = window.setTimeout(() => {
setOpen(true); setOpen(true);
},t); },t);
@@ -89,7 +89,7 @@ function ToolTipEx(props: ToolTipExProps) {
} }
return () => { return () => {
if (handle !== null) { if (handle !== null) {
console.log("ToolTipEx: clearing timeout for ", t); // console.log("ToolTipEx: clearing timeout for ", t);
window.clearTimeout(handle); window.clearTimeout(handle);
} }
}; };
@@ -181,39 +181,39 @@ function ToolTipEx(props: ToolTipExProps) {
return ( return (
<div <div
onClickCapture={(e) => { onClickCapture={(e) => {
console.log("ToolTipEx: onClickCapture"); // console.log("ToolTipEx: onClickCapture");
handleClickCapture(e); handleClickCapture(e);
}} }}
onMouseEnter={(e)=> { onMouseEnter={(e)=> {
console.log("ToolTipEx: onMouseEnter"); // console.log("ToolTipEx: onMouseEnter");
handleMouseEnter(e); handleMouseEnter(e);
}} }}
onMouseLeave={(e)=> { onMouseLeave={(e)=> {
console.log("ToolTipEx: onMouseLeave"); // console.log("ToolTipEx: onMouseLeave");
handleMouseLeave(e); handleMouseLeave(e);
}} }}
onPointerCancelCapture={(e) => { onPointerCancelCapture={(e) => {
console.log("ToolTipEx: onPointerCancelCapture"); // console.log("ToolTipEx: onPointerCancelCapture");
handlePointerCancel(e); handlePointerCancel(e);
}} }}
onContextMenuCapture={(e) => { onContextMenuCapture={(e) => {
console.log("ToolTipEx: onContextMenuCapture"); // console.log("ToolTipEx: onContextMenuCapture");
handleConextMenu(e); handleConextMenu(e);
return false; return false;
}} }}
onPointerDownCapture={(e) => { onPointerDownCapture={(e) => {
console.log("ToolTipEx: onPointerDownCapture"); // console.log("ToolTipEx: onPointerDownCapture");
handlePointerDownCapture(e); handlePointerDownCapture(e);
}} }}
onPointerMoveCapture={(e) => { onPointerMoveCapture={(e) => {
console.log("ToolTipEx: onPointerMoveCapture"); // console.log("ToolTipEx: onPointerMoveCapture");
handlePointerMoveCapture(e); handlePointerMoveCapture(e);
}} }}
onPointerUpCapture={(e) => { onPointerUpCapture={(e) => {
console.log("ToolTipEx: onPointerUpCapture"); // console.log("ToolTipEx: onPointerUpCapture");
handlePointerUpCapture(e); handlePointerUpCapture(e);
}} }}
> >