sync: contextual substrate UX from private repo

- Add DimensionIconsContext for app-wide dimension icon sharing
- Enhanced getNodeIcon() with favicon/YouTube/PDF detection + dimension icons
- Propagate dynamic icons to GridView, ListView, SearchModal, FocusPanel, ViewsOverlay, FolderViewOverlay
- Add RahEdge component with hover labels for map edges
- Update RahNode with dimension-colored borders and icon support
- Add MiniMap with dimension color coding to MapPane
- MCP server: add description field to rah_update_node, bump standalone to v1.4.2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-02-15 08:55:47 +11:00
co-authored by Claude Opus 4.6
parent d6987a3dc1
commit d723212ed3
17 changed files with 492 additions and 53 deletions
+15
View File
@@ -9,6 +9,7 @@ import { parseNodeMarkers } from '@/tools/infrastructure/nodeFormatter';
import { Node, NodeConnection, Chunk } from '@/types/database';
import DimensionTags from './dimensions/DimensionTags';
import { getNodeIcon } from '@/utils/nodeIcons';
import { useDimensionIcons } from '@/context/DimensionIconsContext';
import ConfirmDialog from '../common/ConfirmDialog';
import { SourceReader } from './source';
@@ -44,6 +45,7 @@ interface FocusPanelProps {
}
export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeClick, onTabClose, refreshTrigger, onOpenInOtherSlot, hideTabBar, onTextSelect, highlightedPassage }: FocusPanelProps) {
const { dimensionIcons } = useDimensionIcons();
const [nodesData, setNodesData] = useState<Record<number, Node>>({});
// Context menu state
@@ -1408,6 +1410,9 @@ export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeCli
}}>
{connection.connected_node.id}
</span>
<span style={{ flexShrink: 0, display: 'flex', alignItems: 'center' }}>
{getNodeIcon(connection.connected_node, dimensionIcons, 12)}
</span>
<span style={{ color: '#f8fafc', fontSize: '13px', fontWeight: 500 }}>{connection.connected_node.title}</span>
</div>
{edgeEditingId === connection.edge.id ? (
@@ -1880,6 +1885,13 @@ export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeCli
{activeTab}
</span>
{/* Node type icon */}
{nodesData[activeTab] && (
<span style={{ flexShrink: 0, display: 'flex', alignItems: 'center' }}>
{getNodeIcon(nodesData[activeTab], dimensionIcons, 18)}
</span>
)}
{editingField === 'title' ? (
<input
ref={inputRef as React.RefObject<HTMLInputElement>}
@@ -3209,6 +3221,9 @@ export default function FocusPanel({ openTabs, activeTab, onTabSelect, onNodeCli
}}>
{connection.connected_node.id}
</span>
<span style={{ flexShrink: 0, display: 'flex', alignItems: 'center' }}>
{getNodeIcon(connection.connected_node, dimensionIcons, 12)}
</span>
<span
onClick={() => onNodeClick?.(connection.connected_node.id)}
style={{