feat(message): add embedded mode to ChatScreen for desktop dual-column layout
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 2m37s
Frontend CI / ota-android (push) Successful in 10m43s
Frontend CI / build-android-apk (push) Successful in 40m4s

Replace EmbeddedChat with unified ChatScreen supporting embedded mode through props. Pass conversation data, layout constraints, and navigation callbacks directly to ChatScreen instead of using separate embedded component. Consolidates dual-column layout logic into single component with conditional rendering based on isEmbedded prop.
This commit is contained in:
lafay
2026-04-13 01:52:43 +08:00
parent fe6a03da5d
commit 4f31926eb5
8 changed files with 131 additions and 1095 deletions

View File

@@ -49,9 +49,10 @@ import {
ChatInput,
GroupInfoPanel,
PANEL_HEIGHTS,
ChatScreenProps,
} from './components/ChatScreen';
export const ChatScreen: React.FC = () => {
export const ChatScreen: React.FC<ChatScreenProps> = (props) => {
const navigation = useNavigation();
const router = useRouter();
const insets = useSafeAreaInsets();
@@ -62,12 +63,12 @@ export const ChatScreen: React.FC = () => {
// 响应式布局
const isWideScreen = useBreakpointGTE('lg');
// 监听屏幕宽度变化当变为大屏幕时自动跳转到web端首页
// 监听屏幕宽度变化当变为大屏幕时自动跳转到web端首页(嵌入式模式下不跳转)
useEffect(() => {
if (isWideScreen) {
if (isWideScreen && !props.isEmbedded) {
router.replace(hrefs.hrefHome());
}
}, [isWideScreen, router]);
}, [isWideScreen, router, props.isEmbedded]);
// 输入框区域高度(用于定位浮动 mention 面板)
const [inputWrapperHeight, setInputWrapperHeight] = useState(60);
@@ -88,20 +89,20 @@ export const ChatScreen: React.FC = () => {
const containerStyle = useMemo(() => ([
styles.container,
isWideScreen ? { maxWidth: 1200, alignSelf: 'center' as const, width: '100%' as const } : null,
]), [isWideScreen, styles.container]);
isWideScreen && !props.isEmbedded ? { maxWidth: 1200, alignSelf: 'center' as const, width: '100%' as const } : null,
]), [isWideScreen, styles.container, props.isEmbedded]);
const listContentStyle = useMemo(() => ([
styles.listContent,
isWideScreen
isWideScreen && !props.isEmbedded
? { paddingHorizontal: 24, maxWidth: 900, alignSelf: 'center' as const }
: { paddingHorizontal: 16 },
]), [isWideScreen, styles.listContent]);
]), [isWideScreen, styles.listContent, props.isEmbedded]);
const inputWrapperStyle = useMemo(() => ([
styles.inputWrapper,
isWideScreen ? { maxWidth: 900, alignSelf: 'center' as const, width: '100%' as const } : null,
]), [isWideScreen, styles.inputWrapper]);
isWideScreen && !props.isEmbedded ? { maxWidth: 900, alignSelf: 'center' as const, width: '100%' as const } : null,
]), [isWideScreen, styles.inputWrapper, props.isEmbedded]);
// 图片查看器状态
const [showImageViewer, setShowImageViewer] = useState(false);
@@ -208,7 +209,7 @@ export const ChatScreen: React.FC = () => {
handleReachLatestEdge,
jumpToLatestMessages,
setBrowsingHistory,
} = useChatScreen();
} = useChatScreen(props);
const displayMessages = useMemo(() => [...messages].reverse(), [messages]);
const longPressMenuMemberMap = useMemo(() => {
@@ -412,22 +413,22 @@ export const ChatScreen: React.FC = () => {
}, [handleMessageListContentSizeChange]);
return (
<SafeAreaView style={containerStyle} edges={['top']}>
<SafeAreaView style={containerStyle} edges={props.isEmbedded ? [] : ['top']}>
<KeyboardAvoidingView
style={styles.container}
style={[styles.container, { overflow: 'hidden' }]}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
>
<StatusBar style={resolved === 'dark' ? 'light' : 'dark'} backgroundColor={colors.background.paper} />
{!props.isEmbedded && <StatusBar style={resolved === 'dark' ? 'light' : 'dark'} backgroundColor={colors.background.paper} />}
{/* 顶部栏 */}
<ChatHeader
isGroupChat={isGroupChat}
groupInfo={groupInfo}
otherUser={otherUser}
routeGroupName={routeGroupName}
routeGroupName={routeGroupName ?? undefined}
typingHint={typingHint}
onBack={() => router.back()}
onBack={props.onEmbeddedBack ? props.onEmbeddedBack : () => router.back()}
onTitlePress={navigateToInfo}
onMorePress={navigateToChatSettings}
onGroupInfoPress={handleGroupInfoPress}