Finishing up some TODOs + cleanup.
This commit is contained in:
parent
33b78c35ea
commit
6354501cca
@ -24,6 +24,7 @@
|
|||||||
&__label {
|
&__label {
|
||||||
display: flex;
|
display: flex;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__username {
|
&__username {
|
||||||
|
@ -72,6 +72,13 @@
|
|||||||
padding: 0.25rem 0.5rem;
|
padding: 0.25rem 0.5rem;
|
||||||
border-top: 1px solid var(--userlist-collaborators-border-color);
|
border-top: 1px solid var(--userlist-collaborators-border-color);
|
||||||
border-bottom: 1px solid var(--userlist-collaborators-border-color);
|
border-bottom: 1px solid var(--userlist-collaborators-border-color);
|
||||||
|
|
||||||
|
&__empty {
|
||||||
|
color: var(--color-gray-60);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 150%;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.UserList__hint {
|
.UserList__hint {
|
||||||
@ -94,12 +101,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.UserList__search-wrapper {
|
||||||
|
position: relative;
|
||||||
|
height: 2.5rem;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
left: 0.75rem;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
color: var(--color-gray-40);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.UserList__search {
|
.UserList__search {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
|
padding-left: 2.5rem !important;
|
||||||
|
padding-right: 0.75rem !important;
|
||||||
|
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: var(--color-gray-40);
|
color: var(--color-gray-40);
|
||||||
|
@ -9,7 +9,12 @@ import { ActionManager } from "../actions/manager";
|
|||||||
|
|
||||||
import * as Popover from "@radix-ui/react-popover";
|
import * as Popover from "@radix-ui/react-popover";
|
||||||
import { Island } from "./Island";
|
import { Island } from "./Island";
|
||||||
|
import { searchIcon } from "./icons";
|
||||||
|
import { t } from "../i18n";
|
||||||
|
|
||||||
|
// TODO follow-participant
|
||||||
|
// can be used for debugging styling, filter, etc
|
||||||
|
// don't forget to remove it before shipping
|
||||||
const sampleCollaborators = new Map([
|
const sampleCollaborators = new Map([
|
||||||
[
|
[
|
||||||
"client-id-1",
|
"client-id-1",
|
||||||
@ -70,6 +75,7 @@ const sampleCollaborators = new Map([
|
|||||||
]) as any as Map<string, Collaborator>;
|
]) as any as Map<string, Collaborator>;
|
||||||
|
|
||||||
const FIRST_N_AVATARS = 3;
|
const FIRST_N_AVATARS = 3;
|
||||||
|
const SHOW_COLLABORATORS_FILTER_AT = 6;
|
||||||
|
|
||||||
const ConditionalTooltipWrapper = ({
|
const ConditionalTooltipWrapper = ({
|
||||||
shouldWrap,
|
shouldWrap,
|
||||||
@ -132,16 +138,19 @@ export const UserList = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const actionManager = useExcalidrawActionManager();
|
const actionManager = useExcalidrawActionManager();
|
||||||
|
|
||||||
// const uniqueCollaboratorsMap = new Map<string, Collaborator>();
|
const uniqueCollaboratorsMap = React.useMemo(() => {
|
||||||
// collaborators.forEach((collaborator, socketId) => {
|
const map = new Map<string, Collaborator>();
|
||||||
// uniqueCollaboratorsMap.set(
|
collaborators.forEach((collaborator, socketId) => {
|
||||||
// // filter on user id, else fall back on unique socketId
|
map.set(
|
||||||
// collaborator.id || socketId,
|
// filter on user id, else fall back on unique socketId
|
||||||
// collaborator,
|
collaborator.id || socketId,
|
||||||
// );
|
collaborator,
|
||||||
// });
|
);
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}, [collaborators]);
|
||||||
|
|
||||||
const uniqueCollaboratorsMap = sampleCollaborators;
|
// const uniqueCollaboratorsMap = sampleCollaborators;
|
||||||
const uniqueCollaboratorsArray = React.useMemo(
|
const uniqueCollaboratorsArray = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
Array.from(uniqueCollaboratorsMap).filter(
|
Array.from(uniqueCollaboratorsMap).filter(
|
||||||
@ -210,20 +219,27 @@ export const UserList = ({
|
|||||||
sideOffset={10}
|
sideOffset={10}
|
||||||
>
|
>
|
||||||
<Island style={{ overflow: "hidden" }}>
|
<Island style={{ overflow: "hidden" }}>
|
||||||
{/* TODO follow-participant add search icon */}
|
{SHOW_COLLABORATORS_FILTER_AT <=
|
||||||
<div>
|
uniqueCollaboratorsArray.length && (
|
||||||
<input
|
<div className="UserList__search-wrapper">
|
||||||
className="UserList__search"
|
{searchIcon}
|
||||||
type="text"
|
<input
|
||||||
placeholder="Search"
|
className="UserList__search"
|
||||||
value={searchTerm}
|
type="text"
|
||||||
onChange={(e) => {
|
placeholder={t("userList.search.placeholder")}
|
||||||
setSearchTerm(e.target.value);
|
value={searchTerm}
|
||||||
}}
|
onChange={(e) => {
|
||||||
/>
|
setSearchTerm(e.target.value);
|
||||||
</div>
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="dropdown-menu UserList__collaborators">
|
<div className="dropdown-menu UserList__collaborators">
|
||||||
{/* TODO follow-participant empty state */}
|
{filteredCollaborators.length === 0 && (
|
||||||
|
<div className="UserList__collaborators__empty">
|
||||||
|
{t("userList.search.empty")}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{filteredCollaborators.map(([clientId, collaborator]) =>
|
{filteredCollaborators.map(([clientId, collaborator]) =>
|
||||||
renderCollaborator({
|
renderCollaborator({
|
||||||
actionManager,
|
actionManager,
|
||||||
@ -233,12 +249,12 @@ export const UserList = ({
|
|||||||
}),
|
}),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* TODO follow-participant */}
|
|
||||||
<div className="UserList__hint">
|
<div className="UserList__hint">
|
||||||
<div className="UserList__hint-heading">TODO hint</div>
|
<div className="UserList__hint-heading">
|
||||||
|
{t("userList.hint.heading")}
|
||||||
|
</div>
|
||||||
<div className="UserList__hint-text">
|
<div className="UserList__hint-text">
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
{t("userList.hint.text")}
|
||||||
Quibusdam, ipsum!
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Island>
|
</Island>
|
||||||
|
@ -1647,3 +1647,12 @@ export const frameToolIcon = createIcon(
|
|||||||
</g>,
|
</g>,
|
||||||
tablerIconProps,
|
tablerIconProps,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const searchIcon = createIcon(
|
||||||
|
<g strokeWidth={1.5}>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" />
|
||||||
|
<path d="M21 21l-6 -6" />
|
||||||
|
</g>,
|
||||||
|
tablerIconProps,
|
||||||
|
);
|
||||||
|
@ -480,5 +480,15 @@
|
|||||||
"description": "Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below."
|
"description": "Loading external drawing will <bold>replace your existing content</bold>.<br></br>You can back up your drawing first by using one of the options below."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"userList": {
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Quick search",
|
||||||
|
"empty": "No users found"
|
||||||
|
},
|
||||||
|
"hint": {
|
||||||
|
"heading": "Follow mode",
|
||||||
|
"text": "You can click on a user to toggle follow mode. In follow mode, their canvas movements will be mirrored on your canvas."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user