(fix): fullscreen popovers not showing (qol): update todo
This commit is contained in:
parent
05c186e04e
commit
bd1622d63a
9 changed files with 87 additions and 68 deletions
4
bun.lock
4
bun.lock
|
|
@ -256,7 +256,7 @@
|
|||
},
|
||||
"overrides": {
|
||||
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.17.tar.gz",
|
||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.30.tar.gz",
|
||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.31.tar.gz",
|
||||
},
|
||||
"packages": {
|
||||
"@antfu/ni": ["@antfu/ni@25.0.0", "", { "dependencies": { "ansis": "^4.0.0", "fzf": "^0.5.2", "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" }, "bin": { "na": "bin/na.mjs", "ni": "bin/ni.mjs", "nr": "bin/nr.mjs", "nci": "bin/nci.mjs", "nlx": "bin/nlx.mjs", "nun": "bin/nun.mjs", "nup": "bin/nup.mjs" } }, "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA=="],
|
||||
|
|
@ -697,7 +697,7 @@
|
|||
|
||||
"@tensamin/ttp-core": ["@tensamin/ttp-core@https://git.methanium.net/tensamin/ttp/archive/0.0.17.tar.gz", { "dependencies": { "@eslint/js": "^10.0.1", "@typescript-eslint/parser": "^8.59.1", "@webtransport-bun/webtransport": "^0.3.0", "globals": "^17.5.0", "typescript": "^6.0.3", "typescript-eslint": "^8.59.1", "zod": "^4.4.1" } }, "sha512-smyx+04hSnWM1oyWJfJrRWmxu7OInwyHeIlaD1h3tUrkrSxiKWHl1qCmxVO1bC+cDwyUXhJ5HUnNCbx1aWx7Dg=="],
|
||||
|
||||
"@tensamin/ui": ["@tensamin/ui@https://git.methanium.net/tensamin/ui/archive/0.0.30.tar.gz", { "dependencies": { "@base-ui/react": "^1.3.0", "@fontsource-variable/inter": "^5.2.6", "@tauri-apps/api": "^2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "input-otp": "^1.4.2", "lucide-react": "^1.8.0", "next-themes": "^0.4.6", "react-day-picker": "^9.14.0", "react-resizable-panels": "^4.10.0", "recharts": "3.8.0", "shadcn": "^3.5.0", "sonner": "^2.0.7", "tailwind-merge": "^3.5.0", "tw-animate-css": "^1.3.0", "vaul": "^1.1.2" }, "peerDependencies": { "react": "^19.2.0", "react-dom": "^19.2.0" } }, "sha512-dlJBw7M/GFGHveJrL6uZA2d9yjAJ9F8QNJ2NfqCHTwzMoF6Y2ESHdeKZE5wBr2BEh9ublNqAGpN0TGD3iDV8rQ=="],
|
||||
"@tensamin/ui": ["@tensamin/ui@https://git.methanium.net/tensamin/ui/archive/0.0.31.tar.gz", { "dependencies": { "@base-ui/react": "^1.3.0", "@fontsource-variable/inter": "^5.2.6", "@tauri-apps/api": "^2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "input-otp": "^1.4.2", "lucide-react": "^1.8.0", "next-themes": "^0.4.6", "react-day-picker": "^9.14.0", "react-resizable-panels": "^4.10.0", "recharts": "3.8.0", "shadcn": "^3.5.0", "sonner": "^2.0.7", "tailwind-merge": "^3.5.0", "tw-animate-css": "^1.3.0", "vaul": "^1.1.2" }, "peerDependencies": { "react": "^19.2.0", "react-dom": "^19.2.0" } }, "sha512-I2FhsDtR5ElHwCasf6CfFCiyr5T2Cp9MQ2uAhcMnoNZ0tsK0mJhs+Rz9nUDmysydNyqOj8j/uC0CYXnnG1pCxQ=="],
|
||||
|
||||
"@tensamin/user": ["@tensamin/user@workspace:packages/user"],
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
"jsonc-parser": "^3.3.1"
|
||||
},
|
||||
"overrides": {
|
||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.30.tar.gz",
|
||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.31.tar.gz",
|
||||
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.17.tar.gz"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { Button, Popover, PopoverContent, PopoverTrigger } from "@tensamin/ui";
|
||||
import Wrapper from "@tensamin/user/wrapper";
|
||||
import { Mail } from "lucide-react";
|
||||
import { sendCallInvite } from "../../store";
|
||||
import { sendCallInvite, useCall } from "../../store";
|
||||
import { log, toast } from "@tensamin/shared/log";
|
||||
import { useSession } from "@tensamin/storage/session";
|
||||
|
||||
|
|
@ -13,6 +14,12 @@ export default function InviteButton({
|
|||
iconSize?: number;
|
||||
}) {
|
||||
const { contacts } = useSession();
|
||||
const screenRef = useCall((state) => state.screenRef);
|
||||
const [portalContainer, setPortalContainer] = useState<HTMLElement>();
|
||||
|
||||
useEffect(() => {
|
||||
setPortalContainer(screenRef?.current ?? undefined);
|
||||
}, [screenRef]);
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
|
|
@ -23,7 +30,10 @@ export default function InviteButton({
|
|||
</Button>
|
||||
}
|
||||
/>
|
||||
<PopoverContent className="flex w-40 flex-col gap-0.5 p-1!">
|
||||
<PopoverContent
|
||||
className="flex w-40 flex-col gap-0.5 p-1!"
|
||||
portalProps={{ container: portalContainer }}
|
||||
>
|
||||
{contacts.map((contact) => (
|
||||
<Wrapper
|
||||
key={contact.user_id}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button, Popover, PopoverContent, PopoverTrigger } from "@tensamin/ui";
|
||||
import { MonitorDot, ScreenShare } from "lucide-react";
|
||||
import { toast } from "@tensamin/shared/log";
|
||||
|
|
@ -14,9 +14,15 @@ export default function ScreenshareButton({
|
|||
iconSize?: number;
|
||||
}) {
|
||||
const isScreensharing = useCall((state) => state.screenShareEnabled);
|
||||
const screenRef = useCall((state) => state.screenRef);
|
||||
const [portalContainer, setPortalContainer] = useState<HTMLElement>();
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setPortalContainer(screenRef?.current ?? undefined);
|
||||
}, [screenRef]);
|
||||
|
||||
async function startWebShare() {
|
||||
try {
|
||||
await setScreenShareEnabled(true, {
|
||||
|
|
@ -66,7 +72,10 @@ export default function ScreenshareButton({
|
|||
</Button>
|
||||
}
|
||||
/>
|
||||
<PopoverContent className="flex w-40 flex-col gap-2">
|
||||
<PopoverContent
|
||||
className="flex w-40 flex-col gap-2"
|
||||
portalProps={{ container: portalContainer }}
|
||||
>
|
||||
<Button
|
||||
disabled={isScreensharing}
|
||||
onClick={() => {
|
||||
|
|
@ -101,6 +110,7 @@ export default function ScreenshareButton({
|
|||
open={dialogOpen}
|
||||
onOpenChange={setDialogOpen}
|
||||
isScreensharing={isScreensharing}
|
||||
portalContainer={portalContainer}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -60,10 +60,12 @@ export default function ScreenShareDialog({
|
|||
open,
|
||||
onOpenChange,
|
||||
isScreensharing,
|
||||
portalContainer,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
isScreensharing: boolean;
|
||||
portalContainer?: HTMLElement;
|
||||
}) {
|
||||
const {
|
||||
getScreenShareCapabilities,
|
||||
|
|
@ -191,7 +193,10 @@ export default function ScreenShareDialog({
|
|||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-3xl gap-0 overflow-hidden p-0">
|
||||
<DialogContent
|
||||
className="max-w-3xl gap-0 overflow-hidden p-0"
|
||||
portalProps={{ container: portalContainer }}
|
||||
>
|
||||
<DialogHeader className="p-4 pb-3">
|
||||
<DialogTitle>Share your screen</DialogTitle>
|
||||
<DialogDescription>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import MuteButton from "./buttons/mute";
|
|||
import DeafButton from "./buttons/deaf";
|
||||
import { Room, Track } from "livekit-client";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ResponsiveContainer, AreaChart, Area } from "recharts";
|
||||
import { AreaChart, Area } from "recharts";
|
||||
import LeaveButton from "./buttons/leave";
|
||||
|
||||
export default function SidebarBox() {
|
||||
|
|
@ -122,55 +122,44 @@ export function TinyPingGraph() {
|
|||
}}
|
||||
>
|
||||
{data.length > 1 && (
|
||||
<ResponsiveContainer
|
||||
width="100%"
|
||||
height="100%"
|
||||
minWidth={0}
|
||||
minHeight={24}
|
||||
<AreaChart
|
||||
width={96}
|
||||
height={24}
|
||||
data={data}
|
||||
margin={{ top: 2, right: 0, bottom: 2, left: 0 }}
|
||||
>
|
||||
<AreaChart
|
||||
data={data}
|
||||
margin={{ top: 2, right: 0, bottom: 2, left: 0 }}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="pingGradient"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="1"
|
||||
>
|
||||
<stop
|
||||
offset="0%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0.35}
|
||||
/>
|
||||
<stop
|
||||
offset="70%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0.08}
|
||||
/>
|
||||
<stop
|
||||
offset="100%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0}
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<defs>
|
||||
<linearGradient id="pingGradient" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop
|
||||
offset="0%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0.35}
|
||||
/>
|
||||
<stop
|
||||
offset="70%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0.08}
|
||||
/>
|
||||
<stop
|
||||
offset="100%"
|
||||
stopColor="currentColor"
|
||||
stopOpacity={0}
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<Area
|
||||
type="monotone"
|
||||
dataKey="ping"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
fill="url(#pingGradient)"
|
||||
fillOpacity={1}
|
||||
dot={false}
|
||||
activeDot={false}
|
||||
isAnimationActive={false}
|
||||
/>
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
<Area
|
||||
type="monotone"
|
||||
dataKey="ping"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
fill="url(#pingGradient)"
|
||||
fillOpacity={1}
|
||||
dot={false}
|
||||
activeDot={false}
|
||||
isAnimationActive={false}
|
||||
/>
|
||||
</AreaChart>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -522,7 +522,9 @@ export function triggerCallLayoutCalculation() {
|
|||
}));
|
||||
}
|
||||
|
||||
export function setScreenRef(screenRef: React.RefObject<HTMLDivElement | null> | null) {
|
||||
export function setScreenRef(
|
||||
screenRef: React.RefObject<HTMLDivElement | null> | null,
|
||||
) {
|
||||
useCall.setState({ screenRef });
|
||||
}
|
||||
|
||||
|
|
@ -1093,7 +1095,8 @@ export function useInitializeCall() {
|
|||
};
|
||||
|
||||
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
||||
return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
||||
return () =>
|
||||
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
||||
}, []);
|
||||
|
||||
// esc key listener
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
- Call invite popup
|
||||
- Save call invite in `calls` array
|
||||
- Sounds
|
||||
- Fullscreen button for screenshares
|
||||
- Admin call actions
|
||||
- Timeout
|
||||
- Disconnect
|
||||
|
|
|
|||
|
|
@ -105,14 +105,17 @@ export default function Screen() {
|
|||
messagesRef.current = messages;
|
||||
}, [messages]);
|
||||
|
||||
const getItemKey = React.useCallback((index: number) => {
|
||||
if (shouldShowConversationStart && index === 0) {
|
||||
return "conversation-start";
|
||||
}
|
||||
const getItemKey = React.useCallback(
|
||||
(index: number) => {
|
||||
if (shouldShowConversationStart && index === 0) {
|
||||
return "conversation-start";
|
||||
}
|
||||
|
||||
const messageIndex = shouldShowConversationStart ? index - 1 : index;
|
||||
return messagesRef.current[messageIndex]?.send_time ?? index;
|
||||
}, [shouldShowConversationStart]);
|
||||
const messageIndex = shouldShowConversationStart ? index - 1 : index;
|
||||
return messagesRef.current[messageIndex]?.send_time ?? index;
|
||||
},
|
||||
[shouldShowConversationStart],
|
||||
);
|
||||
|
||||
const setMeasurementRef = React.useCallback(
|
||||
(sendTime: number, element: HTMLDivElement | null) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue