mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-13 19:20:04 +00:00
✨ feat: refresh topic sharing experience (share page + popover) (#15581)
This commit is contained in:
+16
-6
@@ -487,7 +487,7 @@
|
||||
"sessionGroup.tooLong": "Category name length should be between 1-20",
|
||||
"shareModal.copy": "Copy",
|
||||
"shareModal.copyLink": "Copy Link",
|
||||
"shareModal.copyLinkSuccess": "Link copied",
|
||||
"shareModal.copyLinkSuccess": "Share link copied to clipboard",
|
||||
"shareModal.download": "Download Screenshot",
|
||||
"shareModal.downloadError": "Download failed",
|
||||
"shareModal.downloadFile": "Download File",
|
||||
@@ -517,17 +517,23 @@
|
||||
"shareModal.pdfErrorDescription": "An error occurred while generating the PDF, please try again",
|
||||
"shareModal.pdfGenerationError": "PDF generation failed",
|
||||
"shareModal.pdfReady": "PDF is ready",
|
||||
"shareModal.popover.moreOptions": "More share options",
|
||||
"shareModal.popover.privacyWarning.confirm": "I understand, continue",
|
||||
"shareModal.popover.privacyWarning.content": "Please make sure your conversation doesn't contain any personal or sensitive information. You are responsible for any content you choose to share and its consequences.",
|
||||
"shareModal.popover.export": "Export",
|
||||
"shareModal.popover.privacyWarning.confirm": "Share & copy link",
|
||||
"shareModal.popover.privacyWarning.content": "Anyone with the link can open this whole conversation, so take a moment to make sure there's nothing here you'd rather keep private. A shared topic may include:",
|
||||
"shareModal.popover.privacyWarning.doNotShowAgain": "Don't show this again",
|
||||
"shareModal.popover.privacyWarning.title": "Privacy Notice",
|
||||
"shareModal.popover.privacyWarning.items.credentials": "Credentials",
|
||||
"shareModal.popover.privacyWarning.items.files": "Uploaded files",
|
||||
"shareModal.popover.privacyWarning.items.images": "Images",
|
||||
"shareModal.popover.privacyWarning.items.toolCalls": "Connector calling details",
|
||||
"shareModal.popover.privacyWarning.note": "You can switch back to private anytime.",
|
||||
"shareModal.popover.privacyWarning.title": "Before you share this link",
|
||||
"shareModal.popover.title": "Share Topic",
|
||||
"shareModal.popover.visibility": "Visibility",
|
||||
"shareModal.regeneratePdf": "Regenerate PDF",
|
||||
"shareModal.screenshot": "Screenshot",
|
||||
"shareModal.settings": "Export Settings",
|
||||
"shareModal.text": "Text",
|
||||
"shareModal.title": "Export",
|
||||
"shareModal.widthMode.label": "Width Mode",
|
||||
"shareModal.widthMode.narrow": "Narrow",
|
||||
"shareModal.widthMode.wide": "Wide",
|
||||
@@ -545,7 +551,11 @@
|
||||
"sharePage.error.unauthorized.action": "Sign In",
|
||||
"sharePage.error.unauthorized.subtitle": "Please sign in to view this shared topic.",
|
||||
"sharePage.error.unauthorized.title": "Sign In Required",
|
||||
"sharePageDisclaimer": "This content is shared by a user and does not represent the views of LobeHub. LobeHub is not responsible for any consequences arising from this shared content.",
|
||||
"sharePage.menu.copyLink": "Copy Link",
|
||||
"sharePage.menu.goToLobeHub": "Go to LobeHub",
|
||||
"sharePage.menu.more": "More",
|
||||
"sharePage.menu.report": "Report",
|
||||
"sharePageDisclaimer": "Shared by a user. The content reflects their views, not LobeHub's, and LobeHub takes no responsibility for it.",
|
||||
"signalCallbacks.collapse": "Hide details",
|
||||
"signalCallbacks.empty": "No callback messages",
|
||||
"signalCallbacks.expand": "Show details",
|
||||
|
||||
+16
-6
@@ -487,7 +487,7 @@
|
||||
"sessionGroup.tooLong": "分类名称长度需为 1–20 个字符",
|
||||
"shareModal.copy": "复制",
|
||||
"shareModal.copyLink": "复制链接",
|
||||
"shareModal.copyLinkSuccess": "链接已复制",
|
||||
"shareModal.copyLinkSuccess": "分享链接已复制到剪贴板",
|
||||
"shareModal.download": "下载截图",
|
||||
"shareModal.downloadError": "下载失败,请检查网络后重试",
|
||||
"shareModal.downloadFile": "下载文件",
|
||||
@@ -517,17 +517,23 @@
|
||||
"shareModal.pdfErrorDescription": "生成 PDF 时出错,请重试或联系支持",
|
||||
"shareModal.pdfGenerationError": "PDF 生成失败",
|
||||
"shareModal.pdfReady": "PDF 已准备就绪",
|
||||
"shareModal.popover.moreOptions": "更多分享方式",
|
||||
"shareModal.popover.privacyWarning.confirm": "我已了解,继续",
|
||||
"shareModal.popover.privacyWarning.content": "请确保对话中不含个人隐私或敏感信息,LobeHub 不对任何分享的内容及其产生的后果负责。",
|
||||
"shareModal.popover.export": "导出",
|
||||
"shareModal.popover.privacyWarning.confirm": "分享并复制链接",
|
||||
"shareModal.popover.privacyWarning.content": "拿到链接的人都能查看整段对话,分享前花点时间确认其中没有不便公开的内容。被分享的话题可能包含:",
|
||||
"shareModal.popover.privacyWarning.doNotShowAgain": "不再显示此提示",
|
||||
"shareModal.popover.privacyWarning.title": "隐私提醒",
|
||||
"shareModal.popover.privacyWarning.items.credentials": "凭证与密钥",
|
||||
"shareModal.popover.privacyWarning.items.files": "上传的文件",
|
||||
"shareModal.popover.privacyWarning.items.images": "图片",
|
||||
"shareModal.popover.privacyWarning.items.toolCalls": "连接器调用详情",
|
||||
"shareModal.popover.privacyWarning.note": "你可以随时切回私密状态。",
|
||||
"shareModal.popover.privacyWarning.title": "分享链接前请留意",
|
||||
"shareModal.popover.title": "分享话题",
|
||||
"shareModal.popover.visibility": "可见性",
|
||||
"shareModal.regeneratePdf": "重新生成 PDF",
|
||||
"shareModal.screenshot": "截图",
|
||||
"shareModal.settings": "导出设置",
|
||||
"shareModal.text": "文本",
|
||||
"shareModal.title": "导出",
|
||||
"shareModal.widthMode.label": "宽度模式",
|
||||
"shareModal.widthMode.narrow": "窄屏",
|
||||
"shareModal.widthMode.wide": "宽屏",
|
||||
@@ -545,7 +551,11 @@
|
||||
"sharePage.error.unauthorized.action": "登录",
|
||||
"sharePage.error.unauthorized.subtitle": "请登录后查看此分享话题。",
|
||||
"sharePage.error.unauthorized.title": "需要登录",
|
||||
"sharePageDisclaimer": "此内容由用户分享,不代表 LobeHub 观点。LobeHub 不对该分享内容产生的任何后果承担责任。",
|
||||
"sharePage.menu.copyLink": "复制链接",
|
||||
"sharePage.menu.goToLobeHub": "前往 LobeHub",
|
||||
"sharePage.menu.more": "更多",
|
||||
"sharePage.menu.report": "举报",
|
||||
"sharePageDisclaimer": "由用户分享,仅代表其个人观点,不代表 LobeHub 立场;LobeHub 不对该内容承担责任。",
|
||||
"signalCallbacks.collapse": "隐藏详情",
|
||||
"signalCallbacks.empty": "没有回调消息",
|
||||
"signalCallbacks.expand": "显示详情",
|
||||
|
||||
@@ -547,7 +547,7 @@ export default {
|
||||
'sessionGroup.tooLong': 'Category name length should be between 1-20',
|
||||
'shareModal.copy': 'Copy',
|
||||
'shareModal.copyLink': 'Copy Link',
|
||||
'shareModal.copyLinkSuccess': 'Link copied',
|
||||
'shareModal.copyLinkSuccess': 'Share link copied to clipboard',
|
||||
'shareModal.download': 'Download Screenshot',
|
||||
'shareModal.downloadError': 'Download failed',
|
||||
'shareModal.downloadFile': 'Download File',
|
||||
@@ -577,18 +577,24 @@ export default {
|
||||
'shareModal.pdfErrorDescription': 'An error occurred while generating the PDF, please try again',
|
||||
'shareModal.pdfGenerationError': 'PDF generation failed',
|
||||
'shareModal.pdfReady': 'PDF is ready',
|
||||
'shareModal.popover.moreOptions': 'More share options',
|
||||
'shareModal.popover.privacyWarning.confirm': 'I understand, continue',
|
||||
'shareModal.popover.export': 'Export',
|
||||
'shareModal.popover.privacyWarning.confirm': 'Share & copy link',
|
||||
'shareModal.popover.privacyWarning.content':
|
||||
"Please make sure your conversation doesn't contain any personal or sensitive information. You are responsible for any content you choose to share and its consequences.",
|
||||
"Anyone with the link can open this whole conversation, so take a moment to make sure there's nothing here you'd rather keep private. A shared topic may include:",
|
||||
'shareModal.popover.privacyWarning.doNotShowAgain': "Don't show this again",
|
||||
'shareModal.popover.privacyWarning.title': 'Privacy Notice',
|
||||
'shareModal.popover.privacyWarning.items.credentials': 'Credentials',
|
||||
'shareModal.popover.privacyWarning.items.files': 'Uploaded files',
|
||||
'shareModal.popover.privacyWarning.items.images': 'Images',
|
||||
'shareModal.popover.privacyWarning.items.toolCalls': 'Connector calling details',
|
||||
'shareModal.popover.privacyWarning.note': 'You can switch back to private anytime.',
|
||||
'shareModal.popover.privacyWarning.title': 'Before you share this link',
|
||||
'shareModal.popover.title': 'Share Topic',
|
||||
'shareModal.popover.visibility': 'Visibility',
|
||||
'shareModal.regeneratePdf': 'Regenerate PDF',
|
||||
'shareModal.screenshot': 'Screenshot',
|
||||
'shareModal.settings': 'Export Settings',
|
||||
'shareModal.text': 'Text',
|
||||
'shareModal.title': 'Export',
|
||||
'shareModal.widthMode.label': 'Width Mode',
|
||||
'shareModal.widthMode.narrow': 'Narrow',
|
||||
'shareModal.widthMode.wide': 'Wide',
|
||||
@@ -606,8 +612,12 @@ export default {
|
||||
'sharePage.error.unauthorized.action': 'Sign In',
|
||||
'sharePage.error.unauthorized.subtitle': 'Please sign in to view this shared topic.',
|
||||
'sharePage.error.unauthorized.title': 'Sign In Required',
|
||||
'sharePage.menu.copyLink': 'Copy Link',
|
||||
'sharePage.menu.goToLobeHub': 'Go to LobeHub',
|
||||
'sharePage.menu.more': 'More',
|
||||
'sharePage.menu.report': 'Report',
|
||||
'sharePageDisclaimer':
|
||||
'This content is shared by a user and does not represent the views of LobeHub. LobeHub is not responsible for any consequences arising from this shared content.',
|
||||
"Shared by a user. The content reflects their views, not LobeHub's, and LobeHub takes no responsibility for it.",
|
||||
'signalCallbacks.collapse': 'Hide details',
|
||||
'signalCallbacks.empty': 'No callback messages',
|
||||
'signalCallbacks.expand': 'Show details',
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { t } from 'i18next';
|
||||
import { MessageSquare, Settings } from 'lucide-react';
|
||||
import useSWR from 'swr';
|
||||
import { Settings } from 'lucide-react';
|
||||
|
||||
import { lambdaClient } from '@/libs/trpc/client';
|
||||
import { routeMeta } from '@/spa/router/routeMeta';
|
||||
import { useAgentStore } from '@/store/agent';
|
||||
import { agentSelectors } from '@/store/agent/selectors';
|
||||
@@ -20,20 +18,3 @@ export const mobileAgentSettingsRouteMeta = routeMeta({
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const shareTopicRouteMeta = routeMeta({
|
||||
icon: MessageSquare,
|
||||
titleKey: 'navigation.chat',
|
||||
useDynamicMeta: (params) => {
|
||||
const shareId = params.id;
|
||||
const { data } = useSWR(
|
||||
shareId ? ['shared-topic', shareId] : null,
|
||||
() => lambdaClient.share.getSharedTopic.query({ shareId: shareId! }),
|
||||
{ revalidateOnFocus: false },
|
||||
);
|
||||
|
||||
return {
|
||||
title: data?.title || undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ export const openShareModal = ({
|
||||
styles: {
|
||||
content: { height: 'min(80vh, 800px)' },
|
||||
},
|
||||
title: t('share', { ns: 'common' }),
|
||||
title: t('shareModal.title', { ns: 'chat' }),
|
||||
width: 'min(90vw, 1024px)',
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,15 @@ import {
|
||||
} from '@lobehub/ui';
|
||||
import { confirmModal, Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Divider } from 'antd';
|
||||
import { ExternalLinkIcon, LinkIcon, LockIcon } from 'lucide-react';
|
||||
import {
|
||||
FileOutputIcon,
|
||||
ImageIcon,
|
||||
KeyRoundIcon,
|
||||
LinkIcon,
|
||||
LockIcon,
|
||||
PaperclipIcon,
|
||||
WrenchIcon,
|
||||
} from 'lucide-react';
|
||||
import { type ReactNode } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -30,6 +38,13 @@ import { styles } from './style';
|
||||
|
||||
type Visibility = 'private' | 'link';
|
||||
|
||||
const PRIVACY_WARNING_ITEMS = [
|
||||
{ icon: WrenchIcon, labelKey: 'shareModal.popover.privacyWarning.items.toolCalls' },
|
||||
{ icon: KeyRoundIcon, labelKey: 'shareModal.popover.privacyWarning.items.credentials' },
|
||||
{ icon: ImageIcon, labelKey: 'shareModal.popover.privacyWarning.items.images' },
|
||||
{ icon: PaperclipIcon, labelKey: 'shareModal.popover.privacyWarning.items.files' },
|
||||
] as const;
|
||||
|
||||
interface SharePopoverContentProps {
|
||||
onOpenModal?: () => void;
|
||||
topicId?: string;
|
||||
@@ -79,14 +94,20 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
try {
|
||||
await topicService.updateShareVisibility(activeTopicId, visibility);
|
||||
await mutate();
|
||||
message.success(t('shareModal.link.visibilityUpdated'));
|
||||
// Auto-copy the share link the moment link sharing is enabled
|
||||
if (visibility === 'link' && shareUrl) {
|
||||
await copyToClipboard(shareUrl);
|
||||
message.success(t('shareModal.copyLinkSuccess'));
|
||||
} else {
|
||||
message.success(t('shareModal.link.visibilityUpdated'));
|
||||
}
|
||||
} catch {
|
||||
message.error(t('shareModal.link.updateError'));
|
||||
} finally {
|
||||
setUpdating(false);
|
||||
}
|
||||
},
|
||||
[activeTopicId, mutate, message, t],
|
||||
[activeTopicId, mutate, message, t, shareUrl],
|
||||
);
|
||||
|
||||
const handleVisibilityChange = useCallback(
|
||||
@@ -102,18 +123,25 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: (
|
||||
<div>
|
||||
<p>{t('shareModal.popover.privacyWarning.content')}</p>
|
||||
<div style={{ marginTop: 16 }}>
|
||||
<Checkbox
|
||||
onChange={(v) => {
|
||||
doNotShowAgain = v;
|
||||
}}
|
||||
>
|
||||
{t('shareModal.popover.privacyWarning.doNotShowAgain')}
|
||||
</Checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<Flexbox gap={16}>
|
||||
<Text>{t('shareModal.popover.privacyWarning.content')}</Text>
|
||||
<Flexbox gap={12} paddingBlock={8}>
|
||||
{PRIVACY_WARNING_ITEMS.map(({ icon: ItemIcon, labelKey }) => (
|
||||
<Flexbox horizontal align="center" gap={8} key={labelKey}>
|
||||
<ItemIcon size={16} />
|
||||
<Text>{t(labelKey)}</Text>
|
||||
</Flexbox>
|
||||
))}
|
||||
</Flexbox>
|
||||
<Text>{t('shareModal.popover.privacyWarning.note')}</Text>
|
||||
<Checkbox
|
||||
onChange={(v) => {
|
||||
doNotShowAgain = v;
|
||||
}}
|
||||
>
|
||||
{t('shareModal.popover.privacyWarning.doNotShowAgain')}
|
||||
</Checkbox>
|
||||
</Flexbox>
|
||||
),
|
||||
okText: t('shareModal.popover.privacyWarning.confirm'),
|
||||
onOk: () => {
|
||||
@@ -223,13 +251,13 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
|
||||
<Flexbox horizontal align="center" justify="space-between">
|
||||
<Button
|
||||
icon={ExternalLinkIcon}
|
||||
icon={FileOutputIcon}
|
||||
size="small"
|
||||
type="text"
|
||||
variant="text"
|
||||
onClick={handleOpenModal}
|
||||
>
|
||||
{t('shareModal.popover.moreOptions')}
|
||||
{t('shareModal.popover.export')}
|
||||
</Button>
|
||||
{currentVisibility !== 'private' && (
|
||||
<Button icon={LinkIcon} size="small" type="primary" onClick={handleCopyLink}>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox, Text } from '@lobehub/ui';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { ChatList, ConversationProvider, MessageItem } from '@/features/Conversation';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
@@ -14,6 +16,7 @@ interface SharedMessageListProps {
|
||||
}
|
||||
|
||||
const SharedMessageList = memo<SharedMessageListProps>(({ agentId, groupId, shareId, topicId }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const context = useMemo(
|
||||
() => ({
|
||||
agentId: agentId ?? '',
|
||||
@@ -43,7 +46,17 @@ const SharedMessageList = memo<SharedMessageListProps>(({ agentId, groupId, shar
|
||||
replaceMessages(messages, { context: ctx });
|
||||
}}
|
||||
>
|
||||
<ChatList disableActionsBar itemContent={itemContent} />
|
||||
<ChatList
|
||||
disableActionsBar
|
||||
itemContent={itemContent}
|
||||
footerSlot={
|
||||
<Flexbox align={'center'} paddingBlock={'16px 80px'} paddingInline={24}>
|
||||
<Text fontSize={12} style={{ maxWidth: 480, textAlign: 'center' }} type={'secondary'}>
|
||||
{t('sharePageDisclaimer')}
|
||||
</Text>
|
||||
</Flexbox>
|
||||
}
|
||||
/>
|
||||
</ConversationProvider>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, copyToClipboard } from '@lobehub/ui';
|
||||
import { type DropdownItem, DropdownMenu } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { ExternalLink, Flag, LinkIcon, MoreHorizontal } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { mailTo, OFFICIAL_SITE } from '@/const/url';
|
||||
|
||||
const REPORT_EMAIL = 'hi@lobehub.com';
|
||||
|
||||
const HeaderMenu = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { message } = App.useApp();
|
||||
|
||||
const handleCopyLink = useCallback(async () => {
|
||||
await copyToClipboard(window.location.href);
|
||||
message.success(t('shareModal.copyLinkSuccess'));
|
||||
}, [message, t]);
|
||||
|
||||
const items = useMemo<DropdownItem[]>(
|
||||
() => [
|
||||
{
|
||||
icon: <LinkIcon size={16} />,
|
||||
key: 'copy-link',
|
||||
label: t('sharePage.menu.copyLink'),
|
||||
onClick: handleCopyLink,
|
||||
},
|
||||
{
|
||||
icon: <ExternalLink size={16} />,
|
||||
key: 'go-to-lobehub',
|
||||
label: (
|
||||
<a href={OFFICIAL_SITE} rel="noopener noreferrer" target="_blank">
|
||||
{t('sharePage.menu.goToLobeHub')}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
icon: <Flag size={16} />,
|
||||
key: 'report',
|
||||
label: <a href={mailTo(REPORT_EMAIL)}>{t('sharePage.menu.report')}</a>,
|
||||
},
|
||||
],
|
||||
[t, handleCopyLink],
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenu items={items} placement={'bottomRight'}>
|
||||
<ActionIcon icon={MoreHorizontal} title={t('sharePage.menu.more')} />
|
||||
</DropdownMenu>
|
||||
);
|
||||
});
|
||||
|
||||
HeaderMenu.displayName = 'ShareTopicHeaderMenu';
|
||||
|
||||
export default HeaderMenu;
|
||||
@@ -1,11 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { Alert, Center, Flexbox } from '@lobehub/ui';
|
||||
import { Center, Flexbox } from '@lobehub/ui';
|
||||
import { cx } from 'antd-style';
|
||||
import NextLink from 'next/link';
|
||||
import { type PropsWithChildren } from 'react';
|
||||
import { memo, Suspense } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link, Outlet } from 'react-router-dom';
|
||||
|
||||
import { ProductLogo } from '@/components/Branding';
|
||||
@@ -17,11 +16,11 @@ import { useUserStore } from '@/store/user';
|
||||
import { authSelectors } from '@/store/user/slices/auth/selectors';
|
||||
|
||||
import SharePortal from '../features/Portal';
|
||||
import HeaderMenu from './HeaderMenu';
|
||||
import { styles } from './style';
|
||||
import Title from './Title';
|
||||
|
||||
const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const isDarkMode = useIsDark();
|
||||
const isLogin = useUserStore(authSelectors.isLogin);
|
||||
|
||||
@@ -68,7 +67,9 @@ const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
||||
<Title />
|
||||
</Suspense>
|
||||
</Center>
|
||||
<Flexbox horizontal align="center" flex={1} gap={12} justify={'flex-end'} />
|
||||
<Flexbox horizontal align="center" flex={1} gap={12} justify={'flex-end'}>
|
||||
<HeaderMenu />
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
<Flexbox horizontal className={styles.content} style={{ overflow: 'hidden' }}>
|
||||
<Flexbox flex={1} style={{ overflow: 'hidden' }}>
|
||||
@@ -78,9 +79,6 @@ const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
||||
</Flexbox>
|
||||
<SharePortal />
|
||||
</Flexbox>
|
||||
<Center padding={8} style={{ opacity: 0.25 }}>
|
||||
<Alert title={t('sharePageDisclaimer')} type={'secondary'} variant={'borderless'} />
|
||||
</Center>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
@@ -81,6 +81,7 @@ const ActionBar = memo<ActionBarProps>(({ data }) => {
|
||||
borderRadius: 48,
|
||||
boxShadow: '0 2px 12px -4px rgba(0, 0, 0, 0.1)',
|
||||
maxWidth: 960,
|
||||
pointerEvents: 'auto',
|
||||
}}
|
||||
>
|
||||
<Flexbox horizontal align="center" gap={8}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Center } from '@lobehub/ui';
|
||||
import { Button, Center, Flexbox } from '@lobehub/ui';
|
||||
import { TRPCClientError } from '@trpc/client';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { memo } from 'react';
|
||||
@@ -106,17 +106,25 @@ const ShareTopicPage = memo(() => {
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flexbox height={'100%'} style={{ position: 'relative' }} width={'100%'}>
|
||||
<SharedMessageList
|
||||
agentId={data.agentId}
|
||||
groupId={data.groupId}
|
||||
shareId={data.shareId}
|
||||
topicId={data.topicId}
|
||||
/>
|
||||
<Center padding={8}>
|
||||
<Center
|
||||
paddingBlock={16}
|
||||
style={{
|
||||
bottom: 0,
|
||||
insetInline: 0,
|
||||
pointerEvents: 'none',
|
||||
position: 'absolute',
|
||||
}}
|
||||
>
|
||||
<ActionBar data={data} />
|
||||
</Center>
|
||||
</>
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { MessageSquare } from 'lucide-react';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { lambdaClient } from '@/libs/trpc/client';
|
||||
import { routeMeta } from '@/spa/router/routeMeta';
|
||||
|
||||
export const shareTopicRouteMeta = routeMeta({
|
||||
icon: MessageSquare,
|
||||
titleKey: 'navigation.chat',
|
||||
useDynamicMeta: (params) => {
|
||||
const shareId = params.id;
|
||||
const { data } = useSWR(
|
||||
shareId ? ['shared-topic', shareId] : null,
|
||||
() => lambdaClient.share.getSharedTopic.query({ shareId: shareId! }),
|
||||
{ revalidateOnFocus: false },
|
||||
);
|
||||
|
||||
return {
|
||||
title: data?.title || undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -114,6 +114,7 @@ import AllTasksPage from '@/routes/(main)/tasks';
|
||||
import SharePagePage from '@/routes/share/page/[id]';
|
||||
import ShareTopicPage from '@/routes/share/t/[id]';
|
||||
import ShareTopicLayout from '@/routes/share/t/[id]/_layout';
|
||||
import { shareTopicRouteMeta } from '@/routes/share/t/[id]/routeMeta';
|
||||
import { routeMeta } from '@/spa/router/routeMeta';
|
||||
import { SettingsTabs } from '@/store/global/initialState';
|
||||
import { ErrorBoundary, redirectElement } from '@/utils/router';
|
||||
@@ -693,6 +694,7 @@ export const desktopRoutes: RouteObject[] = [
|
||||
children: [
|
||||
{
|
||||
element: <ShareTopicPage />,
|
||||
handle: { meta: shareTopicRouteMeta },
|
||||
path: ':id',
|
||||
},
|
||||
],
|
||||
|
||||
@@ -20,6 +20,7 @@ import { pageRouteMeta } from '@/features/Pages/routeMeta';
|
||||
import { agentRouteMeta } from '@/routes/(main)/agent/features/routeMeta';
|
||||
import { groupRouteMeta } from '@/routes/(main)/group/features/routeMeta';
|
||||
import { settingsRouteMeta } from '@/routes/(main)/settings/features/routeMeta';
|
||||
import { shareTopicRouteMeta } from '@/routes/share/t/[id]/routeMeta';
|
||||
import { routeMeta } from '@/spa/router/routeMeta';
|
||||
import { SettingsTabs } from '@/store/global/initialState';
|
||||
import { dynamicElement, dynamicLayout, ErrorBoundary, redirectElement } from '@/utils/router';
|
||||
@@ -890,6 +891,7 @@ export const desktopRoutes: RouteObject[] = [
|
||||
children: [
|
||||
{
|
||||
element: dynamicElement(() => import('@/routes/share/t/[id]'), 'Desktop > Share > Topic'),
|
||||
handle: { meta: shareTopicRouteMeta },
|
||||
path: ':id',
|
||||
},
|
||||
],
|
||||
|
||||
@@ -6,11 +6,9 @@ import {
|
||||
BusinessMobileRoutesWithMainLayout,
|
||||
BusinessMobileRoutesWithoutMainLayout,
|
||||
} from '@/business/client/BusinessMobileRoutes';
|
||||
import {
|
||||
mobileAgentSettingsRouteMeta,
|
||||
shareTopicRouteMeta,
|
||||
} from '@/features/RouteMeta/mobileRouteMeta';
|
||||
import { mobileAgentSettingsRouteMeta } from '@/features/RouteMeta/mobileRouteMeta';
|
||||
import { agentRouteMeta } from '@/routes/(main)/agent/features/routeMeta';
|
||||
import { shareTopicRouteMeta } from '@/routes/share/t/[id]/routeMeta';
|
||||
import { dynamicElement, dynamicLayout, ErrorBoundary, redirectElement } from '@/utils/router';
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user