Remove react-simple-dropdown

This commit is contained in:
Jeremie Pardou-Piquemal 2022-12-18 22:03:18 +01:00
parent 8fe8abdcfc
commit 7fd5699bef
9 changed files with 202 additions and 388 deletions

View File

@ -13,6 +13,7 @@
],
"license": "MIT",
"dependencies": {
"@react-hookz/web": "^20.0.2",
"bootstrap": "^4.6.2",
"classnames": "^2.3.2",
"jquery": "3",
@ -27,7 +28,6 @@
"react-redux": "^8.0.5",
"react-router": "^6.4.4",
"react-router-dom": "^6.4.4",
"react-simple-dropdown": "^3.2.3",
"react-tooltip": "^5.2.0",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { defer } from 'lodash';
import { useSafeState, useEventListener } from '@react-hookz/web/esnext';
import ChatInput from '@/components/Chat';
import T from '@/components/T';
@ -10,39 +11,28 @@ import styles from './styles.module.scss';
const ActivityList = ({ activities, openModal }) => {
const [focusChat, setFocusChat] = React.useState(false);
const [scrolledToBottom, setScrolledToBottom] = React.useState(true);
const [scrolledToBottom, setScrolledToBottom] = useSafeState(true);
const messageStream = React.useRef(null);
const activitiesList = React.useRef(null);
React.useEffect(() => {
const currentMessageStream = messageStream.current;
useEventListener(messageStream, 'scroll', () => {
const messageStreamHeight = messageStream.current.clientHeight;
const activitiesListHeight = activitiesList.current.clientHeight;
// Update scrolledToBottom state if we scroll the activity stream
const onScroll = () => {
const messageStreamHeight = messageStream.current.clientHeight;
const activitiesListHeight = activitiesList.current.clientHeight;
const bodyRect = document.body.getBoundingClientRect();
const elemRect = activitiesList.current.getBoundingClientRect();
const offset = elemRect.top - bodyRect.top;
const activitiesListYPos = offset;
const bodyRect = document.body.getBoundingClientRect();
const elemRect = activitiesList.current.getBoundingClientRect();
const offset = elemRect.top - bodyRect.top;
const activitiesListYPos = offset;
const newScrolledToBottom = activitiesListHeight + (activitiesListYPos - 60) <= messageStreamHeight;
if (newScrolledToBottom) {
if (!scrolledToBottom) {
setScrolledToBottom(true);
}
} else if (scrolledToBottom) {
setScrolledToBottom(false);
const newScrolledToBottom = activitiesListHeight + (activitiesListYPos - 60) <= messageStreamHeight;
if (newScrolledToBottom) {
if (!scrolledToBottom) {
setScrolledToBottom(true);
}
};
currentMessageStream.addEventListener('scroll', onScroll);
return () => {
// Unbind event if component unmounted
currentMessageStream.removeEventListener('scroll', onScroll);
};
}, [scrolledToBottom]);
} else if (scrolledToBottom) {
setScrolledToBottom(false);
}
});
const scrollToBottomIfShould = React.useCallback(() => {
if (scrolledToBottom) {
@ -57,7 +47,7 @@ const ActivityList = ({ activities, openModal }) => {
const scrollToBottom = React.useCallback(() => {
messageStream.current.scrollTop = messageStream.current.scrollHeight;
setScrolledToBottom(true);
}, []);
}, [setScrolledToBottom]);
const handleChatClick = () => {
setFocusChat(true);

View File

@ -101,93 +101,43 @@ exports[`Connected Home component > should display 1`] = `
</button>
</span>
<div
class="dropdown members-dropdown"
class="members-menu"
>
<a
class="dropdown__trigger "
<button
class="btn btn-link btn-plain members-action"
title="Users"
>
<button
class="btn btn-link btn-plain members-action"
title="Users"
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
1
</span>
</a>
<div
class="dropdown__content "
>
<ul
class="plain"
>
<li>
<span
class="username"
style="color: rgb(159, 244, 144);"
>
shortidgenerated
</span>
<span
class="icon-container"
>
<span
class="me-icon-wrap"
title="Me"
>
<svg
class="me-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"
/>
<circle
cx="12"
cy="7"
r="4"
/>
</svg>
</span>
</span>
</li>
</ul>
</div>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
1
</span>
</div>
</div>
<button

View File

@ -54,54 +54,43 @@ exports[`Nav component is displaying 1`] = `
</button>
</span>
<div
class="dropdown members-dropdown"
class="members-menu"
>
<a
class="dropdown__trigger "
<button
class="btn btn-link btn-plain members-action"
title="Users"
>
<button
class="btn btn-link btn-plain members-action"
title="Users"
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
0
</span>
</a>
<div
class="dropdown__content "
>
<ul
class="plain"
/>
</div>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
0
</span>
</div>
</div>
<button
@ -292,99 +281,43 @@ exports[`Nav component is displaying with another configuration and can rerender
</button>
</span>
<div
class="dropdown members-dropdown"
class="members-menu"
>
<a
class="dropdown__trigger "
<button
class="btn btn-link btn-plain members-action"
title="Users"
>
<button
class="btn btn-link btn-plain members-action"
title="Users"
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
2
</span>
</a>
<div
class="dropdown__content "
>
<ul
class="plain"
>
<li>
<span
class="username"
style="color: rgb(192, 202, 249);"
>
alan
</span>
<span
class="icon-container"
>
<span
class="owner-icon-wrap"
>
<svg
class="owner-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
title="Owner"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
/>
</svg>
</span>
</span>
</li>
<li>
<span
class="username"
style="color: rgb(156, 252, 223);"
>
dan
</span>
<span
class="icon-container"
/>
</li>
</ul>
</div>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
2
</span>
</div>
</div>
<button
@ -575,99 +508,43 @@ exports[`Nav component is displaying with another configuration and can rerender
</button>
</span>
<div
class="dropdown members-dropdown"
class="members-menu"
>
<a
class="dropdown__trigger "
<button
class="btn btn-link btn-plain members-action"
title="Users"
>
<button
class="btn btn-link btn-plain members-action"
title="Users"
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<svg
class="users-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
2
</span>
</a>
<div
class="dropdown__content "
>
<ul
class="plain"
>
<li>
<span
class="username"
style="color: rgb(192, 202, 249);"
>
alan
</span>
<span
class="icon-container"
>
<span
class="owner-icon-wrap"
>
<svg
class="owner-icon"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
title="Owner"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<polygon
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
/>
</svg>
</span>
</span>
</li>
<li>
<span
class="username"
style="color: rgb(156, 252, 223);"
>
dan
</span>
<span
class="icon-container"
/>
</li>
</ul>
</div>
<path
d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"
/>
<circle
cx="9"
cy="7"
r="4"
/>
<path
d="M23 21v-2a4 4 0 0 0-3-3.87"
/>
<path
d="M16 3.13a4 4 0 0 1 0 7.75"
/>
</svg>
</button>
<span>
2
</span>
</div>
</div>
<button

View File

@ -2,25 +2,23 @@ import React from 'react';
import PropTypes from 'prop-types';
import { nanoid } from 'nanoid';
import { Info, Settings, PlusCircle, User, Users, Lock, Unlock, Star } from 'react-feather';
import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown';
import $ from 'jquery';
import { Tooltip } from 'react-tooltip';
import { useClickOutside, useSafeState } from '@react-hookz/web/esnext';
import logoImg from '@/img/logo.png';
import Username from '@/components/Username';
const Nav = ({ members, roomId, userId, roomLocked, toggleLockRoom, openModal, iAmOwner, translations }) => {
const [showCopyTooltip, setShowCopyTooltip] = React.useState(false);
const [showLockedTooltip, setShowLockedTooltip] = React.useState(false);
const mountedRef = React.useRef(true);
const [showCopyTooltip, setShowCopyTooltip] = useSafeState(false);
const [showLockedTooltip, setShowLockedTooltip] = useSafeState(false);
const [showMemberList, setShowMemberList] = useSafeState(false);
const userListRef = React.useRef(null);
const roomUrl = `${window.location.origin}/${roomId}`;
React.useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
useClickOutside(userListRef, () => {
setShowMemberList(false);
});
const newRoom = () => {
$('.navbar-collapse').collapse('hide');
@ -41,22 +39,18 @@ const Nav = ({ members, roomId, userId, roomLocked, toggleLockRoom, openModal, i
if (!iAmOwner) {
setShowLockedTooltip(true);
setTimeout(() => {
if (mountedRef.current) {
setShowLockedTooltip(false);
}
setShowLockedTooltip(false);
}, 2000);
return;
} else {
toggleLockRoom();
}
toggleLockRoom();
};
const handleCopy = async () => {
await navigator.clipboard.writeText(roomUrl);
setShowCopyTooltip(true);
setTimeout(() => {
if (mountedRef.current) {
setShowCopyTooltip(false);
}
setShowCopyTooltip(false);
}, 2000);
};
@ -101,16 +95,18 @@ const Nav = ({ members, roomId, userId, roomLocked, toggleLockRoom, openModal, i
/>
)}
</span>
<div className="members-menu" ref={userListRef}>
<button
className="btn btn-link btn-plain members-action"
title="Users"
onClick={() => setShowMemberList(prev => !prev)}
>
<Users className="users-icon" />
</button>
<span>{members.length}</span>
<Dropdown className="members-dropdown">
<DropdownTrigger>
<button className="btn btn-link btn-plain members-action" title="Users">
<Users className="users-icon" />
</button>
<span>{members.length}</span>
</DropdownTrigger>
<DropdownContent>
<ul className="plain">
{showMemberList && (
<ul className="member-list">
{members.map((member, index) => (
<li key={`user-${index}`}>
<Username username={member.username} />
@ -129,8 +125,8 @@ const Nav = ({ members, roomId, userId, roomLocked, toggleLockRoom, openModal, i
</li>
))}
</ul>
</DropdownContent>
</Dropdown>
)}
</div>
</div>
<button

View File

@ -1,4 +1,3 @@
import React from 'react';
import { render } from '@testing-library/react';
import { test, expect } from 'vitest';

View File

@ -5,7 +5,6 @@ import { nanoid } from 'nanoid';
import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-simple-dropdown/styles/Dropdown.css';
import './stylesheets/app.sass';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
import 'react-tooltip/dist/react-tooltip.css';

View File

@ -75,20 +75,19 @@ button.lock-room
padding: 0px 1rem
background: black
.members-dropdown
margin-left: 10px
.dropdown__trigger
.members-action
margin-right: 5px
.dropdown__content
.members-menu
position: relative
.members-action
margin-right: 5px
.member-list
position: absolute
background: black
border-radius: 3px
border: 1px solid $inactive
padding: 15px
width: 175px
left: -10px
left: -5px
top: 35px
ul
li
overflow: auto
height: 25px
@ -101,4 +100,4 @@ button.lock-room
.icon-container
float: right
.me-icon, .owner-icon
width: 15px
width: 15px

View File

@ -489,6 +489,18 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@react-hookz/deep-equal@^1.0.3":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@react-hookz/deep-equal/-/deep-equal-1.0.4.tgz#68a71f36cbc88724b3ce6f4036183778b6e7f282"
integrity sha512-N56fTrAPUDz/R423pag+n6TXWbvlBZDtTehaGFjK0InmN+V2OFWLE/WmORhmn6Ce7dlwH5+tQN1LJFw3ngTJVg==
"@react-hookz/web@^20.0.2":
version "20.0.2"
resolved "https://registry.yarnpkg.com/@react-hookz/web/-/web-20.0.2.tgz#6aab268ec74fedc3c3e43ee659b59dc40c2d9d05"
integrity sha512-OJdpUnF+0Ywg65LFTVmQz3uwscGG2CiDGUazda7YKwClyQVFjcEFNEJzkzfuBNvVLIgeRPllRfurMn8uoqTquQ==
dependencies:
"@react-hookz/deep-equal" "^1.0.3"
"@remix-run/router@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.4.tgz#cbfbec6735711e7c2fc93b9b40adf70ef5a39990"
@ -1090,7 +1102,7 @@ ci-info@^3.2.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.0.tgz#6d01b3696c59915b6ce057e4aa4adfc2fa25f5ef"
integrity sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==
classnames@^2.1.2, classnames@^2.3.2:
classnames@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
@ -2826,7 +2838,7 @@ promise-polyfill@^8.1.3:
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.3.tgz#2edc7e4b81aff781c88a0d577e5fe9da822107c6"
integrity sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg==
prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -2945,14 +2957,6 @@ react-router@6.4.4, react-router@^6.4.4:
dependencies:
"@remix-run/router" "1.0.4"
react-simple-dropdown@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/react-simple-dropdown/-/react-simple-dropdown-3.2.3.tgz#c9737bcb7a54c7de267a1afeeec04de588a3fa7b"
integrity sha512-NmyyvA0D4wph5ctzkn8U4wmblOacavJMl9gTOhQR3v8I997mc1FL1NFKkj3Mx+HNysBKRD/HI+kpxXCAgXumPw==
dependencies:
classnames "^2.1.2"
prop-types "^15.5.8"
react-tooltip@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.2.0.tgz#e10e7de2385e8fe6bf3438739c574558b455de3b"