Files
bDS/src/renderer/components/ActivityBar/ActivityBar.tsx

142 lines
5.7 KiB
TypeScript

import React from 'react';
import { useAppStore } from '../../store';
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 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 SyncIcon = () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>
</svg>
);
export const ActivityBar: React.FC = () => {
const { activeView, setActiveView, sidebarVisible, toggleSidebar, syncStatus, pendingChanges, openTab, tabs, activeTabId } = useAppStore();
const totalPending = pendingChanges.posts + pendingChanges.media;
// Check if settings tab is currently active
const isSettingsTabActive = tabs.some(t => t.type === 'settings' && t.id === activeTabId);
// Check if tags tab is currently active
const isTagsTabActive = tabs.some(t => t.type === 'tags' && t.id === activeTabId);
// Check if chat sidebar is active (activeView === 'chat' and sidebar is visible)
const isChatActive = activeView === 'chat' && sidebarVisible;
// Handle view click - toggle sidebar if clicking on active view, otherwise switch view
const handleViewClick = (view: 'posts' | 'media' | 'chat') => {
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 = () => {
// Open settings as a dedicated (non-transient) tab
openTab({ type: 'settings', id: 'settings', isTransient: false });
};
const handleTagsClick = () => {
// Open tags as a dedicated (non-transient) tab
openTab({ type: 'tags', id: 'tags', isTransient: false });
};
return (
<div className="activity-bar">
<div className="activity-bar-top">
<button
className={`activity-bar-item ${activeView === 'posts' && sidebarVisible ? 'active' : ''}`}
onClick={() => handleViewClick('posts')}
title="Posts (click again to toggle sidebar)"
>
<PostsIcon />
</button>
<button
className={`activity-bar-item ${activeView === 'media' && sidebarVisible ? 'active' : ''}`}
onClick={() => handleViewClick('media')}
title="Media (click again to toggle sidebar)"
>
<MediaIcon />
</button>
<button
className={`activity-bar-item ${isTagsTabActive ? 'active' : ''}`}
onClick={handleTagsClick}
title="Tags"
>
<TagsIcon />
</button>
<button
className={`activity-bar-item ${isChatActive ? 'active' : ''}`}
onClick={() => handleViewClick('chat')}
title="AI Assistant (click again to toggle sidebar)"
>
<ChatIcon />
</button>
</div>
<div className="activity-bar-bottom">
<button
className={`activity-bar-item ${syncStatus === 'syncing' ? 'syncing' : ''}`}
onClick={() => window.electronAPI?.sync.start()}
title={`Sync (${totalPending} pending)`}
>
<SyncIcon />
{totalPending > 0 && (
<span className="activity-bar-badge">{totalPending}</span>
)}
</button>
<button
className={`activity-bar-item ${isSettingsTabActive ? 'active' : ''}`}
onClick={handleSettingsClick}
title="Settings"
>
<SettingsIcon />
</button>
</div>
</div>
);
};