mirror of https://github.com/msgbyte/tailchat
feat: add livekit member panel
parent
c937178956
commit
19a1e5dbe5
@ -0,0 +1,54 @@
|
||||
import { useParticipants } from '@livekit/components-react';
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Icon, UserListItem } from '@capital/component';
|
||||
import { useEvent } from '@capital/common';
|
||||
import type { Participant } from 'livekit-client';
|
||||
import { Translate } from '../../translate';
|
||||
|
||||
const MemberList = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: clamp(200px, 55ch, 60ch);
|
||||
background-color: var(--lk-bg2);
|
||||
border-left: 1px solid var(--lk-border-color);
|
||||
padding: 8px;
|
||||
`;
|
||||
|
||||
const IsSpeakingTip = styled.div`
|
||||
font-size: 12px;
|
||||
opacity: 0.6;
|
||||
`;
|
||||
|
||||
export const Member: React.FC = React.memo(() => {
|
||||
const participants = useParticipants();
|
||||
|
||||
const getAction = useEvent((participant: Participant) => {
|
||||
return [
|
||||
!participant.isSpeaking && (
|
||||
<IsSpeakingTip>({Translate.isSpeaking})</IsSpeakingTip>
|
||||
),
|
||||
<div key="mic-state">
|
||||
{participant.isMicrophoneEnabled ? (
|
||||
<Icon icon="mdi:microphone" />
|
||||
) : (
|
||||
<Icon icon="mdi:microphone-off" />
|
||||
)}
|
||||
</div>,
|
||||
];
|
||||
});
|
||||
|
||||
return (
|
||||
<MemberList>
|
||||
{participants.map((member) => (
|
||||
<UserListItem
|
||||
key={member.sid}
|
||||
userId={member.identity}
|
||||
actions={getAction(member)}
|
||||
/>
|
||||
))}
|
||||
</MemberList>
|
||||
);
|
||||
});
|
||||
Member.displayName = 'Member';
|
@ -1,25 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import type { SVGProps } from 'react';
|
||||
|
||||
export const ChatIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={18}
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M0 2.75A2.75 2.75 0 0 1 2.75 0h10.5A2.75 2.75 0 0 1 16 2.75v13.594a.75.75 0 0 1-1.234.572l-3.691-3.12a1.25 1.25 0 0 0-.807-.296H2.75A2.75 2.75 0 0 1 0 10.75v-8ZM2.75 1.5c-.69 0-1.25.56-1.25 1.25v8c0 .69.56 1.25 1.25 1.25h7.518c.65 0 1.279.23 1.775.65l2.457 2.077V2.75c0-.69-.56-1.25-1.25-1.25H2.75Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M3 4.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm0 2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
@ -1,25 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import type { SVGProps } from 'react';
|
||||
|
||||
export const LeaveIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M2 2.75A2.75 2.75 0 0 1 4.75 0h6.5A2.75 2.75 0 0 1 14 2.75v10.5A2.75 2.75 0 0 1 11.25 16h-6.5A2.75 2.75 0 0 1 2 13.25v-.5a.75.75 0 0 1 1.5 0v.5c0 .69.56 1.25 1.25 1.25h6.5c.69 0 1.25-.56 1.25-1.25V2.75c0-.69-.56-1.25-1.25-1.25h-6.5c-.69 0-1.25.56-1.25 1.25v.5a.75.75 0 0 1-1.5 0v-.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M8.78 7.47a.75.75 0 0 1 0 1.06l-2.25 2.25a.75.75 0 1 1-1.06-1.06l.97-.97H1.75a.75.75 0 0 1 0-1.5h4.69l-.97-.97a.75.75 0 0 1 1.06-1.06l2.25 2.25Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
Loading…
Reference in New Issue