feat: support src collaborators (#5114)
* feat: support avatarURLfor collaborators * fix * better avatars :) * use position fixed for tooltips so it renders correctly when offsets updated * update docs * Update src/excalidraw-app/collab/CollabWrapper.tsx * rename avatarUrl to src
This commit is contained in:
parent
22b2e10ddb
commit
9e6d5fdbcb
@ -1,4 +1,4 @@
|
||||
import { getClientColors, getClientInitials } from "../clients";
|
||||
import { getClientColors } from "../clients";
|
||||
import { Avatar } from "../components/Avatar";
|
||||
import { centerScrollOn } from "../scene/scroll";
|
||||
import { Collaborator } from "../types";
|
||||
@ -43,16 +43,15 @@ export const actionGoToCollaborator = register({
|
||||
}
|
||||
|
||||
const { background, stroke } = getClientColors(clientId, appState);
|
||||
const shortName = getClientInitials(collaborator.username);
|
||||
|
||||
return (
|
||||
<Avatar
|
||||
color={background}
|
||||
border={stroke}
|
||||
onClick={() => updateData(collaborator.pointer)}
|
||||
>
|
||||
{shortName}
|
||||
</Avatar>
|
||||
name={collaborator.username || ""}
|
||||
src={collaborator.src}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -12,5 +12,11 @@
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
|
||||
&-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,28 @@
|
||||
import "./Avatar.scss";
|
||||
|
||||
import React from "react";
|
||||
import { getClientInitials } from "../clients";
|
||||
|
||||
type AvatarProps = {
|
||||
children: string;
|
||||
onClick: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||
color: string;
|
||||
border: string;
|
||||
name: string;
|
||||
src?: string;
|
||||
};
|
||||
|
||||
export const Avatar = ({ children, color, border, onClick }: AvatarProps) => (
|
||||
<div
|
||||
className="Avatar"
|
||||
style={{ background: color, border: `1px solid ${border}` }}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
export const Avatar = ({ color, border, onClick, name, src }: AvatarProps) => {
|
||||
const shortName = getClientInitials(name);
|
||||
const style = src
|
||||
? undefined
|
||||
: { background: color, border: `1px solid ${border}` };
|
||||
return (
|
||||
<div className="Avatar" style={style} onClick={onClick}>
|
||||
{src ? (
|
||||
<img className="Avatar-img" src={src} alt={shortName} />
|
||||
) : (
|
||||
shortName
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// container in body where the actual tooltip is appended to
|
||||
.excalidraw-tooltip {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
|
||||
padding: 8px;
|
||||
|
@ -17,6 +17,7 @@ Please add the latest change on the top under the correct section.
|
||||
|
||||
#### Features
|
||||
|
||||
- Support [`src`](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L50) for collaborators. Now onwards host can pass `src` to render the customized avatar for collaborators [#5114](https://github.com/excalidraw/excalidraw/pull/5114).
|
||||
- Support `libraryItems` argument in `initialData.libraryItems` and `updateScene({ libraryItems })` to be a Promise resolving to `LibraryItems`, and support functional update of `libraryItems` in [`updateScene({ libraryItems })`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#updateScene). [#5101](https://github.com/excalidraw/excalidraw/pull/5101).
|
||||
- Expose util [`mergeLibraryItems`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#mergeLibraryItems) [#5101](https://github.com/excalidraw/excalidraw/pull/5101).
|
||||
- Expose util [`exportToClipboard`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToClipboard) which allows to copy the scene contents to clipboard as `svg`, `png` or `json` [#5103](https://github.com/excalidraw/excalidraw/pull/5103).
|
||||
|
@ -512,7 +512,7 @@ You can use this function to update the scene with the sceneData. It accepts the
|
||||
| --- | --- | --- |
|
||||
| `elements` | [`ImportedDataState["elements"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L17) | The `elements` to be updated in the scene |
|
||||
| `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L18) | The `appState` to be updated in the scene. |
|
||||
| `collaborators` | <pre>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L29">Collaborator></a></pre> | The list of collaborators to be updated in the scene. |
|
||||
| `collaborators` | <pre>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L35">Collaborator></a></pre> | The list of collaborators to be updated in the scene. |
|
||||
| `commitToHistory` | `boolean` | Implies if the `history (undo/redo)` should be recorded. Defaults to `false`. |
|
||||
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200) | Promise<[LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200)> | ((currentItems: [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200)>) => [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200) | Promise<[LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200)>) | The `libraryItems` to be update in the scene. |
|
||||
|
||||
|
@ -31,7 +31,10 @@ const resolvablePromise = () => {
|
||||
|
||||
const renderTopRightUI = () => {
|
||||
return (
|
||||
<button onClick={() => alert("This is dummy top right UI")}>
|
||||
<button
|
||||
onClick={() => alert("This is dummy top right UI")}
|
||||
style={{ height: "2.5rem" }}
|
||||
>
|
||||
{" "}
|
||||
Click me{" "}
|
||||
</button>
|
||||
@ -58,6 +61,7 @@ export default function App() {
|
||||
const [exportWithDarkMode, setExportWithDarkMode] = useState(false);
|
||||
const [exportEmbedScene, setExportEmbedScene] = useState(false);
|
||||
const [theme, setTheme] = useState("light");
|
||||
const [isCollaborating, setIsCollaborating] = useState(false);
|
||||
|
||||
const initialStatePromiseRef = useRef({ promise: null });
|
||||
if (!initialStatePromiseRef.current.promise) {
|
||||
@ -228,6 +232,36 @@ export default function App() {
|
||||
/>
|
||||
Switch to Dark Theme
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isCollaborating}
|
||||
onChange={() => {
|
||||
if (!isCollaborating) {
|
||||
const collaborators = new Map();
|
||||
collaborators.set("id1", {
|
||||
username: "Doremon",
|
||||
src: "doremon.png",
|
||||
});
|
||||
collaborators.set("id2", {
|
||||
username: "Excalibot",
|
||||
src: "https://avatars.githubusercontent.com/excalibot",
|
||||
});
|
||||
collaborators.set("id3", {
|
||||
username: "Pika",
|
||||
src: "pika.jpeg",
|
||||
});
|
||||
excalidrawRef.current.updateScene({ collaborators });
|
||||
} else {
|
||||
excalidrawRef.current.updateScene({
|
||||
collaborators: new Map(),
|
||||
});
|
||||
}
|
||||
setIsCollaborating(!isCollaborating);
|
||||
}}
|
||||
/>
|
||||
Show collaborators
|
||||
</label>
|
||||
<div>
|
||||
<button onClick={onCopy.bind(null, "png")}>
|
||||
Copy to Clipboard as PNG
|
||||
|
BIN
src/packages/excalidraw/example/public/doremon.png
Normal file
BIN
src/packages/excalidraw/example/public/doremon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 KiB |
BIN
src/packages/excalidraw/example/public/pika.jpeg
Normal file
BIN
src/packages/excalidraw/example/public/pika.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
@ -45,6 +45,9 @@ export type Collaborator = {
|
||||
background: string;
|
||||
stroke: string;
|
||||
};
|
||||
// The url of the collaborator's avatar, defaults to username intials
|
||||
// if not present
|
||||
src?: string;
|
||||
};
|
||||
|
||||
export type DataURL = string & { _brand: "DataURL" };
|
||||
|
Loading…
x
Reference in New Issue
Block a user