@lobehub/lobehub 2.0.0-next.213 → 2.0.0-next.215
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/e2e.yml +1 -1
- package/.github/workflows/pr-build-desktop.yml +2 -2
- package/.github/workflows/release-desktop-beta.yml +2 -2
- package/.github/workflows/release.yml +1 -1
- package/.github/workflows/test.yml +2 -2
- package/CHANGELOG.md +51 -0
- package/apps/desktop/package.json +3 -2
- package/apps/desktop/src/main/const/store.ts +1 -1
- package/apps/desktop/src/main/controllers/SystemCtr.ts +2 -3
- package/apps/desktop/src/main/core/App.ts +10 -3
- package/apps/desktop/src/main/types/store.ts +1 -1
- package/changelog/v1.json +14 -0
- package/package.json +4 -3
- package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx +4 -2
- package/packages/builtin-tool-local-system/src/client/Intervention/EditLocalFile/index.tsx +3 -2
- package/packages/builtin-tool-local-system/src/client/Render/EditLocalFile/index.tsx +3 -2
- package/packages/const/src/theme.ts +0 -2
- package/packages/desktop-bridge/src/routeVariants.ts +2 -9
- package/packages/electron-client-ipc/src/types/system.ts +1 -1
- package/scripts/electronWorkflow/modifiers/nextConfig.mts +41 -13
- package/src/app/[variants]/(auth)/_layout/index.tsx +3 -2
- package/src/app/[variants]/(auth)/_layout/style.ts +8 -18
- package/src/app/[variants]/(auth)/layout.tsx +7 -3
- package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/index.tsx +4 -2
- package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/style.ts +3 -0
- package/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx +3 -2
- package/src/app/[variants]/(main)/chat/profile/features/ProfileEditor/PluginTag.tsx +3 -2
- package/src/app/[variants]/(main)/community/(list)/_layout/Footer.tsx +3 -2
- package/src/app/[variants]/(main)/group/features/Conversation/ChatItem/Thread.tsx +3 -2
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/index.tsx +0 -1
- package/src/app/[variants]/(main)/group/profile/features/ProfileEditor/PluginTag.tsx +3 -2
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentItem/Editing.tsx +2 -2
- package/src/app/[variants]/(main)/home/_layout/Footer/index.tsx +1 -1
- package/src/app/[variants]/(main)/home/_layout/index.tsx +3 -2
- package/src/app/[variants]/(main)/home/features/CommunityAgents/Item.tsx +3 -2
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/AspectRatioSelect/index.tsx +4 -2
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ModelSelect/ImageModelItem.tsx +3 -2
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/Select/index.tsx +4 -2
- package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +3 -2
- package/src/app/[variants]/(main)/memory/features/TimeLineView/index.tsx +9 -4
- package/src/app/[variants]/(main)/page/_layout/Body/List/Item/Editing.tsx +2 -2
- package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +11 -11
- package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +3 -2
- package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/TotalCard.tsx +4 -2
- package/src/app/[variants]/(mobile)/me/(home)/features/Header.tsx +6 -8
- package/src/app/[variants]/layout.tsx +10 -15
- package/src/app/[variants]/onboarding/_layout/index.tsx +3 -2
- package/src/app/[variants]/onboarding/features/ModeSelectionStep.tsx +3 -2
- package/src/app/[variants]/router/index.tsx +12 -8
- package/src/components/Cell/Divider.tsx +4 -2
- package/src/components/DataStyleModal/index.tsx +4 -2
- package/src/components/FeatureList/index.tsx +4 -2
- package/src/components/FileParsingStatus/EmbeddingStatus.tsx +3 -2
- package/src/components/FileParsingStatus/index.tsx +3 -2
- package/src/components/Notification/index.tsx +4 -2
- package/src/components/client/ClientOnly.tsx +17 -0
- package/src/features/AlertBanner/CloudBanner.tsx +4 -3
- package/src/features/CommandMenu/ThemeMenu.tsx +1 -1
- package/src/features/CommandMenu/types.ts +5 -2
- package/src/features/CommandMenu/useCommandMenu.ts +3 -2
- package/src/features/Conversation/Markdown/plugins/LobeArtifact/Render/index.tsx +3 -2
- package/src/features/Conversation/Messages/components/FileChunks/ChunkItem.tsx +3 -2
- package/src/features/Conversation/Messages/components/FileChunks/index.tsx +4 -2
- package/src/features/Conversation/Messages/components/SearchGrounding.tsx +3 -2
- package/src/features/ElectronTitlebar/hooks/useWatchThemeUpdate.ts +21 -38
- package/src/features/GroupChatSettings/AgentCard.tsx +3 -2
- package/src/features/GroupChatSettings/HostMemberCard.tsx +3 -2
- package/src/features/PageEditor/DiffAllToolbar.tsx +4 -2
- package/src/features/Portal/Document/Header.tsx +11 -9
- package/src/features/User/UserPanel/ThemeButton.tsx +18 -29
- package/src/hooks/useIsDark.ts +11 -0
- package/src/layout/AuthProvider/Clerk/useAppearance.ts +4 -2
- package/src/layout/AuthProvider/MarketAuth/MarketAuthConfirmModal.tsx +3 -2
- package/src/layout/GlobalProvider/AppTheme.tsx +15 -19
- package/src/layout/GlobalProvider/NextThemeProvider.tsx +22 -0
- package/src/layout/GlobalProvider/StyleRegistry.tsx +18 -13
- package/src/layout/GlobalProvider/index.tsx +38 -36
- package/src/libs/next/proxy/define-config.ts +2 -11
- package/src/store/global/action.test.ts +0 -15
- package/src/store/global/actions/__tests__/general.test.ts +0 -37
- package/src/store/global/actions/general.ts +0 -21
- package/src/store/global/initialState.ts +0 -6
- package/src/store/global/selectors/systemStatus.test.ts +0 -20
- package/src/store/global/selectors/systemStatus.ts +0 -2
- package/src/styles/global.ts +0 -2
- package/src/utils/server/routeVariants.test.ts +17 -51
- package/src/utils/server/routeVariants.ts +0 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Center, Flexbox, Icon } from '@lobehub/ui';
|
|
2
|
-
import { createStaticStyles,
|
|
2
|
+
import { createStaticStyles, responsive } from 'antd-style';
|
|
3
3
|
import { type LucideIcon } from 'lucide-react';
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
|
|
6
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
7
|
+
|
|
6
8
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
7
9
|
desc: css`
|
|
8
10
|
width: 280px;
|
|
@@ -48,7 +50,7 @@ interface FeatureListProps {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
const FeatureList = memo<FeatureListProps>(({ data }) => {
|
|
51
|
-
const
|
|
53
|
+
const isDarkMode = useIsDark();
|
|
52
54
|
|
|
53
55
|
return (
|
|
54
56
|
<Flexbox gap={32}>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Flexbox, Icon, Tag, Tooltip } from '@lobehub/ui';
|
|
2
|
-
import { createStaticStyles, cx
|
|
2
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
3
3
|
import { BoltIcon, RotateCwIcon } from 'lucide-react';
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
|
|
7
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
7
8
|
import { AsyncTaskStatus, type FileParsingTask } from '@/types/asyncTask';
|
|
8
9
|
|
|
9
10
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
@@ -36,7 +37,7 @@ interface EmbeddingStatusProps extends FileParsingTask {
|
|
|
36
37
|
const EmbeddingStatus = memo<EmbeddingStatusProps>(
|
|
37
38
|
({ chunkCount, embeddingStatus, embeddingError, onClick, onErrorClick, className }) => {
|
|
38
39
|
const { t } = useTranslation(['components', 'common']);
|
|
39
|
-
const
|
|
40
|
+
const isDarkMode = useIsDark();
|
|
40
41
|
|
|
41
42
|
switch (embeddingStatus) {
|
|
42
43
|
case AsyncTaskStatus.Processing: {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Button, Flexbox, Icon, Tag, Tooltip } from '@lobehub/ui';
|
|
2
2
|
import { Badge } from 'antd';
|
|
3
|
-
import { createStaticStyles, cssVar, cx
|
|
3
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
4
4
|
import { BoltIcon, Loader2Icon, RotateCwIcon } from 'lucide-react';
|
|
5
5
|
import { memo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
|
8
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
8
9
|
import { AsyncTaskStatus, type FileParsingTask } from '@/types/asyncTask';
|
|
9
10
|
|
|
10
11
|
import EmbeddingStatus from './EmbeddingStatus';
|
|
@@ -52,7 +53,7 @@ const FileParsingStatus = memo<FileParsingStatusProps>(
|
|
|
52
53
|
hideEmbeddingButton,
|
|
53
54
|
}) => {
|
|
54
55
|
const { t } = useTranslation(['components', 'common']);
|
|
55
|
-
const
|
|
56
|
+
const isDarkMode = useIsDark();
|
|
56
57
|
|
|
57
58
|
switch (chunkingStatus) {
|
|
58
59
|
case AsyncTaskStatus.Processing: {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ActionIcon, Flexbox, type FlexboxProps } from '@lobehub/ui';
|
|
4
|
-
import { createStaticStyles, cssVar, cx
|
|
4
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
5
5
|
import { XIcon } from 'lucide-react';
|
|
6
6
|
import { memo } from 'react';
|
|
7
7
|
|
|
8
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
9
|
+
|
|
8
10
|
const styles = createStaticStyles(({ css }) => ({
|
|
9
11
|
cancelIcon: css`
|
|
10
12
|
position: absolute;
|
|
@@ -70,7 +72,7 @@ const Notification = memo<NotificationProps>(
|
|
|
70
72
|
className,
|
|
71
73
|
...rest
|
|
72
74
|
}) => {
|
|
73
|
-
const
|
|
75
|
+
const isDarkMode = useIsDark();
|
|
74
76
|
const { className: wrapperClassName, ...restWrapper } = wrapper;
|
|
75
77
|
return (
|
|
76
78
|
show && (
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type FC, type PropsWithChildren, useEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
const ClientOnly: FC<PropsWithChildren> = ({ children }) => {
|
|
6
|
+
const [mounted, setMounted] = useState(false);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
setMounted(true);
|
|
10
|
+
}, []);
|
|
11
|
+
|
|
12
|
+
if (!mounted) return null;
|
|
13
|
+
|
|
14
|
+
return children;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default ClientOnly;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { LOBE_CHAT_CLOUD, UTM_SOURCE } from '@lobechat/business-const';
|
|
4
|
-
import { Button, Center, Flexbox, Icon
|
|
4
|
+
import { Button, Center, Flexbox, Icon, lobeStaticStylish } from '@lobehub/ui';
|
|
5
5
|
import { useSize } from 'ahooks';
|
|
6
|
-
import { createStaticStyles, cx
|
|
6
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
7
7
|
import { ArrowRightIcon } from 'lucide-react';
|
|
8
8
|
import Link from 'next/link';
|
|
9
9
|
import { memo, useEffect, useRef, useState } from 'react';
|
|
@@ -11,6 +11,7 @@ import Marquee from 'react-fast-marquee';
|
|
|
11
11
|
import { useTranslation } from 'react-i18next';
|
|
12
12
|
|
|
13
13
|
import { OFFICIAL_URL } from '@/const/url';
|
|
14
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
14
15
|
import { isOnServerSide } from '@/utils/env';
|
|
15
16
|
|
|
16
17
|
export const BANNER_HEIGHT = 40;
|
|
@@ -50,7 +51,7 @@ const CloudBanner = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
50
51
|
const contentRef = useRef(null);
|
|
51
52
|
const size = useSize(ref);
|
|
52
53
|
const contentSize = useSize(contentRef);
|
|
53
|
-
const
|
|
54
|
+
const isDarkMode = useIsDark();
|
|
54
55
|
const { t } = useTranslation('common');
|
|
55
56
|
const [isTruncated, setIsTruncated] = useState(mobile);
|
|
56
57
|
|
|
@@ -24,7 +24,7 @@ const ThemeMenu = memo(() => {
|
|
|
24
24
|
<div className={styles.itemLabel}>{t('cmdk.themeDark')}</div>
|
|
25
25
|
</div>
|
|
26
26
|
</Command.Item>
|
|
27
|
-
<Command.Item onSelect={() => handleThemeChange('
|
|
27
|
+
<Command.Item onSelect={() => handleThemeChange('system')} value="theme-system">
|
|
28
28
|
<Monitor className={styles.icon} />
|
|
29
29
|
<div className={styles.itemContent}>
|
|
30
30
|
<div className={styles.itemLabel}>{t('cmdk.themeAuto')}</div>
|
|
@@ -4,7 +4,7 @@ export interface ChatMessage {
|
|
|
4
4
|
role: 'user' | 'assistant';
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export type ThemeMode = 'light' | 'dark' | '
|
|
7
|
+
export type ThemeMode = 'light' | 'dark' | 'system';
|
|
8
8
|
|
|
9
9
|
export type PageType = 'theme' | 'ask-ai' | string;
|
|
10
10
|
|
|
@@ -25,4 +25,7 @@ export type MenuContext =
|
|
|
25
25
|
| 'page'
|
|
26
26
|
| 'painting';
|
|
27
27
|
|
|
28
|
-
export type ContextType = Extract<
|
|
28
|
+
export type ContextType = Extract<
|
|
29
|
+
MenuContext,
|
|
30
|
+
'agent' | 'group' | 'resource' | 'settings' | 'page' | 'painting'
|
|
31
|
+
>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useDebounce } from 'ahooks';
|
|
2
|
+
import { useTheme as useNextThemesTheme } from 'next-themes';
|
|
2
3
|
import { useEffect, useMemo } from 'react';
|
|
3
4
|
import { useNavigate } from 'react-router-dom';
|
|
4
5
|
import useSWR from 'swr';
|
|
@@ -37,7 +38,7 @@ export const useCommandMenu = () => {
|
|
|
37
38
|
} = useCommandMenuContext();
|
|
38
39
|
|
|
39
40
|
const navigate = useNavigate();
|
|
40
|
-
const
|
|
41
|
+
const { setTheme } = useNextThemesTheme();
|
|
41
42
|
const createAgent = useAgentStore((s) => s.createAgent);
|
|
42
43
|
const refreshAgentList = useHomeStore((s) => s.refreshAgentList);
|
|
43
44
|
const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId);
|
|
@@ -106,7 +107,7 @@ export const useCommandMenu = () => {
|
|
|
106
107
|
};
|
|
107
108
|
|
|
108
109
|
const handleThemeChange = (theme: ThemeMode) => {
|
|
109
|
-
|
|
110
|
+
setTheme(theme);
|
|
110
111
|
closeCommandMenu();
|
|
111
112
|
};
|
|
112
113
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Center, Flexbox, Icon } from '@lobehub/ui';
|
|
2
|
-
import { createStaticStyles, cx
|
|
2
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
3
3
|
import { Loader2 } from 'lucide-react';
|
|
4
4
|
import { memo, useEffect } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
|
|
7
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
7
8
|
import { useChatStore } from '@/store/chat';
|
|
8
9
|
import { chatPortalSelectors, messageStateSelectors } from '@/store/chat/selectors';
|
|
9
10
|
import { dotLoading } from '@/styles/loading';
|
|
@@ -57,7 +58,7 @@ interface ArtifactProps extends MarkdownElementProps {
|
|
|
57
58
|
|
|
58
59
|
const Render = memo<ArtifactProps>(({ identifier, title, type, language, children, id }) => {
|
|
59
60
|
const { t } = useTranslation('chat');
|
|
60
|
-
const
|
|
61
|
+
const isDarkMode = useIsDark();
|
|
61
62
|
|
|
62
63
|
const hasChildren = !!children;
|
|
63
64
|
const str = ((children as string) || '').toString?.();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type ChatFileChunk } from '@lobechat/types';
|
|
2
2
|
import { Center, Flexbox, Text, Tooltip } from '@lobehub/ui';
|
|
3
|
-
import { cx
|
|
3
|
+
import { cx } from 'antd-style';
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
|
|
6
6
|
import FileIcon from '@/components/FileIcon';
|
|
7
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
7
8
|
import { useChatStore } from '@/store/chat';
|
|
8
9
|
|
|
9
10
|
import { styles } from './style';
|
|
@@ -13,7 +14,7 @@ export interface ChunkItemProps extends ChatFileChunk {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const ChunkItem = memo<ChunkItemProps>(({ id, fileId, similarity, text, filename, fileType }) => {
|
|
16
|
-
const
|
|
17
|
+
const isDarkMode = useIsDark();
|
|
17
18
|
// Note: openFilePreview is a portal action, kept in ChatStore as it's a global UI state
|
|
18
19
|
const openFilePreview = useChatStore((s) => s.openFilePreview);
|
|
19
20
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type ChatFileChunk } from '@lobechat/types';
|
|
2
2
|
import { Flexbox, Icon } from '@lobehub/ui';
|
|
3
|
-
import { createStaticStyles, cssVar, cx
|
|
3
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
4
4
|
import { BookOpenTextIcon, ChevronDown, ChevronRight } from 'lucide-react';
|
|
5
5
|
import { memo, useState } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
|
8
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
9
|
+
|
|
8
10
|
import ChunkItem from './ChunkItem';
|
|
9
11
|
|
|
10
12
|
const styles = createStaticStyles(({ css }) => ({
|
|
@@ -47,7 +49,7 @@ interface FileChunksProps {
|
|
|
47
49
|
|
|
48
50
|
const FileChunks = memo<FileChunksProps>(({ data }) => {
|
|
49
51
|
const { t } = useTranslation('chat');
|
|
50
|
-
const
|
|
52
|
+
const isDarkMode = useIsDark();
|
|
51
53
|
|
|
52
54
|
const [showDetail, setShowDetail] = useState(false);
|
|
53
55
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Flexbox, Icon, SearchResultCards, Tag } from '@lobehub/ui';
|
|
2
|
-
import { createStaticStyles, cssVar, cx
|
|
2
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
3
3
|
import { ChevronDown, ChevronRight, Globe } from 'lucide-react';
|
|
4
4
|
import { AnimatePresence, m as motion } from 'motion/react';
|
|
5
5
|
import Image from 'next/image';
|
|
6
6
|
import { memo, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
9
10
|
import { type GroundingSearch } from '@/types/search';
|
|
10
11
|
|
|
11
12
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
@@ -46,7 +47,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
46
47
|
|
|
47
48
|
const SearchGrounding = memo<GroundingSearch>(({ searchQueries, citations }) => {
|
|
48
49
|
const { t } = useTranslation('chat');
|
|
49
|
-
const
|
|
50
|
+
const isDarkMode = useIsDark();
|
|
50
51
|
|
|
51
52
|
const [showDetail, setShowDetail] = useState(false);
|
|
52
53
|
|
|
@@ -1,33 +1,15 @@
|
|
|
1
1
|
import { useWatchBroadcast } from '@lobechat/electron-client-ipc';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useTheme } from 'next-themes';
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
4
|
|
|
5
|
+
import { isDesktop } from '@/const/version';
|
|
5
6
|
import { useElectronStore } from '@/store/electron';
|
|
6
7
|
import { useGlobalStore } from '@/store/global';
|
|
7
|
-
import { systemStatusSelectors } from '@/store/global/selectors';
|
|
8
8
|
import { ensureElectronIpc } from '@/utils/electron/ipc';
|
|
9
9
|
|
|
10
|
-
const sidebarColors = {
|
|
11
|
-
dark: '#000',
|
|
12
|
-
light: '#f8f8f8',
|
|
13
|
-
};
|
|
14
10
|
export const useWatchThemeUpdate = () => {
|
|
15
|
-
const [
|
|
16
|
-
|
|
17
|
-
s.isAppStateInit,
|
|
18
|
-
s.appState.systemAppearance,
|
|
19
|
-
s.updateElectronAppState,
|
|
20
|
-
s.appState.isMac,
|
|
21
|
-
],
|
|
22
|
-
);
|
|
23
|
-
const [switchThemeMode, switchLocale] = useGlobalStore((s) => [
|
|
24
|
-
s.switchThemeMode,
|
|
25
|
-
s.switchLocale,
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
useWatchBroadcast('themeChanged', ({ themeMode }) => {
|
|
29
|
-
switchThemeMode(themeMode, { skipBroadcast: true });
|
|
30
|
-
});
|
|
11
|
+
const [updateElectronAppState] = useElectronStore((s) => [s.updateElectronAppState]);
|
|
12
|
+
const [switchLocale] = useGlobalStore((s) => [s.switchLocale]);
|
|
31
13
|
|
|
32
14
|
useWatchBroadcast('localeChanged', ({ locale }) => {
|
|
33
15
|
switchLocale(locale as any, { skipBroadcast: true });
|
|
@@ -36,20 +18,21 @@ export const useWatchThemeUpdate = () => {
|
|
|
36
18
|
useWatchBroadcast('systemThemeChanged', ({ themeMode }) => {
|
|
37
19
|
updateElectronAppState({ systemAppearance: themeMode });
|
|
38
20
|
});
|
|
39
|
-
const themeMode = useGlobalStore(systemStatusSelectors.themeMode);
|
|
40
|
-
useLayoutEffect(() => {
|
|
41
|
-
ensureElectronIpc().system.setSystemThemeMode(themeMode);
|
|
42
|
-
}, []);
|
|
43
|
-
|
|
44
|
-
useLayoutEffect(() => {
|
|
45
|
-
if (!isAppStateInit || !isMac) return;
|
|
46
|
-
document.documentElement.style.background = 'none';
|
|
47
|
-
|
|
48
|
-
const lobeApp = document.querySelector('#' + LOBE_THEME_APP_ID);
|
|
49
|
-
if (!lobeApp) return;
|
|
50
21
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
22
|
+
const { theme } = useTheme();
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!isDesktop) return;
|
|
26
|
+
if (!theme) return;
|
|
27
|
+
|
|
28
|
+
(async () => {
|
|
29
|
+
try {
|
|
30
|
+
await ensureElectronIpc().system.updateThemeModeHandler(
|
|
31
|
+
theme as 'dark' | 'light' | 'system',
|
|
32
|
+
);
|
|
33
|
+
} catch {
|
|
34
|
+
// Ignore errors in non-electron environment
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
}, [theme]);
|
|
55
38
|
};
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { Avatar, Flexbox, Icon, Skeleton, Text, Tooltip } from '@lobehub/ui';
|
|
4
4
|
import { Switch } from 'antd';
|
|
5
|
-
import { createStaticStyles, cssVar, cx
|
|
5
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
6
|
import { Bot, Loader2 } from 'lucide-react';
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
10
10
|
import { DEFAULT_AVATAR } from '@/const/meta';
|
|
11
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
11
12
|
import { type LobeAgentSession } from '@/types/session';
|
|
12
13
|
|
|
13
14
|
const styles = createStaticStyles(({ css }) => ({
|
|
@@ -59,7 +60,7 @@ interface AgentCardProps {
|
|
|
59
60
|
const AgentCard = memo<AgentCardProps>(
|
|
60
61
|
({ agent, inGroup, isHost, loading, onAction, operationLoading }) => {
|
|
61
62
|
const { t } = useTranslation('setting');
|
|
62
|
-
const
|
|
63
|
+
const isDarkMode = useIsDark();
|
|
63
64
|
|
|
64
65
|
if (loading) {
|
|
65
66
|
return (
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { Avatar, Flexbox, Icon, Text, Tooltip } from '@lobehub/ui';
|
|
4
4
|
import { Switch } from 'antd';
|
|
5
|
-
import { createStaticStyles, cssVar, cx
|
|
5
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
6
|
import { Bot, Loader2 } from 'lucide-react';
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
10
10
|
import { DEFAULT_SUPERVISOR_AVATAR } from '@/const/meta';
|
|
11
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
11
12
|
|
|
12
13
|
const styles = createStaticStyles(({ css }) => ({
|
|
13
14
|
container: css`
|
|
@@ -53,7 +54,7 @@ interface HostMemberCardProps {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
const HostMemberCard = memo<HostMemberCardProps>(({ checked, loading, onToggle }) => {
|
|
56
|
-
const
|
|
57
|
+
const isDarkMode = useIsDark();
|
|
57
58
|
const { t } = useTranslation('setting');
|
|
58
59
|
|
|
59
60
|
const title = t('settingGroupMembers.host.title');
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
import { DiffAction, LITEXML_DIFFNODE_ALL_COMMAND } from '@lobehub/editor';
|
|
4
4
|
import { Block, Icon } from '@lobehub/ui';
|
|
5
5
|
import { Button, Space } from 'antd';
|
|
6
|
-
import { createStaticStyles, cssVar, cx
|
|
6
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
7
7
|
import { Check, X } from 'lucide-react';
|
|
8
8
|
import { memo, useEffect, useState } from 'react';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
10
10
|
|
|
11
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
12
|
+
|
|
11
13
|
import { usePageEditorStore } from './store';
|
|
12
14
|
|
|
13
15
|
const styles = createStaticStyles(({ css }) => ({
|
|
@@ -36,7 +38,7 @@ const styles = createStaticStyles(({ css }) => ({
|
|
|
36
38
|
|
|
37
39
|
const DiffAllToolbar = memo(() => {
|
|
38
40
|
const { t } = useTranslation('editor');
|
|
39
|
-
const
|
|
41
|
+
const isDarkMode = useIsDark();
|
|
40
42
|
const [editor, performSave] = usePageEditorStore((s) => [s.editor, s.performSave]);
|
|
41
43
|
const [hasPendingDiffs, setHasPendingDiffs] = useState(false);
|
|
42
44
|
|
|
@@ -61,15 +61,17 @@ const Header = () => {
|
|
|
61
61
|
</Flexbox>
|
|
62
62
|
<Flexbox align={'center'} gap={8} horizontal>
|
|
63
63
|
<AutoSaveHint />
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
{document.fileType !== 'agent/plan' && (
|
|
65
|
+
<Button
|
|
66
|
+
icon={<ExternalLink size={14} />}
|
|
67
|
+
loading={loading}
|
|
68
|
+
onClick={handleOpenInPageEditor}
|
|
69
|
+
size={'small'}
|
|
70
|
+
type={'text'}
|
|
71
|
+
>
|
|
72
|
+
{t('openInPageEditor')}
|
|
73
|
+
</Button>
|
|
74
|
+
)}
|
|
73
75
|
</Flexbox>
|
|
74
76
|
</Flexbox>
|
|
75
77
|
);
|
|
@@ -1,65 +1,54 @@
|
|
|
1
|
-
import { ActionIcon,
|
|
1
|
+
import { ActionIcon, DropdownMenu, type DropdownMenuProps, Icon } from '@lobehub/ui';
|
|
2
2
|
import { Monitor, Moon, Sun } from 'lucide-react';
|
|
3
|
+
import { useTheme as useNextThemesTheme } from 'next-themes';
|
|
3
4
|
import { FC, useMemo } from 'react';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
5
6
|
|
|
6
|
-
import { type MenuProps } from '@/components/Menu';
|
|
7
|
-
import { useGlobalStore } from '@/store/global';
|
|
8
|
-
import { systemStatusSelectors } from '@/store/global/selectors';
|
|
9
|
-
|
|
10
7
|
const themeIcons = {
|
|
11
|
-
auto: Monitor,
|
|
12
8
|
dark: Moon,
|
|
13
9
|
light: Sun,
|
|
10
|
+
system: Monitor,
|
|
14
11
|
};
|
|
15
12
|
|
|
16
|
-
const ThemeButton: FC<{ placement?:
|
|
13
|
+
const ThemeButton: FC<{ placement?: DropdownMenuProps['placement']; size?: number }> = ({
|
|
17
14
|
placement,
|
|
18
15
|
size,
|
|
19
16
|
}) => {
|
|
20
|
-
const
|
|
21
|
-
systemStatusSelectors.themeMode(s),
|
|
22
|
-
s.switchThemeMode,
|
|
23
|
-
]);
|
|
17
|
+
const { setTheme, theme } = useNextThemesTheme();
|
|
24
18
|
|
|
25
19
|
const { t } = useTranslation('setting');
|
|
26
20
|
|
|
27
|
-
const items
|
|
21
|
+
const items = useMemo<DropdownMenuProps['items']>(
|
|
28
22
|
() => [
|
|
29
23
|
{
|
|
30
|
-
icon: <Icon icon={themeIcons.
|
|
31
|
-
key: '
|
|
24
|
+
icon: <Icon icon={themeIcons.system} />,
|
|
25
|
+
key: 'system',
|
|
32
26
|
label: t('settingCommon.themeMode.auto'),
|
|
33
|
-
onClick: () =>
|
|
27
|
+
onClick: () => setTheme('system'),
|
|
34
28
|
},
|
|
35
29
|
{
|
|
36
30
|
icon: <Icon icon={themeIcons.light} />,
|
|
37
31
|
key: 'light',
|
|
38
32
|
label: t('settingCommon.themeMode.light'),
|
|
39
|
-
onClick: () =>
|
|
33
|
+
onClick: () => setTheme('light'),
|
|
40
34
|
},
|
|
41
35
|
{
|
|
42
36
|
icon: <Icon icon={themeIcons.dark} />,
|
|
43
37
|
key: 'dark',
|
|
44
38
|
label: t('settingCommon.themeMode.dark'),
|
|
45
|
-
onClick: () =>
|
|
39
|
+
onClick: () => setTheme('dark'),
|
|
46
40
|
},
|
|
47
41
|
],
|
|
48
|
-
[t],
|
|
42
|
+
[setTheme, t],
|
|
49
43
|
);
|
|
50
44
|
|
|
51
45
|
return (
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}}
|
|
59
|
-
placement={placement}
|
|
60
|
-
>
|
|
61
|
-
<ActionIcon icon={themeIcons[themeMode]} size={size || { blockSize: 32, size: 16 }} />
|
|
62
|
-
</Dropdown>
|
|
46
|
+
<DropdownMenu items={items} placement={placement}>
|
|
47
|
+
<ActionIcon
|
|
48
|
+
icon={themeIcons[(theme as 'dark' | 'light' | 'system') || 'system']}
|
|
49
|
+
size={size || { blockSize: 32, size: 16 }}
|
|
50
|
+
/>
|
|
51
|
+
</DropdownMenu>
|
|
63
52
|
);
|
|
64
53
|
};
|
|
65
54
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useTheme as useNextThemesTheme } from 'next-themes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook to check if the current theme is dark
|
|
5
|
+
* @returns boolean - true if current theme is dark, false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export const useIsDark = (): boolean => {
|
|
8
|
+
const { resolvedTheme } = useNextThemesTheme();
|
|
9
|
+
|
|
10
|
+
return resolvedTheme === 'dark';
|
|
11
|
+
};
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import { dark } from '@clerk/themes';
|
|
4
4
|
import { type ElementsConfig, type Theme } from '@clerk/types';
|
|
5
5
|
import { BRANDING_URL } from '@lobechat/business-const';
|
|
6
|
-
import { createStaticStyles, cssVar, cx
|
|
6
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
7
|
+
|
|
8
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
7
9
|
|
|
8
10
|
const prefixCls = 'cl';
|
|
9
11
|
|
|
@@ -95,7 +97,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
95
97
|
})) as Partial<Record<keyof ElementsConfig, any>>;
|
|
96
98
|
|
|
97
99
|
export const useAppearance = () => {
|
|
98
|
-
const
|
|
100
|
+
const isDarkMode = useIsDark();
|
|
99
101
|
|
|
100
102
|
const navbarStyle = cx(styles.navbar, isDarkMode && (styles as any).navbar_dark);
|
|
101
103
|
const scrollBoxStyle = cx(styles.scrollBox, isDarkMode && (styles as any).scrollBox_dark);
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { BRANDING_NAME } from '@lobechat/business-const';
|
|
4
4
|
import { Block, Modal, Text } from '@lobehub/ui';
|
|
5
|
-
import { createStaticStyles, cx
|
|
5
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
6
6
|
import { memo } from 'react';
|
|
7
7
|
import { Trans, useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
9
|
import { PRIVACY_URL, TERMS_URL } from '@/const/url';
|
|
10
10
|
import AuthCard from '@/features/AuthCard';
|
|
11
|
+
import { useIsDark } from '@/hooks/useIsDark';
|
|
11
12
|
|
|
12
13
|
const styles = createStaticStyles(({ css }) => ({
|
|
13
14
|
container: css`
|
|
@@ -34,7 +35,7 @@ interface MarketAuthConfirmModalProps {
|
|
|
34
35
|
const MarketAuthConfirmModal = memo<MarketAuthConfirmModalProps>(
|
|
35
36
|
({ open, onConfirm, onCancel }) => {
|
|
36
37
|
const { t } = useTranslation('marketAuth');
|
|
37
|
-
const
|
|
38
|
+
const isDarkMode = useIsDark();
|
|
38
39
|
|
|
39
40
|
const footer = (
|
|
40
41
|
<Text align={'center'} as={'div'} fontSize={13} type={'secondary'}>
|