Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 3 additions & 47 deletions src/web-ui/src/app/components/AboutDialog/AboutDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,6 @@
text-align: center;
position: relative;
overflow: hidden;

// Background glow effect
&::before {
content: '';
position: absolute;
top: -60%;
left: 50%;
transform: translateX(-50%);
width: 300px;
height: 200px;
background: radial-gradient(ellipse, rgba(139, 92, 246, 0.1) 0%, transparent 70%);
filter: blur(40px);
pointer-events: none;
animation: about-glow-float 12s ease-in-out infinite;
}

&::after {
content: '';
position: absolute;
top: 20%;
right: 5%;
width: 100px;
height: 100px;
background: radial-gradient(circle, rgba(59, 130, 246, 0.06) 0%, transparent 70%);
filter: blur(25px);
pointer-events: none;
animation: about-glow-float 10s ease-in-out infinite reverse;
}
}

@keyframes about-glow-float {
0%, 100% { transform: translateX(-50%) translate(0, 0) scale(1); }
33% { transform: translateX(-50%) translate(15px, -10px) scale(1.03); }
66% { transform: translateX(-50%) translate(-10px, 8px) scale(0.98); }
}

.bitfun-about-dialog__title {
Expand All @@ -69,7 +35,6 @@
margin: 0 0 10px 0;
letter-spacing: -0.03em;
color: var(--color-text-primary);
text-shadow: 0 0 40px rgba(100, 180, 255, 0.2);
position: relative;
z-index: 1;
animation: about-title-enter 0.5s ease-out 0.1s both;
Expand Down Expand Up @@ -115,7 +80,7 @@
.bitfun-about-dialog__divider {
width: 60px;
height: 1px;
background: linear-gradient(90deg, transparent 0%, rgba(139, 92, 246, 0.25) 50%, transparent 100%);
background: var(--border-subtle);
margin-top: 18px;
position: relative;
z-index: 1;
Expand Down Expand Up @@ -145,13 +110,9 @@
span {
width: 3px;
height: 3px;
background: linear-gradient(135deg, #8B5CF6, #3B82F6);
background: var(--color-text-muted);
border-radius: 50%;
opacity: 0.35;
animation: about-dot-pulse 2.5s ease-in-out infinite;

&:nth-child(2) { animation-delay: 0.25s; }
&:nth-child(3) { animation-delay: 0.5s; }
opacity: 0.45;
}
}

Expand All @@ -160,11 +121,6 @@
to { opacity: 1; }
}

@keyframes about-dot-pulse {
0%, 100% { opacity: 0.25; transform: scale(1); }
50% { opacity: 0.6; transform: scale(1.3); }
}

// ==================== Scrollable area ====================

.bitfun-about-dialog__scrollable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

// Small decorative gradient behind icon
&__icon {
--gallery-detail-gradient: linear-gradient(135deg, rgba(59,130,246,0.28) 0%, rgba(139,92,246,0.18) 100%);

width: 56px;
height: 56px;
border-radius: $size-radius-lg;
Expand All @@ -25,25 +23,9 @@
justify-content: center;
flex-shrink: 0;
color: var(--color-text-primary);
background: var(--gallery-detail-gradient);
border: 1px solid rgba(255, 255, 255, 0.1);
background: var(--element-bg-soft);
border: 1px solid var(--border-subtle);
position: relative;

// Blurred glow behind icon
&::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80px;
height: 80px;
border-radius: 50%;
background: var(--gallery-detail-gradient);
filter: blur(20px);
z-index: -1;
opacity: 0.6;
}
}

