import {
Chat,
ChatBox,
IconButton,
Loader,
Resizable,
StreamNotificationProvider,
Text,
useTheme,
View,
zero,
} from "@streamplace/components";
import { scrims, spacing } from "@streamplace/components/src/lib/theme/tokens";
import { useKeyboard } from "hooks/useKeyboard";
import { useEffect, useState } from "react";
import { Platform, Pressable, useWindowDimensions } from "react-native";
import Animated, {
SharedValue,
useAnimatedStyle,
useSharedValue,
withSpring,
} from "react-native-reanimated";
import { useNavigation } from "@react-navigation/native";
import { usePDSAgent } from "@streamplace/components/src/streamplace-store/xrpc";
import { EmojiPicker } from "components/emoji-picker/emoji-picker";
import { BadgePicker } from "components/mobile/badge-picker";
import { ArrowRight, ChevronsRight } from "lucide-react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useStore } from "store";
import { useEmojiData } from "utils/emoji";
const { borderRadius, gap, layout, flex, px, position, bottom } = zero;
export function DesktopChatPanel({ chatVisible, chatPanelWidth, setShowChat }) {
const { theme } = useTheme();
let insets = useSafeAreaInsets();
let panelWidthWithInsets = chatPanelWidth;
const sidebarOffset = useSharedValue(chatVisible ? 0 : panelWidthWithInsets);
const sidebarOpacity = useSharedValue(chatVisible ? 1 : 0);
const kb = useKeyboard();
useEffect(() => {
console.log(
"Setting sidebar offset x to",
chatVisible ? 0 : panelWidthWithInsets,
);
sidebarOffset.value = withSpring(chatVisible ? 0 : panelWidthWithInsets, {
damping: 100,
stiffness: 1000,
});
sidebarOpacity.value = withSpring(chatVisible ? 1 : 0, {
damping: 100,
stiffness: 1000,
});
}, [chatVisible, panelWidthWithInsets, sidebarOffset]);
const animatedSidebarStyle = useAnimatedStyle(() => ({
transform: [
{ translateX: sidebarOffset.value },
{ translateY: -kb.keyboardHeight },
],
}));
const notificationOffsetStyle = useAnimatedStyle(() => ({
transform: [{ translateX: -sidebarOffset.value }],
}));
return (
<>
0 ? insets.right - 20 : 0,
top: 0,
bottom: 0,
width: panelWidthWithInsets,
flexShrink: 0,
backgroundColor: theme.colors.surface0,
borderLeftWidth: 1,
borderLeftColor: theme.colors.borderSubtle,
zIndex: 999,
},
animatedSidebarStyle,
]}
>
>
);
}
function FixedChatPanel() {
const kb = useKeyboard();
const [containerHeight, setContainerHeight] = useState(0);
const sa = useSafeAreaInsets();
const dims = useWindowDimensions();
const SpringSettings = {
duration: 25,
mass: 10,
};
// calculate top bar + safe area height
const videoHeight = dims.height - sa.top - 88 - containerHeight;
const calculatedHeight =
containerHeight + (kb.keyboardHeight > 0 ? videoHeight : 0);
const animatedSidebarStyle = useAnimatedStyle(() => ({
height: withSpring(
containerHeight > 0
? Math.max(0, calculatedHeight - kb.keyboardHeight)
: containerHeight,
SpringSettings,
),
backgroundColor: withSpring(
kb.keyboardHeight > 0 ? scrims.dark : "rgba(0, 0, 0, 0)", // token-ok
SpringSettings,
),
borderRadius: withSpring(containerHeight > 0 ? 18 : 0, SpringSettings),
transform: [
{
translateY:
Platform.OS === "web"
? 0
: withSpring(-kb.keyboardHeight, SpringSettings),
},
],
}));
return (
setContainerHeight(e.nativeEvent.layout.height)}
>
);
}
// MobileChatPanel.tsx
export function MobileChatPanel({
isPlayerRatioGreater,
portraitVideoTranslateY,
fixed = false,
}: {
isPlayerRatioGreater: boolean;
portraitVideoTranslateY?: SharedValue;
fixed?: boolean;
}) {
const insets = useSafeAreaInsets();
// create fixed style
const fixedStyle = useAnimatedStyle(() => ({
marginTop: portraitVideoTranslateY ? portraitVideoTranslateY.value : 0,
}));
if (fixed) {
return (
);
}
return (
(
)}
>
);
}
function ChatPanel({ setShowChat }: { setShowChat?: (show: boolean) => void }) {
const { theme } = useTheme();
let agent = usePDSAgent();
const navigation = useNavigation();
const openLoginModal = useStore((state) => state.openLoginModal);
const emojiData = useEmojiData();
const customEmoji: any[] = [];
return (
{/* Panel header — labels the surface, hosts the collapse control */}
{setShowChat && (
Chat
setShowChat(false)}
>
)}
{agent?.did ? (
setShowChat(v) : undefined}
leftSlot={}
emojiPicker={(isOpen, onClose, onSelect) => (
)}
/>
) : !agent ? (
) : (
{
const state = navigation.getState();
if (!state) {
openLoginModal();
return;
}
let route: any = state.routes[state.index];
while (route.state?.index !== undefined) {
route = route.state.routes[route.state.index];
}
openLoginModal({ name: route.name, params: route.params } as any);
}}
style={[
layout.flex.row,
layout.flex.center,
gap.all[2],
{
paddingVertical: spacing[2],
paddingHorizontal: spacing[3],
borderRadius: borderRadius.lg,
backgroundColor: theme.colors.surface2,
borderWidth: 1,
borderColor: theme.colors.borderSubtle,
},
]}
>
Log in or sign up to chat
)}
);
}