1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-25 11:42:30 +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 { PresenceUpdateStatus } from "@spacebarchat/spacebar-api-types/v9";
import { motion } from "framer-motion";
import { useState } from "react";
import styled from "styled-components"; import styled from "styled-components";
import useFloating from "../../hooks/useFloating";
import { useAppStore } from "../../stores/AppStore"; import { useAppStore } from "../../stores/AppStore";
import GuildMember from "../../stores/objects/GuildMember"; import GuildMember from "../../stores/objects/GuildMember";
import User from "../../stores/objects/User";
import Avatar from "../Avatar"; import Avatar from "../Avatar";
import UserProfilePopout from "../floating/UserProfilePopout";
const ListItem = styled.div<{ isCategory?: boolean }>` const ListItem = styled.div<{ isCategory?: boolean }>`
padding: ${(props) => (props.isCategory ? "16px 8px 0 0" : "1px 8px 0 0")}; padding: ${(props) => (props.isCategory ? "16px 8px 0 0" : "1px 8px 0 0")};
@ -62,17 +76,24 @@ function MemberListItem({ item }: Props) {
const app = useAppStore(); const app = useAppStore();
const presence = app.presences.get(item.guild.id)?.get(item.user!.id); const presence = app.presences.get(item.guild.id)?.get(item.user!.id);
const { refs, getReferenceProps } = useFloating({ const [open, setOpen] = useState(false);
placement: "left-start",
type: "userPopout", const floating = useFloating({
config: { placement: "right-start",
user: item.user!, open,
member: item, 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 ( return (
<ListItem key={item.user?.id} ref={refs.setReference} {...getReferenceProps()}> <>
<ListItem key={item.user?.id} ref={floating.refs.setReference} {...interactions.getReferenceProps()}>
<Container> <Container>
<Wrapper offline={presence?.status === PresenceUpdateStatus.Offline}> <Wrapper offline={presence?.status === PresenceUpdateStatus.Offline}>
<AvatarWrapper> <AvatarWrapper>
@ -84,6 +105,26 @@ function MemberListItem({ item }: Props) {
</Wrapper> </Wrapper>
</Container> </Container>
</ListItem> </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 styled from "styled-components";
import useFloating from "../hooks/useFloating";
import { useAppStore } from "../stores/AppStore"; import { useAppStore } from "../stores/AppStore";
import User from "../stores/objects/User"; import User from "../stores/objects/User";
import Avatar from "./Avatar"; import Avatar from "./Avatar";
import Icon from "./Icon"; import Icon from "./Icon";
import IconButton from "./IconButton"; import IconButton from "./IconButton";
import Tooltip from "./Tooltip"; import Tooltip from "./Tooltip";
import UserProfilePopout from "./floating/UserProfilePopout";
const Section = styled.section` const Section = styled.section`
flex: 0 0 auto; flex: 0 0 auto;
@ -69,21 +82,28 @@ const ActionsWrapper = styled.div`
function UserPanel() { function UserPanel() {
const app = useAppStore(); const app = useAppStore();
const [open, setOpen] = useState(false);
const { refs, getReferenceProps } = useFloating({ const floating = useFloating({
placement: "right-start", placement: "bottom",
type: "userPopout", open,
config: { onOpenChange: setOpen,
user: app.account as unknown as User, // 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 = () => {}; const openSettingsModal = () => {};
return ( return (
<>
<Section> <Section>
<Container> <Container>
<AvatarWrapper ref={refs.setReference} {...getReferenceProps()}> <AvatarWrapper ref={floating.refs.setReference} {...interactions.getReferenceProps()}>
<Avatar popoutPlacement="top" onClick={null} /> <Avatar popoutPlacement="top" onClick={null} />
<Name> <Name>
<Username>{app.account?.username}</Username> <Username>{app.account?.username}</Username>
@ -100,6 +120,26 @@ function UserPanel() {
</ActionsWrapper> </ActionsWrapper>
</Container> </Container>
</Section> </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 { observer } from "mobx-react-lite";
import { floatingController } from "./FloatingController"; import { floatingController } from "./FloatingController";
export default observer(() => { function FloatingRender() {
// 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);
return <FloatingPortal>{floatingController.rendered}</FloatingPortal>; return <FloatingPortal>{floatingController.rendered}</FloatingPortal>;
}); }
export default observer(FloatingRender);