&__summary {
Expand Down
36 changes: 3 additions & 33 deletions src/web-ui/src/app/components/NavPanel/MainNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,12 @@ import { useMiniAppCatalogSync } from '../../scenes/miniapps/hooks/useMiniAppCat
import { flowChatStore } from '@/flow_chat/store/FlowChatStore';
import { compareSessionsForDisplay } from '@/flow_chat/utils/sessionOrdering';
import { flowChatManager } from '@/flow_chat/services/FlowChatManager';
import { configManager } from '@/infrastructure/config/services/ConfigManager';
import { workspaceManager } from '@/infrastructure/services/business/workspaceManager';
import { useWorkspaceContext } from '@/infrastructure/contexts/WorkspaceContext';
import { createLogger } from '@/shared/utils/logger';
import { WorkspaceKind } from '@/shared/types';
import { useSSHRemoteContext, SSHConnectionDialog, RemoteFileBrowser } from '@/features/ssh-remote';

const DEFAULT_MODE_CONFIG_KEY = 'app.session_config.default_mode';
const NAV_DISPLAY_MODE_STORAGE_KEY = 'bitfun.nav.displayMode';
import './NavPanel.scss';

Expand Down Expand Up @@ -272,7 +270,6 @@ const MainNav: React.FC<MainNavProps> = ({
return workspaceSessions[0]?.sessionId;
}, [resolvedAssistantWorkspace]);

const [defaultSessionMode, setDefaultSessionMode] = useState<'code' | 'cowork'>('code');
const [navDisplayMode, setNavDisplayMode] = useState<NavDisplayMode>(getInitialNavDisplayMode);
const [isModeSwitching, setIsModeSwitching] = useState(false);
const [modeLogoSrc, setModeLogoSrc] = useState('/panda_1.png');
Expand All @@ -281,25 +278,6 @@ const MainNav: React.FC<MainNavProps> = ({
const modeSwitchTimerRef = useRef<number | null>(null);
const modeSwitchSwapTimerRef = useRef<number | null>(null);

useEffect(() => {
configManager.getConfig<'code' | 'cowork'>(DEFAULT_MODE_CONFIG_KEY).then(mode => {
if (mode === 'code' || mode === 'cowork') {
setDefaultSessionMode(mode);
setSessionMode(mode);
}
}).catch(() => {});

const unwatch = configManager.watch(DEFAULT_MODE_CONFIG_KEY, () => {
configManager.getConfig<'code' | 'cowork'>(DEFAULT_MODE_CONFIG_KEY).then(mode => {
if (mode === 'code' || mode === 'cowork') {
setDefaultSessionMode(mode);
setSessionMode(mode);
}
}).catch(() => {});
});
return () => unwatch();
}, [setSessionMode]);

useEffect(() => () => {
if (modeSwitchTimerRef.current !== null) {
window.clearTimeout(modeSwitchTimerRef.current);
Expand Down Expand Up @@ -346,18 +324,12 @@ const MainNav: React.FC<MainNavProps> = ({
try {
await flowChatManager.createChatSession(
{},
mode ?? (
isAssistantWorkspaceActive
? 'Claw'
: defaultSessionMode === 'cowork'
? 'Cowork'
: 'agentic'
)
mode ?? (isAssistantWorkspaceActive ? 'Claw' : 'agentic')
);
} catch (err) {
log.error('Failed to create session', err);
}
}, [openScene, switchLeftPanelTab, defaultSessionMode, isAssistantWorkspaceActive]);
}, [openScene, switchLeftPanelTab, isAssistantWorkspaceActive]);

const handleCreateCodeSession = useCallback(() => {
setSessionMode('code');
Expand Down Expand Up @@ -897,9 +869,7 @@ const MainNav: React.FC<MainNavProps> = ({
tab === 'sessions'
? isAssistantWorkspaceActive
? t('nav.sessions.newClawSession')
: defaultSessionMode === 'cowork'
? t('nav.sessions.newCoworkSession')
: t('nav.sessions.newCodeSession')
: t('nav.sessions.newCodeSession')
: undefined
}
onActionClick={tab === 'sessions' ? handleCreateSession : undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,6 @@
text-align: center;
position: relative;
overflow: hidden;

// Background glow effect
&::before {
content: '';
position: absolute;
top: -80%;
left: 50%;
transform: translateX(-50%);
width: 250px;
height: 150px;
background: radial-gradient(ellipse, rgba(34, 197, 94, 0.08) 0%, transparent 70%);
filter: blur(30px);
pointer-events: none;
animation: new-project-glow 10s ease-in-out infinite;
}
}

@keyframes new-project-glow {
0%, 100% { transform: translateX(-50%) scale(1); opacity: 0.8; }
50% { transform: translateX(-50%) scale(1.1); opacity: 1; }
}

&__icon-wrapper {
Expand Down
21 changes: 2 additions & 19 deletions src/web-ui/src/app/components/SceneBar/SceneBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@
* AI Agent tab shows the current session title as a subtitle.
*/

import React, { useCallback, useRef, useState, useEffect } from 'react';
import React, { useCallback, useRef } from 'react';
import SceneTab from './SceneTab';
import { WindowControls } from '@/component-library';
import { useSceneManager } from '../../hooks/useSceneManager';
import { useCurrentSessionTitle } from '../../hooks/useCurrentSessionTitle';
import { useCurrentSettingsTabTitle } from '../../hooks/useCurrentSettingsTabTitle';
import { useI18n } from '@/infrastructure/i18n/hooks/useI18n';
import { flowChatManager } from '@/flow_chat/services/FlowChatManager';
import { configManager } from '@/infrastructure/config/services/ConfigManager';
import { createLogger } from '@/shared/utils/logger';
import './SceneBar.scss';

const DEFAULT_MODE_CONFIG_KEY = 'app.session_config.default_mode';

const log = createLogger('SceneBar');

const INTERACTIVE_SELECTOR =
Expand All @@ -43,20 +40,6 @@ const SceneBar: React.FC<SceneBarProps> = ({
const sessionTitle = useCurrentSessionTitle();
const settingsTabTitle = useCurrentSettingsTabTitle();
const { t } = useI18n('common');
const [defaultMode, setDefaultMode] = useState<'code' | 'cowork'>('code');

useEffect(() => {
configManager.getConfig<'code' | 'cowork'>(DEFAULT_MODE_CONFIG_KEY).then(mode => {
if (mode === 'code' || mode === 'cowork') setDefaultMode(mode);
}).catch(() => {});
const unwatch = configManager.watch(DEFAULT_MODE_CONFIG_KEY, () => {
configManager.getConfig<'code' | 'cowork'>(DEFAULT_MODE_CONFIG_KEY).then(mode => {
if (mode === 'code' || mode === 'cowork') setDefaultMode(mode);
}).catch(() => {});
});
return () => unwatch();
}, []);

const hasWindowControls = !!(onMinimize && onMaximize && onClose);
const sceneBarClassName = `bitfun-scene-bar ${!hasWindowControls ? 'bitfun-scene-bar--no-controls' : ''} ${className}`.trim();
const isSingleTab = openTabs.length <= 1;
Expand Down Expand Up @@ -122,7 +105,7 @@ const SceneBar: React.FC<SceneBarProps> = ({
const subtitle =
(tab.id === 'session' && sessionTitle ? sessionTitle : undefined)
?? (tab.id === 'settings' && settingsTabTitle ? settingsTabTitle : undefined);
const actionTitle = tab.id === 'session' ? (defaultMode === 'cowork' ? t('nav.sessions.newCoworkSession') : t('nav.sessions.newCodeSession')) : undefined;
const actionTitle = tab.id === 'session' ? t('nav.sessions.newCodeSession') : undefined;
return (
<SceneTab
key={tab.id}
Expand Down
16 changes: 1 addition & 15 deletions src/web-ui/src/app/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,18 @@ import { NewProjectDialog } from '../components/NewProjectDialog';
import { AboutDialog } from '../components/AboutDialog';
import { WorkspaceManager } from '../../tools/workspace';
import { workspaceAPI } from '@/infrastructure/api';
import { configManager } from '@/infrastructure/config/services/ConfigManager';
import { createLogger } from '@/shared/utils/logger';
import { useI18n } from '@/infrastructure/i18n';
import { WorkspaceKind } from '@/shared/types';
import { shortcutManager } from '@/infrastructure/services/ShortcutManager';
import './AppLayout.scss';

const log = createLogger('AppLayout');
const DEFAULT_MODE_CONFIG_KEY = 'app.session_config.default_mode';

interface AppLayoutProps {
className?: string;
}

type DefaultSessionMode = 'code' | 'cowork';

async function resolveDefaultSessionAgentType(): Promise<'agentic' | 'Cowork'> {
try {
const defaultMode = await configManager.getConfig<DefaultSessionMode>(DEFAULT_MODE_CONFIG_KEY);
return defaultMode === 'cowork' ? 'Cowork' : 'agentic';
} catch (error) {
log.warn('Failed to load default session mode, falling back to code', error);
return 'agentic';
}
}

const AppLayout: React.FC<AppLayoutProps> = ({ className = '' }) => {
const { t } = useI18n('components');
const { currentWorkspace, hasWorkspace, openWorkspace, recentWorkspaces, loading } = useWorkspaceContext();
Expand Down Expand Up @@ -201,7 +187,7 @@ const AppLayout: React.FC<AppLayoutProps> = ({ className = '' }) => {
const initialSessionMode =
currentWorkspace.workspaceKind === WorkspaceKind.Assistant
? 'Claw'
: explicitPreferredMode || await resolveDefaultSessionAgentType();
: explicitPreferredMode || 'agentic';
sessionId = await flowChatManager.createChatSession({}, initialSessionMode);
}

Expand Down
Loading
Loading