1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-22 02:12:38 +01:00
This commit is contained in:
Puyodead1 2023-12-13 11:11:02 -05:00
parent e49522096e
commit fa960f36e9
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
3 changed files with 130 additions and 62 deletions

View File

@ -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>
)}
</>
);
}

View File

@ -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>
)}
</>
);
}

View File

@ -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);