Implemented some TODOs.
This commit is contained in:
parent
a576b0e3b5
commit
b4867cb3dc
@ -100,6 +100,7 @@ export const getDefaultAppState = (): Omit<
|
||||
selectedLinearElement: null,
|
||||
userToFollow: null,
|
||||
shouldDisconnectFollowModeOnCanvasInteraction: true,
|
||||
amIBeingFollowed: false,
|
||||
};
|
||||
};
|
||||
|
||||
@ -212,6 +213,7 @@ const APP_STATE_STORAGE_CONF = (<
|
||||
export: false,
|
||||
server: false,
|
||||
},
|
||||
amIBeingFollowed: { browser: false, export: false, server: false },
|
||||
});
|
||||
|
||||
const _clearAppStateForStorage = <
|
||||
|
@ -1543,14 +1543,14 @@ class App extends React.Component<AppProps, AppState> {
|
||||
if (prevState.userToFollow) {
|
||||
this.props?.onUserFollowed?.({
|
||||
userToFollow: prevState.userToFollow,
|
||||
action: "unsubscribe",
|
||||
action: "unfollow",
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.userToFollow) {
|
||||
this.props?.onUserFollowed?.({
|
||||
userToFollow: this.state.userToFollow,
|
||||
action: "subscribe",
|
||||
action: "follow",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
import throttle from "lodash.throttle";
|
||||
import { PureComponent } from "react";
|
||||
import { AppState, ExcalidrawImperativeAPI, UserToFollow } from "../../types";
|
||||
import {
|
||||
AppState,
|
||||
ExcalidrawImperativeAPI,
|
||||
OnUserFollowedPayload,
|
||||
} from "../../types";
|
||||
import { ErrorDialog } from "../../components/ErrorDialog";
|
||||
import { APP_NAME, ENV, EVENT } from "../../constants";
|
||||
import { ImportedDataState } from "../../data/types";
|
||||
@ -541,12 +545,8 @@ class Collab extends PureComponent<Props, CollabState> {
|
||||
case "SCROLL_AND_ZOOM": {
|
||||
const { bounds } = decryptedData.payload;
|
||||
|
||||
const socketId: SocketUpdateDataSource["SCROLL_AND_ZOOM"]["payload"]["socketId"] =
|
||||
decryptedData.payload.socketId;
|
||||
|
||||
const _appState = this.excalidrawAPI.getAppState();
|
||||
// TODO follow-participant
|
||||
// if (_appState.userToFollow?.clientId === socketId) {
|
||||
|
||||
const { appState } = zoomToFitBounds({
|
||||
appState: _appState,
|
||||
bounds,
|
||||
@ -554,7 +554,6 @@ class Collab extends PureComponent<Props, CollabState> {
|
||||
viewportZoomFactor: 1,
|
||||
});
|
||||
this.excalidrawAPI.updateScene({ appState });
|
||||
// }
|
||||
|
||||
break;
|
||||
}
|
||||
@ -585,15 +584,16 @@ class Collab extends PureComponent<Props, CollabState> {
|
||||
scenePromise.resolve(sceneData);
|
||||
});
|
||||
|
||||
// TODO follow-participant
|
||||
// set amIBeingFollowed flag
|
||||
this.portal.socket.on("broadcast-follow", () => {
|
||||
console.log("broadcast-follow");
|
||||
this.excalidrawAPI.updateScene({
|
||||
appState: { amIBeingFollowed: true },
|
||||
});
|
||||
});
|
||||
// TODO follow-participant
|
||||
// set amIBeingFollowed flag
|
||||
|
||||
this.portal.socket.on("broadcast-unfollow", () => {
|
||||
console.log("broadcast-unfollow");
|
||||
this.excalidrawAPI.updateScene({
|
||||
appState: { amIBeingFollowed: false },
|
||||
});
|
||||
});
|
||||
|
||||
this.initializeIdleDetector();
|
||||
@ -803,48 +803,44 @@ class Collab extends PureComponent<Props, CollabState> {
|
||||
CURSOR_SYNC_TIMEOUT,
|
||||
);
|
||||
|
||||
// TODO follow-participant
|
||||
// only calculate this + broadcast if some flag on appState is set
|
||||
// (eg amIBeingFollowed)
|
||||
onScrollAndZoomChange = throttle(
|
||||
(payload: { zoom: AppState["zoom"]; scroll: { x: number; y: number } }) => {
|
||||
const appState = this.excalidrawAPI.getAppState();
|
||||
|
||||
const { x: x1, y: y1 } = viewportCoordsToSceneCoords(
|
||||
{ clientX: 0, clientY: 0 },
|
||||
{
|
||||
offsetLeft: appState.offsetLeft,
|
||||
offsetTop: appState.offsetTop,
|
||||
scrollX: payload.scroll.x,
|
||||
scrollY: payload.scroll.y,
|
||||
zoom: payload.zoom,
|
||||
},
|
||||
);
|
||||
|
||||
const { x: x2, y: y2 } = viewportCoordsToSceneCoords(
|
||||
{ clientX: appState.width, clientY: appState.height },
|
||||
{
|
||||
offsetLeft: appState.offsetLeft,
|
||||
offsetTop: appState.offsetTop,
|
||||
scrollX: payload.scroll.x,
|
||||
scrollY: payload.scroll.y,
|
||||
zoom: payload.zoom,
|
||||
},
|
||||
);
|
||||
|
||||
this.portal.socket &&
|
||||
this.portal.broadcastScrollAndZoom(
|
||||
{ bounds: [x1, y1, x2, y2] },
|
||||
// TODO follow-participant
|
||||
`follow_${this.portal.socket.id}`,
|
||||
if (appState.amIBeingFollowed) {
|
||||
const { x: x1, y: y1 } = viewportCoordsToSceneCoords(
|
||||
{ clientX: 0, clientY: 0 },
|
||||
{
|
||||
offsetLeft: appState.offsetLeft,
|
||||
offsetTop: appState.offsetTop,
|
||||
scrollX: payload.scroll.x,
|
||||
scrollY: payload.scroll.y,
|
||||
zoom: payload.zoom,
|
||||
},
|
||||
);
|
||||
|
||||
const { x: x2, y: y2 } = viewportCoordsToSceneCoords(
|
||||
{ clientX: appState.width, clientY: appState.height },
|
||||
{
|
||||
offsetLeft: appState.offsetLeft,
|
||||
offsetTop: appState.offsetTop,
|
||||
scrollX: payload.scroll.x,
|
||||
scrollY: payload.scroll.y,
|
||||
zoom: payload.zoom,
|
||||
},
|
||||
);
|
||||
|
||||
this.portal.socket &&
|
||||
this.portal.broadcastScrollAndZoom(
|
||||
{ bounds: [x1, y1, x2, y2] },
|
||||
// TODO follow-participant
|
||||
`follow_${this.portal.socket.id}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
onUserFollowed = (payload: {
|
||||
userToFollow: UserToFollow;
|
||||
action: "subscribe" | "unsubscribe";
|
||||
}) => {
|
||||
onUserFollowed = (payload: OnUserFollowedPayload) => {
|
||||
this.portal.socket && this.portal.broadcastUserFollowed(payload);
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
FILE_UPLOAD_TIMEOUT,
|
||||
WS_SCENE_EVENT_TYPES,
|
||||
} from "../app_constants";
|
||||
import { UserIdleState, UserToFollow } from "../../types";
|
||||
import { OnUserFollowedPayload, UserIdleState } from "../../types";
|
||||
import { trackEvent } from "../../analytics";
|
||||
import throttle from "lodash.throttle";
|
||||
import { newElementWith } from "../../element/mutateElement";
|
||||
@ -248,10 +248,7 @@ class Portal {
|
||||
}
|
||||
};
|
||||
|
||||
broadcastUserFollowed = (payload: {
|
||||
userToFollow: UserToFollow;
|
||||
action: "subscribe" | "unsubscribe";
|
||||
}) => {
|
||||
broadcastUserFollowed = (payload: OnUserFollowedPayload) => {
|
||||
if (this.socket?.id) {
|
||||
this.socket?.emit("on-user-follow", payload);
|
||||
}
|
||||
|
14
src/types.ts
14
src/types.ts
@ -229,6 +229,8 @@ export type AppState = {
|
||||
userToFollow: UserToFollow | null;
|
||||
/** whether follow mode should be disconnected when the non-remote user interacts with the canvas */
|
||||
shouldDisconnectFollowModeOnCanvasInteraction: boolean;
|
||||
/** whether the user is being followed on the canvas */
|
||||
amIBeingFollowed: boolean;
|
||||
};
|
||||
|
||||
export type UIAppState = Omit<
|
||||
@ -313,6 +315,11 @@ export type ExcalidrawInitialDataState = Merge<
|
||||
}
|
||||
>;
|
||||
|
||||
export type OnUserFollowedPayload = {
|
||||
userToFollow: UserToFollow;
|
||||
action: "follow" | "unfollow";
|
||||
};
|
||||
|
||||
export interface ExcalidrawProps {
|
||||
onChange?: (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
@ -373,12 +380,7 @@ export interface ExcalidrawProps {
|
||||
zoom: Zoom;
|
||||
scroll: { x: number; y: number };
|
||||
}) => void;
|
||||
// TODO follow-participant
|
||||
onUserFollowed?: (payload: {
|
||||
userToFollow: UserToFollow;
|
||||
// TODO follow-participant extract to own type
|
||||
action: "subscribe" | "unsubscribe";
|
||||
}) => void;
|
||||
onUserFollowed?: (payload: OnUserFollowedPayload) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user