mirror of
https://github.com/spacebarchat/client.git
synced 2024-11-22 02:12:38 +01:00
a
This commit is contained in:
parent
e49522096e
commit
fa960f36e9
@ -1,9 +1,23 @@
|
||||
import {
|
||||
FloatingPortal,
|
||||
flip,
|
||||
offset,
|
||||
shift,
|
||||
useClick,
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useInteractions,
|
||||
useRole,
|
||||
} from "@floating-ui/react";
|
||||
import { PresenceUpdateStatus } from "@spacebarchat/spacebar-api-types/v9";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import useFloating from "../../hooks/useFloating";
|
||||
import { useAppStore } from "../../stores/AppStore";
|
||||
import GuildMember from "../../stores/objects/GuildMember";
|
||||
import User from "../../stores/objects/User";
|
||||
import Avatar from "../Avatar";
|
||||
import UserProfilePopout from "../floating/UserProfilePopout";
|
||||
|
||||
const ListItem = styled.div<{ isCategory?: boolean }>`
|
||||
padding: ${(props) => (props.isCategory ? "16px 8px 0 0" : "1px 8px 0 0")};
|
||||
@ -62,28 +76,55 @@ function MemberListItem({ item }: Props) {
|
||||
const app = useAppStore();
|
||||
const presence = app.presences.get(item.guild.id)?.get(item.user!.id);
|
||||
|
||||
const { refs, getReferenceProps } = useFloating({
|
||||
placement: "left-start",
|
||||
type: "userPopout",
|
||||
config: {
|
||||
user: item.user!,
|
||||
member: item,
|
||||
},
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const floating = useFloating({
|
||||
placement: "right-start",
|
||||
open,
|
||||
onOpenChange: setOpen,
|
||||
// whileElementsMounted: autoUpdate,
|
||||
middleware: [offset(5), flip(), shift()],
|
||||
});
|
||||
|
||||
const click = useClick(floating.context);
|
||||
const dismiss = useDismiss(floating.context);
|
||||
const role = useRole(floating.context);
|
||||
const interactions = useInteractions([click, dismiss, role]);
|
||||
|
||||
return (
|
||||
<ListItem key={item.user?.id} ref={refs.setReference} {...getReferenceProps()}>
|
||||
<Container>
|
||||
<Wrapper offline={presence?.status === PresenceUpdateStatus.Offline}>
|
||||
<AvatarWrapper>
|
||||
<Avatar user={item.user!} size={32} presence={presence} />
|
||||
</AvatarWrapper>
|
||||
<TextWrapper>
|
||||
<Text color={item.roleColor}>{item.nick ?? item.user?.username}</Text>
|
||||
</TextWrapper>
|
||||
</Wrapper>
|
||||
</Container>
|
||||
</ListItem>
|
||||
<>
|
||||
<ListItem key={item.user?.id} ref={floating.refs.setReference} {...interactions.getReferenceProps()}>
|
||||
<Container>
|
||||
<Wrapper offline={presence?.status === PresenceUpdateStatus.Offline}>
|
||||
<AvatarWrapper>
|
||||
<Avatar user={item.user!} size={32} presence={presence} />
|
||||
</AvatarWrapper>
|
||||
<TextWrapper>
|
||||
<Text color={item.roleColor}>{item.nick ?? item.user?.username}</Text>
|
||||
</TextWrapper>
|
||||
</Wrapper>
|
||||
</Container>
|
||||
</ListItem>
|
||||
|
||||
{open && (
|
||||
<FloatingPortal>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.1, easing: [0.87, 0, 0.13, 1] }}
|
||||
>
|
||||
<div
|
||||
ref={floating.refs.setFloating}
|
||||
style={floating.floatingStyles}
|
||||
{...interactions.getFloatingProps()}
|
||||
>
|
||||
<UserProfilePopout user={app.account! as unknown as User} member={item} />
|
||||
</div>
|
||||
</motion.div>
|
||||
</FloatingPortal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,24 @@
|
||||
import {
|
||||
FloatingPortal,
|
||||
flip,
|
||||
offset,
|
||||
shift,
|
||||
useClick,
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useInteractions,
|
||||
useRole,
|
||||
} from "@floating-ui/react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import useFloating from "../hooks/useFloating";
|
||||
import { useAppStore } from "../stores/AppStore";
|
||||
import User from "../stores/objects/User";
|
||||
import Avatar from "./Avatar";
|
||||
import Icon from "./Icon";
|
||||
import IconButton from "./IconButton";
|
||||
import Tooltip from "./Tooltip";
|
||||
import UserProfilePopout from "./floating/UserProfilePopout";
|
||||
|
||||
const Section = styled.section`
|
||||
flex: 0 0 auto;
|
||||
@ -69,37 +82,64 @@ const ActionsWrapper = styled.div`
|
||||
|
||||
function UserPanel() {
|
||||
const app = useAppStore();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const { refs, getReferenceProps } = useFloating({
|
||||
placement: "right-start",
|
||||
type: "userPopout",
|
||||
config: {
|
||||
user: app.account as unknown as User,
|
||||
},
|
||||
const floating = useFloating({
|
||||
placement: "bottom",
|
||||
open,
|
||||
onOpenChange: setOpen,
|
||||
// whileElementsMounted: autoUpdate,
|
||||
middleware: [offset(5), flip(), shift()],
|
||||
});
|
||||
|
||||
const click = useClick(floating.context);
|
||||
const dismiss = useDismiss(floating.context);
|
||||
const role = useRole(floating.context);
|
||||
const interactions = useInteractions([click, dismiss, role]);
|
||||
|
||||
const openSettingsModal = () => {};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<Container>
|
||||
<AvatarWrapper ref={refs.setReference} {...getReferenceProps()}>
|
||||
<Avatar popoutPlacement="top" onClick={null} />
|
||||
<Name>
|
||||
<Username>{app.account?.username}</Username>
|
||||
<Subtext>#{app.account?.discriminator}</Subtext>
|
||||
</Name>
|
||||
</AvatarWrapper>
|
||||
<>
|
||||
<Section>
|
||||
<Container>
|
||||
<AvatarWrapper ref={floating.refs.setReference} {...interactions.getReferenceProps()}>
|
||||
<Avatar popoutPlacement="top" onClick={null} />
|
||||
<Name>
|
||||
<Username>{app.account?.username}</Username>
|
||||
<Subtext>#{app.account?.discriminator}</Subtext>
|
||||
</Name>
|
||||
</AvatarWrapper>
|
||||
|
||||
<ActionsWrapper>
|
||||
<Tooltip title="Settings">
|
||||
<IconButton aria-label="settings" color="#fff" onClick={openSettingsModal}>
|
||||
<Icon icon="mdiCog" size="20px" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</ActionsWrapper>
|
||||
</Container>
|
||||
</Section>
|
||||
<ActionsWrapper>
|
||||
<Tooltip title="Settings">
|
||||
<IconButton aria-label="settings" color="#fff" onClick={openSettingsModal}>
|
||||
<Icon icon="mdiCog" size="20px" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</ActionsWrapper>
|
||||
</Container>
|
||||
</Section>
|
||||
|
||||
{open && (
|
||||
<FloatingPortal>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.1, easing: [0.87, 0, 0.13, 1] }}
|
||||
>
|
||||
<div
|
||||
ref={floating.refs.setFloating}
|
||||
style={floating.floatingStyles}
|
||||
{...interactions.getFloatingProps()}
|
||||
>
|
||||
<UserProfilePopout user={app.account! as unknown as User} />
|
||||
</div>
|
||||
</motion.div>
|
||||
</FloatingPortal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,21 +2,8 @@ import { FloatingPortal } from "@floating-ui/react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { floatingController } from "./FloatingController";
|
||||
|
||||
export default observer(() => {
|
||||
// useEffect(() => {
|
||||
// function keyDown(event: KeyboardEvent) {
|
||||
// if (event.key === "Escape") {
|
||||
// modalController.pop("close");
|
||||
// } else if (event.key === "Enter") {
|
||||
// if (event.target instanceof HTMLSelectElement) return;
|
||||
// modalController.pop("confirm");
|
||||
// }
|
||||
// }
|
||||
|
||||
// document.addEventListener("keydown", keyDown);
|
||||
// return () => document.removeEventListener("keydown", keyDown);
|
||||
// }, []);
|
||||
console.log(floatingController.elements);
|
||||
|
||||
function FloatingRender() {
|
||||
return <FloatingPortal>{floatingController.rendered}</FloatingPortal>;
|
||||
});
|
||||
}
|
||||
|
||||
export default observer(FloatingRender);
|
||||
|
Loading…
Reference in New Issue
Block a user