diff --git a/apps/web/src/routes/settings/profile.tsx b/apps/web/src/routes/settings/profile.tsx
index e46cc62..0b98f2d 100644
--- a/apps/web/src/routes/settings/profile.tsx
+++ b/apps/web/src/routes/settings/profile.tsx
@@ -1,211 +1,3 @@
-import { useStorage } from "@tensamin/storage/context";
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
- Button,
- Input,
-} from "@tensamin/ui";
-import { useUser, type User } from "@tensamin/user/context";
-import { useEffect, useRef, useState } from "react";
-import MDInput from "@tensamin/markdown/input";
-import { ttp } from "@tensamin/shared/data";
-import { useTTP } from "@tensamin/ttp";
-import { Check } from "lucide-react";
-
-async function prepImage(
- file: File,
- size = 300,
- quality = 0.8,
-): Promise
{
- const bitmap = await createImageBitmap(file);
-
- const canvas = document.createElement("canvas");
- canvas.width = size;
- canvas.height = size;
-
- const ctx = canvas.getContext("2d");
- if (!ctx) throw new Error("Could not get canvas context");
-
- const scale = Math.max(size / bitmap.width, size / bitmap.height);
- const width = bitmap.width * scale;
- const height = bitmap.height * scale;
- const x = (size - width) / 2;
- const y = (size - height) / 2;
-
- ctx.drawImage(bitmap, x, y, width, height);
-
- return canvas.toDataURL("image/webp", quality);
-}
-
export default function Page() {
- const { get } = useUser();
- const { load } = useStorage();
- const { send } = useTTP();
- const [currentUser, setCurrentUser] = useState(null);
- const [draftUser, setDraftUser] = useState>({});
- const [errorMessage, setErrorMessage] = useState("");
- const [saveSucceeded, setSaveSucceeded] = useState(false);
- const avatarUploadRef = useRef(null);
- const draftInitializedRef = useRef(false);
- const effectiveAvatar =
- draftUser.avatar === "none" ? undefined : draftUser.avatar;
-
- const updateDraftUser = (
- updater: (previous: Partial) => Partial,
- ) => {
- setSaveSucceeded(false);
- setErrorMessage("");
- setDraftUser(updater);
- };
-
- useEffect(() => {
- const fetchUser = async () => {
- const user = await get(await load("user_id"));
- setCurrentUser(user);
- };
-
- fetchUser();
- }, [load, get]);
-
- useEffect(() => {
- if (!currentUser || draftInitializedRef.current) return;
-
- setDraftUser(currentUser);
- draftInitializedRef.current = true;
- }, [currentUser]);
-
- const handleAvatarUpload = async (file: File) => {
- const final = await prepImage(file);
- updateDraftUser((prev) => ({ ...prev, avatar: final }));
- if (avatarUploadRef.current) {
- avatarUploadRef.current.value = "";
- }
- };
-
- return currentUser ? (
- <>
-
- e.target.files?.[0] && handleAvatarUpload(e.target.files[0])
- }
- type="file"
- />
-
-
-
-
-
- {draftUser.display?.slice(0, 2).toUpperCase() ||
- currentUser.display.slice(0, 2).toUpperCase()}
-
-
-
-
Avatar
-
-
-
-
-
- GIFs are supported in decentralised mode or with Tensamin Premium
-
- Maximum file size is 16mb.
-
-
-
-
- updateDraftUser((prev) => ({
- ...prev,
- display: event.target.value,
- }))
- }
- placeholder="Display Name"
- value={draftUser.display || ""}
- />
-
- updateDraftUser((prev) => ({
- ...prev,
- username: event.target.value,
- }))
- }
- placeholder="Username"
- value={draftUser.username || ""}
- />
-
- updateDraftUser((prev) => ({ ...prev, about: value }))
- }
- value={draftUser.about || ""}
- />
-
- {errorMessage && (
- {errorMessage}
- )}
-
- >
- ) : (
- Loading...
- );
+ return ;
}
diff --git a/bun.lock b/bun.lock
index c7fc5aa..325be20 100644
--- a/bun.lock
+++ b/bun.lock
@@ -55,7 +55,6 @@
"@tensamin/call": "workspace:*",
"@tensamin/chat": "workspace:*",
"@tensamin/crypto": "workspace:*",
- "@tensamin/markdown": "workspace:*",
"@tensamin/notifications": "workspace:*",
"@tensamin/shared": "workspace:*",
"@tensamin/storage": "workspace:*",
diff --git a/packages/call/src/components/buttons/screenshare.tsx b/packages/call/src/components/buttons/screenshare.tsx
index 21ba118..4471539 100644
--- a/packages/call/src/components/buttons/screenshare.tsx
+++ b/packages/call/src/components/buttons/screenshare.tsx
@@ -18,12 +18,10 @@ export default function ScreenshareButton({
className,
iconSize,
tooltip,
- defaultPortal,
}: {
className?: string;
iconSize?: number;
tooltip?: string;
- defaultPortal?: boolean;
}) {
const isScreensharing = useCall((state) => state.screenShareEnabled);
const screenRef = useCall((state) => state.screenRef);
@@ -32,9 +30,8 @@ export default function ScreenshareButton({
const [menuOpen, setMenuOpen] = useState(false);
useEffect(() => {
- if (defaultPortal) return;
setPortalContainer(screenRef?.current ?? undefined);
- }, [screenRef, defaultPortal]);
+ }, [screenRef]);
async function startWebShare() {
try {
@@ -113,9 +110,7 @@ export default function ScreenshareButton({
/>
{/* Detect video / user and place here */}
diff --git a/packages/call/src/components/sidebarBox.tsx b/packages/call/src/components/sidebarBox.tsx
index 6a850f0..294d051 100644
--- a/packages/call/src/components/sidebarBox.tsx
+++ b/packages/call/src/components/sidebarBox.tsx
@@ -20,18 +20,24 @@ import LeaveButton from "./buttons/leave";
export default function SidebarBox() {
const state = useCall((store) => store.state);
+ const screenRef = useCall((store) => store.screenRef);
const isMobile = useIsMobile();
+ const [portalContainer, setPortalContainer] = useState
();
+
+ useEffect(() => {
+ setPortalContainer(screenRef?.current ?? undefined);
+ }, [screenRef]);
return state === "closed" ? null : (
-
+
-
+
@@ -39,7 +45,7 @@ export default function SidebarBox() {
);
}
-function ConnectionBar() {
+function ConnectionBar({ portalContainer }: { portalContainer?: HTMLElement }) {
const state = useCall((store) => store.state);
const isEncrypted = useCall((store) => store.isEncrypted);
const callId = useCall((store) => store.callId);
@@ -62,7 +68,7 @@ function ConnectionBar() {
{state === "closed" && "Closed"}
{state === "closing" && "Closing"}
-
+
{isEncrypted ? (
@@ -72,12 +78,18 @@ function ConnectionBar() {
}
/>
- Click to open call page
+
+ Click to open call page
+
);
}
-export function TinyPingGraph() {
+export function TinyPingGraph({
+ portalContainer,
+}: {
+ portalContainer?: HTMLElement;
+}) {
const room = useCall((store) => store.room);
const [mapData, setMapData] = useState
}
/>
-