Broadcast mouse activity (#1175)

* broadcast mouse activity

* move to same MOUSE_LOCATION event

* remove key up handler

* update tests

* Fix border

* refactor

* rename activity to button

Co-authored-by: Panayiotis Lipiridis <lipiridis@gmail.com>
This commit is contained in:
Kostas Bariotis 2020-04-04 16:12:19 +01:00 committed by GitHub
parent 23540eba4c
commit b97520400a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 116 additions and 14 deletions

View file

@ -441,6 +441,10 @@ export class App extends React.Component<any, AppState> {
if (this.state.isCollaborating && !this.socket) {
this.initializeSocketClient({ showLoadingState: true });
}
const cursorButton: {
[id: string]: string | undefined;
} = {};
const pointerViewportCoords: SceneState["remotePointerViewportCoords"] = {};
const remoteSelectedElementIds: SceneState["remoteSelectedElementIds"] = {};
this.state.collaborators.forEach((user, socketID) => {
@ -464,6 +468,7 @@ export class App extends React.Component<any, AppState> {
this.canvas,
window.devicePixelRatio,
);
cursorButton[socketID] = user.button;
});
const { atLeastOneVisibleElement, scrollBars } = renderScene(
globalSceneState.getAllElements().filter((element) => {
@ -486,6 +491,7 @@ export class App extends React.Component<any, AppState> {
viewBackgroundColor: this.state.viewBackgroundColor,
zoom: this.state.zoom,
remotePointerViewportCoords: pointerViewportCoords,
remotePointerButton: cursorButton,
remoteSelectedElementIds: remoteSelectedElementIds,
shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,
},
@ -871,6 +877,7 @@ export class App extends React.Component<any, AppState> {
const {
socketID,
pointerCoords,
button,
selectedElementIds,
} = decryptedData.payload;
this.setState((state) => {
@ -879,6 +886,7 @@ export class App extends React.Component<any, AppState> {
}
const user = state.collaborators.get(socketID)!;
user.pointer = pointerCoords;
user.button = button;
user.selectedElementIds = selectedElementIds;
state.collaborators.set(socketID, user);
return state;
@ -923,6 +931,7 @@ export class App extends React.Component<any, AppState> {
private broadcastMouseLocation = (payload: {
pointerCoords: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointerCoords"];
button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"];
}) => {
if (this.socket?.id) {
const data: SocketUpdateDataSource["MOUSE_LOCATION"] = {
@ -930,6 +939,7 @@ export class App extends React.Component<any, AppState> {
payload: {
socketID: this.socket.id,
pointerCoords: payload.pointerCoords,
button: payload.button || "up",
selectedElementIds: this.state.selectedElementIds,
},
};
@ -1345,13 +1355,8 @@ export class App extends React.Component<any, AppState> {
private handleCanvasPointerMove = (
event: React.PointerEvent<HTMLCanvasElement>,
) => {
const pointerCoords = viewportCoordsToSceneCoords(
event,
this.state,
this.canvas,
window.devicePixelRatio,
);
this.savePointer(pointerCoords);
this.savePointer(event.clientX, event.clientY, this.state.cursorButton);
if (gesture.pointers.has(event.pointerId)) {
gesture.pointers.set(event.pointerId, {
x: event.clientX,
@ -1502,7 +1507,11 @@ export class App extends React.Component<any, AppState> {
return;
}
this.setState({ lastPointerDownWith: event.pointerType });
this.setState({
lastPointerDownWith: event.pointerType,
cursorButton: "down",
});
this.savePointer(event.clientX, event.clientY, "down");
// pan canvas on wheel button drag or space+drag
if (
@ -1535,6 +1544,10 @@ export class App extends React.Component<any, AppState> {
if (!isHoldingSpace) {
setCursorForShape(this.state.elementType);
}
this.setState({
cursorButton: "up",
});
this.savePointer(event.clientX, event.clientY, "up");
window.removeEventListener("pointermove", onPointerMove);
window.removeEventListener("pointerup", teardown);
window.removeEventListener("blur", teardown);
@ -1635,6 +1648,10 @@ export class App extends React.Component<any, AppState> {
isDraggingScrollBar = false;
setCursorForShape(this.state.elementType);
lastPointerUp = null;
this.setState({
cursorButton: "up",
});
this.savePointer(event.clientX, event.clientY, "up");
window.removeEventListener("pointermove", onPointerMove);
window.removeEventListener("pointerup", onPointerUp);
});
@ -2398,7 +2415,7 @@ export class App extends React.Component<any, AppState> {
}
});
const onPointerUp = withBatchedUpdates((event: PointerEvent) => {
const onPointerUp = withBatchedUpdates((childEvent: PointerEvent) => {
const {
draggingElement,
resizingElement,
@ -2412,11 +2429,15 @@ export class App extends React.Component<any, AppState> {
isRotating: false,
resizingElement: null,
selectionElement: null,
cursorButton: "up",
editingElement: multiElement ? this.state.editingElement : null,
});
this.savePointer(childEvent.clientX, childEvent.clientY, "up");
resizeArrowFn = null;
lastPointerUp = null;
window.removeEventListener("pointermove", onPointerMove);
window.removeEventListener("pointerup", onPointerUp);
@ -2426,7 +2447,7 @@ export class App extends React.Component<any, AppState> {
}
if (!draggingOccurred && draggingElement && !multiElement) {
const { x, y } = viewportCoordsToSceneCoords(
event,
childEvent,
this.state,
this.canvas,
window.devicePixelRatio,
@ -2503,7 +2524,7 @@ export class App extends React.Component<any, AppState> {
// was added to selection (on pointerdown phase) we need to keep
// selection unchanged
if (hitElement && !draggingOccurred && !hitElementWasAddedToSelection) {
if (event.shiftKey) {
if (childEvent.shiftKey) {
this.setState((prevState) => ({
selectedElementIds: {
...prevState.selectedElementIds,
@ -2735,12 +2756,26 @@ export class App extends React.Component<any, AppState> {
}
}
private savePointer = (pointerCoords: { x: number; y: number }) => {
private savePointer = (x: number, y: number, button: "up" | "down") => {
if (!x || !y) {
return;
}
const pointerCoords = viewportCoordsToSceneCoords(
{ clientX: x, clientY: y },
this.state,
this.canvas,
window.devicePixelRatio,
);
if (isNaN(pointerCoords.x) || isNaN(pointerCoords.y)) {
// sometimes the pointer goes off screen
return;
}
this.socket && this.broadcastMouseLocation({ pointerCoords });
this.socket &&
this.broadcastMouseLocation({
pointerCoords,
button,
});
};
private resetShouldCacheIgnoreZoomDebounced = debounce(() => {