200 lines
7.7 KiB
TypeScript
200 lines
7.7 KiB
TypeScript
import React from 'react';
|
|
import { useAppStore } from '../../store';
|
|
import { useI18n } from '../../i18n';
|
|
import './ActivityBar.css';
|
|
|
|
// Simple SVG icons
|
|
const PostsIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"/>
|
|
<path d="M8 12h8v2H8zm0 4h8v2H8z"/>
|
|
</svg>
|
|
);
|
|
|
|
const PagesIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M4 4h10v4h6v12H4V4zm10 1.5V9h4.5L14 5.5zM7 12h10v1.5H7V12zm0 3h10v1.5H7V15z"/>
|
|
</svg>
|
|
);
|
|
|
|
const MediaIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
|
|
</svg>
|
|
);
|
|
|
|
const SettingsIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>
|
|
</svg>
|
|
);
|
|
|
|
const TagsIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58s1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41s-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>
|
|
</svg>
|
|
);
|
|
|
|
const ChatIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
|
|
<circle cx="8" cy="10" r="1.5"/>
|
|
<circle cx="12" cy="10" r="1.5"/>
|
|
<circle cx="16" cy="10" r="1.5"/>
|
|
</svg>
|
|
);
|
|
|
|
const ImportIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
|
|
</svg>
|
|
);
|
|
|
|
const GitIcon = () => (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M22 11.73L12.27 2a1 1 0 0 0-1.41 0L8.84 4.02l2.56 2.56a1.2 1.2 0 0 1 1.52 1.53l2.47 2.47a1.2 1.2 0 1 1-.72.67l-2.3-2.3v6.06a1.2 1.2 0 1 1-.85 0V8.9a1.2 1.2 0 0 1-.66-1.59L8.35 4.8 2 11.16a1 1 0 0 0 0 1.41L11.73 22a1 1 0 0 0 1.41 0L22 13.14a1 1 0 0 0 0-1.41z"/>
|
|
</svg>
|
|
);
|
|
|
|
export const ActivityBar: React.FC = () => {
|
|
const { t } = useI18n();
|
|
const { activeView, setActiveView, sidebarVisible, toggleSidebar, openTab, tabs, activeTabId } = useAppStore();
|
|
|
|
// Check if settings tab is currently active
|
|
const isSettingsTabActive = tabs.some(t => t.type === 'settings' && t.id === activeTabId);
|
|
|
|
// Check if settings view is active (either tab or sidebar)
|
|
const isSettingsActive = (activeView === 'settings' && sidebarVisible) || isSettingsTabActive;
|
|
|
|
// Check if tags sidebar is active
|
|
const isTagsActive = activeView === 'tags' && sidebarVisible;
|
|
|
|
// Check if chat sidebar is active (activeView === 'chat' and sidebar is visible)
|
|
const isChatActive = activeView === 'chat' && sidebarVisible;
|
|
|
|
// Check if import sidebar is active
|
|
const isImportActive = activeView === 'import' && sidebarVisible;
|
|
const isGitActive = activeView === 'git' && sidebarVisible;
|
|
|
|
// Handle view click - toggle sidebar if clicking on active view, otherwise switch view
|
|
const handleViewClick = (view: 'posts' | 'pages' | 'media' | 'chat' | 'git') => {
|
|
if (activeView === view && sidebarVisible) {
|
|
// Clicking on active view toggles sidebar off
|
|
toggleSidebar();
|
|
} else if (activeView === view && !sidebarVisible) {
|
|
// Clicking on active view when hidden shows it
|
|
toggleSidebar();
|
|
} else {
|
|
// Switching to a different view - ensure sidebar is visible
|
|
if (!sidebarVisible) {
|
|
toggleSidebar();
|
|
}
|
|
setActiveView(view);
|
|
}
|
|
};
|
|
|
|
const handleSettingsClick = () => {
|
|
// Toggle sidebar if settings is already active, otherwise switch to settings
|
|
if (activeView === 'settings' && sidebarVisible) {
|
|
toggleSidebar();
|
|
} else {
|
|
// Open settings tab and show settings sidebar
|
|
openTab({ type: 'settings', id: 'settings', isTransient: false });
|
|
setActiveView('settings');
|
|
if (!sidebarVisible) {
|
|
toggleSidebar();
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleTagsClick = () => {
|
|
// Toggle sidebar if tags is already active, otherwise switch to tags
|
|
if (activeView === 'tags' && sidebarVisible) {
|
|
toggleSidebar();
|
|
} else {
|
|
openTab({ type: 'tags', id: 'tags', isTransient: false });
|
|
setActiveView('tags');
|
|
if (!sidebarVisible) {
|
|
toggleSidebar();
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleImportClick = () => {
|
|
if (activeView === 'import' && sidebarVisible) {
|
|
toggleSidebar();
|
|
} else {
|
|
setActiveView('import');
|
|
if (!sidebarVisible) {
|
|
toggleSidebar();
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="activity-bar">
|
|
<div className="activity-bar-top">
|
|
<button
|
|
className={`activity-bar-item ${activeView === 'posts' && sidebarVisible ? 'active' : ''}`}
|
|
onClick={() => handleViewClick('posts')}
|
|
title={`${t('activity.posts')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<PostsIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${activeView === 'pages' && sidebarVisible ? 'active' : ''}`}
|
|
onClick={() => handleViewClick('pages')}
|
|
title={`${t('activity.pages')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<PagesIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${activeView === 'media' && sidebarVisible ? 'active' : ''}`}
|
|
onClick={() => handleViewClick('media')}
|
|
title={`${t('activity.media')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<MediaIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${isTagsActive ? 'active' : ''}`}
|
|
onClick={handleTagsClick}
|
|
title={`${t('activity.tags')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<TagsIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${isChatActive ? 'active' : ''}`}
|
|
onClick={() => handleViewClick('chat')}
|
|
title={`${t('activity.aiAssistant')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<ChatIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${isImportActive ? 'active' : ''}`}
|
|
onClick={handleImportClick}
|
|
title={`${t('activity.import')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<ImportIcon />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="activity-bar-bottom">
|
|
<button
|
|
className={`activity-bar-item ${isGitActive ? 'active' : ''}`}
|
|
onClick={() => handleViewClick('git')}
|
|
title={`${t('activity.sourceControl')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<GitIcon />
|
|
</button>
|
|
<button
|
|
className={`activity-bar-item ${isSettingsActive ? 'active' : ''}`}
|
|
onClick={handleSettingsClick}
|
|
title={`${t('common.settings')} ${t('activity.toggleHint')}`}
|
|
>
|
|
<SettingsIcon />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|