mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 17:47:27 +00:00
💄 style: Update Sync Style
This commit is contained in:
parent
4d573ab697
commit
3aa8be4a13
7 changed files with 293 additions and 227 deletions
|
|
@ -4,7 +4,6 @@ import { ActionIcon, Logo, MobileNavBar } from '@lobehub/ui';
|
|||
import { MessageSquarePlus } from 'lucide-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { memo } from 'react';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import { MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
||||
import SyncStatusInspector from '@/features/SyncStatusInspector';
|
||||
|
|
@ -16,25 +15,23 @@ import { mobileHeaderSticky } from '@/styles/mobileHeader';
|
|||
const Header = memo(() => {
|
||||
const [createSession] = useSessionStore((s) => [s.createSession]);
|
||||
const router = useRouter();
|
||||
const { enableWebrtc, showCreateSession } = useServerConfigStore(featureFlagsSelectors);
|
||||
const { showCreateSession, enableWebrtc } = useServerConfigStore(featureFlagsSelectors);
|
||||
|
||||
return (
|
||||
<MobileNavBar
|
||||
left={
|
||||
<Flexbox align={'center'} gap={8} horizontal style={{ marginLeft: 8 }}>
|
||||
<UserAvatar onClick={() => router.push('/me')} size={32} />
|
||||
<Logo type={'text'} />
|
||||
{enableWebrtc && <SyncStatusInspector placement={'bottom'} />}
|
||||
</Flexbox>
|
||||
}
|
||||
center={<Logo type={'text'} />}
|
||||
left={<UserAvatar onClick={() => router.push('/me')} size={32} />}
|
||||
right={
|
||||
showCreateSession && (
|
||||
<ActionIcon
|
||||
icon={MessageSquarePlus}
|
||||
onClick={() => createSession()}
|
||||
size={MOBILE_HEADER_ICON_SIZE}
|
||||
/>
|
||||
)
|
||||
<>
|
||||
{enableWebrtc && <SyncStatusInspector mobile />}
|
||||
{showCreateSession && (
|
||||
<ActionIcon
|
||||
icon={MessageSquarePlus}
|
||||
onClick={() => createSession()}
|
||||
size={MOBILE_HEADER_ICON_SIZE}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
style={mobileHeaderSticky}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const useStyles = createStyles(
|
|||
|
||||
background: ${inverseTheme ? rgba(token.colorTextTertiary, 0.15) : token.colorFillTertiary};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
box-shadow: 0 0 0 1px ${rgba(token.colorBorder, 0.1)} inset;
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
|
@ -67,7 +68,7 @@ const HotKeys = memo<HotKeysProps>(({ keys, desc, inverseTheme }) => {
|
|||
|
||||
if (!desc) return content;
|
||||
return (
|
||||
<Flexbox gap={16} horizontal>
|
||||
<Flexbox align={'center'} gap={4} style={{ paddingBottom: 4 }}>
|
||||
{desc}
|
||||
{content}
|
||||
</Flexbox>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,25 @@
|
|||
import { Icon, Tag } from '@lobehub/ui';
|
||||
import { Badge, Button, Popover } from 'antd';
|
||||
import { TooltipPlacement } from 'antd/es/tooltip';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { Button, Popover } from 'antd';
|
||||
import { LucideCloudCog, LucideCloudy } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import { useOpenSettings } from '@/hooks/useInterceptingRoutes';
|
||||
import { SettingsTabs } from '@/store/global/initialState';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { syncSettingsSelectors } from '@/store/user/selectors';
|
||||
|
||||
import { DisableTag } from './SyncTags';
|
||||
|
||||
interface DisableSyncProps {
|
||||
mobile?: boolean;
|
||||
noPopover?: boolean;
|
||||
placement?: TooltipPlacement;
|
||||
}
|
||||
|
||||
const DisableSync = memo<DisableSyncProps>(({ noPopover, placement = 'bottomLeft' }) => {
|
||||
const DisableSync = memo<DisableSyncProps>(({ noPopover, mobile }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const openSettings = useOpenSettings();
|
||||
const [haveConfig, setSettings] = useUserStore((s) => [
|
||||
!!syncSettingsSelectors.webrtcConfig(s).channelName,
|
||||
s.setSettings,
|
||||
|
|
@ -26,52 +29,53 @@ const DisableSync = memo<DisableSyncProps>(({ noPopover, placement = 'bottomLeft
|
|||
setSettings({ sync: { webrtc: { enabled: true } } });
|
||||
};
|
||||
|
||||
const tag = (
|
||||
<div>
|
||||
<Tag>
|
||||
<Badge status="default" />
|
||||
{t('sync.status.disabled')}
|
||||
</Tag>
|
||||
</div>
|
||||
if (noPopover) return <DisableTag mobile={mobile} />;
|
||||
|
||||
const title = (
|
||||
<Flexbox gap={8} horizontal>
|
||||
<Icon icon={LucideCloudy} />
|
||||
{t('sync.disabled.title')}
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
return noPopover ? (
|
||||
tag
|
||||
) : (
|
||||
const content = (
|
||||
<Flexbox gap={12} width={mobile ? 240 : 320}>
|
||||
{t('sync.disabled.desc')}
|
||||
{haveConfig ? (
|
||||
<Flexbox gap={8} horizontal={!mobile}>
|
||||
<Button
|
||||
block
|
||||
icon={<Icon icon={LucideCloudCog} />}
|
||||
onClick={() => openSettings(SettingsTabs.Sync)}
|
||||
>
|
||||
{t('sync.disabled.actions.settings')}
|
||||
</Button>
|
||||
<Button block onClick={enableSync} type={'primary'}>
|
||||
{t('sync.disabled.actions.enable')}
|
||||
</Button>
|
||||
</Flexbox>
|
||||
) : (
|
||||
<Button
|
||||
block
|
||||
icon={<Icon icon={LucideCloudCog} />}
|
||||
onClick={() => openSettings(SettingsTabs.Sync)}
|
||||
type={'primary'}
|
||||
>
|
||||
{t('sync.disabled.actions.settings')}
|
||||
</Button>
|
||||
)}
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
arrow={false}
|
||||
content={
|
||||
<Flexbox gap={12} width={320}>
|
||||
{t('sync.disabled.desc')}
|
||||
{haveConfig ? (
|
||||
<Flexbox gap={8} horizontal>
|
||||
<Link href={'/settings/sync'}>
|
||||
<Button block icon={<Icon icon={LucideCloudCog} />}>
|
||||
{t('sync.disabled.actions.settings')}
|
||||
</Button>
|
||||
</Link>
|
||||
<Button block onClick={enableSync} type={'primary'}>
|
||||
{t('sync.disabled.actions.enable')}
|
||||
</Button>
|
||||
</Flexbox>
|
||||
) : (
|
||||
<Link href={'/settings/sync'}>
|
||||
<Button block icon={<Icon icon={LucideCloudCog} />} type={'primary'}>
|
||||
{t('sync.disabled.actions.settings')}
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</Flexbox>
|
||||
}
|
||||
placement={placement}
|
||||
title={
|
||||
<Flexbox gap={8} horizontal>
|
||||
<Icon icon={LucideCloudy} />
|
||||
{t('sync.disabled.title')}
|
||||
</Flexbox>
|
||||
}
|
||||
content={content}
|
||||
placement={'bottomLeft'}
|
||||
title={title}
|
||||
trigger={['click']}
|
||||
>
|
||||
{tag}
|
||||
<DisableTag mobile={mobile} />
|
||||
</Popover>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,18 @@
|
|||
import { ActionIcon, Avatar, Icon } from '@lobehub/ui';
|
||||
import { Divider, Popover, Switch, Tag, Typography } from 'antd';
|
||||
import { ActionIcon, Avatar, Icon, Snippet, Tag } from '@lobehub/ui';
|
||||
import { Divider, Popover, Switch, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { TooltipPlacement } from 'antd/es/tooltip';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { LucideCloudy, LucideLaptop, LucideSmartphone, SettingsIcon } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { LucideCloudCog, LucideLaptop, LucideSmartphone } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import { useOpenSettings } from '@/hooks/useInterceptingRoutes';
|
||||
import { SettingsTabs } from '@/store/global/initialState';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { syncSettingsSelectors } from '@/store/user/selectors';
|
||||
import { pathString } from '@/utils/url';
|
||||
|
||||
import EnableTag from './EnableTag';
|
||||
|
||||
const { Text } = Typography;
|
||||
import { EnableTag } from './SyncTags';
|
||||
|
||||
const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
||||
text: css`
|
||||
|
|
@ -26,18 +23,19 @@ const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
|||
}
|
||||
`,
|
||||
title: css`
|
||||
color: ${token.colorTextTertiary};
|
||||
flex: none;
|
||||
color: ${token.colorTextSecondary};
|
||||
`,
|
||||
}));
|
||||
|
||||
interface EnableSyncProps {
|
||||
hiddenActions?: boolean;
|
||||
placement?: TooltipPlacement;
|
||||
mobile?: boolean;
|
||||
}
|
||||
|
||||
const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLeft' }) => {
|
||||
const EnableSync = memo<EnableSyncProps>(({ hiddenActions, mobile }) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const openSettings = useOpenSettings();
|
||||
const { styles, theme } = useStyles();
|
||||
const [syncStatus, isSyncing, channelName, enableWebRTC, setSettings] = useUserStore((s) => [
|
||||
s.syncStatus,
|
||||
|
|
@ -53,82 +51,80 @@ const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLe
|
|||
setSettings({ sync: { webrtc: { enabled } } });
|
||||
};
|
||||
|
||||
const title = (
|
||||
<Flexbox align={'center'} distribution={'space-between'} horizontal style={{ minWidth: 240 }}>
|
||||
{t('sync.title')}
|
||||
<Flexbox align={'center'} gap={8} horizontal>
|
||||
{!hiddenActions && <Switch checked={enableWebRTC} onChange={switchSync} size={'small'} />}
|
||||
{!hiddenActions && (
|
||||
<ActionIcon
|
||||
icon={LucideCloudCog}
|
||||
onClick={() => openSettings(SettingsTabs.Sync)}
|
||||
size={{ blockSize: 24, fontSize: 16 }}
|
||||
title={t('sync.actions.settings')}
|
||||
/>
|
||||
)}
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
const content = (
|
||||
<Flexbox gap={16} style={{ minWidth: 240 }}>
|
||||
<Flexbox gap={4} width={'100%'}>
|
||||
<div className={styles.title}>
|
||||
{[t('sync.channel'), mobile && t(`sync.status.${syncStatus}`)]
|
||||
.filter(Boolean)
|
||||
.join(' · ')}
|
||||
</div>
|
||||
<Snippet language={'text'} style={{ flex: 1 }} type={'block'}>
|
||||
{String(channelName)}
|
||||
</Snippet>
|
||||
</Flexbox>
|
||||
<Divider dashed style={{ margin: 0 }} />
|
||||
<Flexbox gap={12}>
|
||||
{users.map((user) => (
|
||||
<Flexbox align={'center'} gap={12} horizontal key={user.clientID}>
|
||||
<Avatar
|
||||
avatar={
|
||||
<Icon
|
||||
color={theme.colorBgLayout}
|
||||
icon={user.isMobile ? LucideSmartphone : LucideLaptop}
|
||||
size={{ fontSize: 24 }}
|
||||
/>
|
||||
}
|
||||
background={theme.colorPrimary}
|
||||
shape={'square'}
|
||||
size={36}
|
||||
style={{ flex: 'none' }}
|
||||
/>
|
||||
<Flexbox>
|
||||
<Flexbox gap={8} horizontal>
|
||||
{user.name || user.id}
|
||||
{user.current && (
|
||||
<Flexbox horizontal>
|
||||
<Tag>{t('sync.awareness.current')}</Tag>
|
||||
</Flexbox>
|
||||
)}
|
||||
</Flexbox>
|
||||
<Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
|
||||
{[user.os, user.browser].join(' · ')}
|
||||
</Typography.Text>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
))}
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
arrow={false}
|
||||
content={
|
||||
<Flexbox gap={16}>
|
||||
<Flexbox align={'center'} gap={24} horizontal>
|
||||
<Flexbox
|
||||
align={'center'}
|
||||
className={styles.title}
|
||||
gap={4}
|
||||
horizontal
|
||||
style={{ paddingInlineEnd: 12 }}
|
||||
>
|
||||
{t('sync.channel')}
|
||||
<Text className={styles.text} copyable>
|
||||
{channelName}
|
||||
</Text>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
<Divider dashed style={{ margin: 0 }} />
|
||||
<Flexbox gap={12}>
|
||||
{users.map((user) => (
|
||||
<Flexbox gap={12} horizontal key={user.clientID}>
|
||||
<Avatar
|
||||
avatar={
|
||||
<Icon
|
||||
color={theme.purple}
|
||||
icon={user.isMobile ? LucideSmartphone : LucideLaptop}
|
||||
size={{ fontSize: 24 }}
|
||||
/>
|
||||
}
|
||||
background={theme.purple1}
|
||||
shape={'square'}
|
||||
/>
|
||||
|
||||
<Flexbox>
|
||||
<Flexbox gap={8} horizontal>
|
||||
{user.name || user.id}
|
||||
{user.current && (
|
||||
<Flexbox horizontal>
|
||||
<Tag bordered={false} color={'blue'}>
|
||||
{t('sync.awareness.current')}
|
||||
</Tag>
|
||||
</Flexbox>
|
||||
)}
|
||||
</Flexbox>
|
||||
<Typography.Text type={'secondary'}>
|
||||
{user.os} · {user.browser}
|
||||
</Typography.Text>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
))}
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
}
|
||||
placement={placement}
|
||||
title={
|
||||
<Flexbox distribution={'space-between'} horizontal>
|
||||
<Flexbox align={'center'} gap={8} horizontal>
|
||||
<Icon icon={LucideCloudy} />
|
||||
{t('sync.title')}
|
||||
{!hiddenActions && (
|
||||
<Switch checked={enableWebRTC} onChange={switchSync} size={'small'} />
|
||||
)}
|
||||
</Flexbox>
|
||||
{!hiddenActions && (
|
||||
<Link href={pathString('/settings/sync')}>
|
||||
<ActionIcon icon={SettingsIcon} title={t('sync.actions.settings')} />
|
||||
</Link>
|
||||
)}
|
||||
</Flexbox>
|
||||
}
|
||||
content={content}
|
||||
placement={mobile ? 'bottom' : 'bottomLeft'}
|
||||
title={title}
|
||||
trigger={['click']}
|
||||
>
|
||||
<div>
|
||||
<EnableTag isSyncing={isSyncing} status={syncStatus} />
|
||||
</div>
|
||||
<EnableTag isSyncing={isSyncing} mobile={mobile} status={syncStatus} />
|
||||
</Popover>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
import { Icon, Tooltip } from '@lobehub/ui';
|
||||
import { Badge, Tag } from 'antd';
|
||||
import { LucideCloudy, LucideRefreshCw, LucideRouter, LucideWifiOff } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { PeerSyncStatus } from '@/types/sync';
|
||||
|
||||
const EnableTag = memo<{ isSyncing: boolean; status: PeerSyncStatus }>(({ status, isSyncing }) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
switch (status) {
|
||||
case PeerSyncStatus.Connecting: {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={'blue'}
|
||||
icon={<Badge color={'blue'} status="processing" />}
|
||||
style={{ display: 'flex', gap: 4 }}
|
||||
>
|
||||
{t('sync.status.connecting')}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Synced: {
|
||||
return (
|
||||
<Tag bordered={false} color={'green'} icon={<Icon icon={LucideCloudy} />}>
|
||||
{t('sync.status.synced')}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Ready: {
|
||||
return (
|
||||
<Tag bordered={false} color={'blue'} icon={<Icon icon={LucideRouter} />}>
|
||||
{t('sync.status.ready')}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Syncing: {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={'blue'}
|
||||
icon={<Icon icon={LucideRefreshCw} spin={isSyncing} />}
|
||||
>
|
||||
{t('sync.status.syncing')}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Unconnected: {
|
||||
return (
|
||||
<Tooltip title={t('sync.unconnected.tip')}>
|
||||
<Tag bordered={false} color={'red'} icon={<Icon icon={LucideWifiOff} />}>
|
||||
{t('sync.status.unconnected')}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default EnableTag;
|
||||
137
src/features/SyncStatusInspector/SyncTags.tsx
Normal file
137
src/features/SyncStatusInspector/SyncTags.tsx
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import { ActionIcon, DivProps, Icon, Tooltip } from '@lobehub/ui';
|
||||
import { Tag } from 'antd';
|
||||
import { useTheme } from 'antd-style';
|
||||
import {
|
||||
LucideCloudCog,
|
||||
LucideCloudy,
|
||||
LucideIcon,
|
||||
LucideRefreshCw,
|
||||
LucideRouter,
|
||||
LucideWifiOff,
|
||||
Radio,
|
||||
} from 'lucide-react';
|
||||
import { CSSProperties, memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
||||
import { PeerSyncStatus } from '@/types/sync';
|
||||
|
||||
export const TAG_STYLE: CSSProperties = {
|
||||
borderRadius: 12,
|
||||
cursor: 'pointer',
|
||||
display: 'block',
|
||||
};
|
||||
|
||||
export interface EnableTagProps extends DivProps {
|
||||
isSyncing: boolean;
|
||||
mobile?: boolean;
|
||||
status: PeerSyncStatus;
|
||||
}
|
||||
|
||||
export const EnableTag = memo<EnableTagProps>(({ status, isSyncing, mobile, style, ...rest }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const config = useMemo(() => {
|
||||
switch (status) {
|
||||
case PeerSyncStatus.Connecting: {
|
||||
return {
|
||||
icon: Radio,
|
||||
style: {
|
||||
background: theme.colorWarningBg,
|
||||
color: theme.colorWarning,
|
||||
},
|
||||
title: t('sync.status.connecting'),
|
||||
};
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Synced: {
|
||||
return {
|
||||
icon: LucideCloudy,
|
||||
style: {
|
||||
background: theme.colorSuccessBg,
|
||||
color: theme.colorSuccess,
|
||||
},
|
||||
title: t('sync.status.synced'),
|
||||
};
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Ready: {
|
||||
return {
|
||||
icon: LucideRouter,
|
||||
style: {
|
||||
background: theme.colorInfoBg,
|
||||
color: theme.colorInfo,
|
||||
},
|
||||
title: t('sync.status.ready'),
|
||||
};
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Syncing: {
|
||||
return {
|
||||
icon: LucideRefreshCw,
|
||||
style: {
|
||||
background: theme.colorWarningBg,
|
||||
color: theme.colorWarning,
|
||||
},
|
||||
title: t('sync.status.syncing'),
|
||||
};
|
||||
}
|
||||
|
||||
case PeerSyncStatus.Unconnected: {
|
||||
return {
|
||||
icon: LucideWifiOff,
|
||||
style: {
|
||||
background: theme.colorErrorBg,
|
||||
color: theme.colorError,
|
||||
},
|
||||
title: t('sync.status.unconnected'),
|
||||
tooltip: t('sync.unconnected.tip'),
|
||||
};
|
||||
}
|
||||
}
|
||||
}, [status, t, theme]) as {
|
||||
icon: LucideIcon;
|
||||
style: CSSProperties;
|
||||
title: string;
|
||||
tooltip?: string;
|
||||
};
|
||||
|
||||
if (mobile)
|
||||
return (
|
||||
<ActionIcon
|
||||
color={config.style.color === theme.colorInfo ? undefined : config.style.color}
|
||||
icon={config.icon}
|
||||
loading={isSyncing}
|
||||
size={MOBILE_HEADER_ICON_SIZE}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
||||
const tag = (
|
||||
<Tag
|
||||
bordered={false}
|
||||
icon={<Icon icon={config.icon} spin={isSyncing} />}
|
||||
style={{ ...TAG_STYLE, ...config.style, ...style }}
|
||||
{...rest}
|
||||
>
|
||||
{config.title}
|
||||
</Tag>
|
||||
);
|
||||
|
||||
if (!config.tooltip) return tag;
|
||||
|
||||
return <Tooltip title={config.tooltip}>{tag}</Tooltip>;
|
||||
});
|
||||
|
||||
export const DisableTag = memo<DivProps & { mobile?: boolean }>(({ style, mobile, ...rest }) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
if (mobile) return <ActionIcon icon={LucideCloudCog} size={MOBILE_HEADER_ICON_SIZE} {...rest} />;
|
||||
|
||||
return (
|
||||
<Tag bordered={false} style={{ ...TAG_STYLE, ...style }} {...rest}>
|
||||
{t('sync.status.disabled')}
|
||||
</Tag>
|
||||
);
|
||||
});
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { TooltipPlacement } from 'antd/es/tooltip';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { useUserStore } from '@/store/user';
|
||||
|
|
@ -9,19 +8,17 @@ import EnableSync from './EnableSync';
|
|||
interface SyncStatusTagProps {
|
||||
hiddenActions?: boolean;
|
||||
hiddenEnableGuide?: boolean;
|
||||
placement?: TooltipPlacement;
|
||||
mobile?: boolean;
|
||||
}
|
||||
|
||||
const SyncStatusTag = memo<SyncStatusTagProps>(
|
||||
({ hiddenActions, placement, hiddenEnableGuide }) => {
|
||||
const [enableSync] = useUserStore((s) => [s.syncEnabled]);
|
||||
const SyncStatusTag = memo<SyncStatusTagProps>(({ hiddenActions, hiddenEnableGuide, mobile }) => {
|
||||
const [enableSync] = useUserStore((s) => [s.syncEnabled]);
|
||||
|
||||
return enableSync ? (
|
||||
<EnableSync hiddenActions={hiddenActions} placement={placement} />
|
||||
) : (
|
||||
<DisableSync noPopover={hiddenEnableGuide} placement={placement} />
|
||||
);
|
||||
},
|
||||
);
|
||||
return enableSync ? (
|
||||
<EnableSync hiddenActions={hiddenActions} mobile={mobile} />
|
||||
) : (
|
||||
<DisableSync mobile={mobile} noPopover={hiddenEnableGuide} />
|
||||
);
|
||||
});
|
||||
|
||||
export default SyncStatusTag;
|
||||
|
|
|
|||
Loading…
Reference in a new issue