-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModalUsersList.tsx
110 lines (99 loc) · 2.72 KB
/
ModalUsersList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import React, { useRef, useState, useEffect } from 'react'
import styled from '@emotion/styled'
import CancelIcon from '@mui/icons-material/Cancel'
import { ModalProps, ModalBase } from '../atoms/Modal'
import { useRoomUserActions, useGetUsersById } from '../../state/rooms/hooks'
import { useIntersectionObserver } from '../../lib/hooks/useIntersectionObserver'
import { WIDTH_MOBILE } from '../../constants'
type Props = ModalProps & { roomId: string }
export const ModalUsersList: React.FC<Props> = ({ open, onClose, roomId }) => {
const users = useGetUsersById(roomId)
const { getNextUsers } = useRoomUserActions()
const [loading, setLoading] = useState(false)
const listWrapRef = useRef<HTMLUListElement>(null)
const [intersectionRef, isIntersecting] = useIntersectionObserver()
useEffect(() => {
if (loading) {
return
}
if (isIntersecting) {
setLoading(true)
getNextUsers({ roomId }).then(() => setLoading(false))
}
}, [getNextUsers, isIntersecting, loading, roomId])
const list = (users?.users || []).map((e) => (
<li key={e.userId} attr-id={e.userId}>
<img src={e.icon} className="icon" crossOrigin="anonymous" />
{e.account}
</li>
))
return (
<ModalBase open={open} onClose={onClose}>
<ModalInner>
<header>
<h4>入室中ユーザー</h4>
<CancelIcon className="cancel" onClick={onClose} />
</header>
<div className="count">{users?.count || 0}</div>
<div className="users">
<ul ref={listWrapRef} className="scroll-styled-y">
{list}
{open && list.length > 0 && (
<li className="last" ref={intersectionRef}></li>
)}
</ul>
</div>
</ModalInner>
</ModalBase>
)
}
const ModalInner = styled.form`
max-width: 440px;
border-radius: 3px;
background-color: var(--color-background);
color: var(--color-on-background);
padding: 20px;
header {
display: flex;
h4 {
margin: 0;
flex: 1;
}
.cancel {
cursor: pointer;
}
}
.count {
display: flex;
justify-content: flex-end;
padding: 0.5em 0.2em 0.5em 0;
border-bottom: 1px solid var(--color-border);
}
.users {
ul {
list-style-type: none;
margin: 0;
padding: 0;
max-height: 400px;
overflow: auto;
> li {
padding: 1em 0 1em;
display: flex;
border-bottom: 1px solid var(--color-border);
}
> li.last {
visibility: hidden;
}
}
.icon {
padding-left: 3px;
width: 20px;
height: 20px;
margin: 0 1em 0 0;
}
}
@container page-container (max-width: ${WIDTH_MOBILE}px) {
min-width: 80vw;
max-width: 80vw;
}
`