chore: phase 2 and 3 refactors
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { Tab } from '../store/appStore';
|
||||
import type { SidebarView } from './sidebarViewRegistry';
|
||||
|
||||
export type ActivityId = 'posts' | 'pages' | 'media' | 'tags' | 'chat' | 'import' | 'git' | 'settings';
|
||||
export type SidebarView = 'posts' | 'pages' | 'media' | 'settings' | 'tags' | 'chat' | 'import' | 'git';
|
||||
|
||||
export interface ActivitySnapshot {
|
||||
activeView: SidebarView;
|
||||
|
||||
29
src/renderer/navigation/sectionActivation.ts
Normal file
29
src/renderer/navigation/sectionActivation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export interface ActivateSidebarSectionOptions {
|
||||
isEditorTabActive: boolean;
|
||||
ensureEditorTabActive: () => void;
|
||||
activateSection: () => void;
|
||||
delayWhenOpeningEditorMs?: number;
|
||||
schedule?: (callback: () => void, delayMs: number) => void;
|
||||
}
|
||||
|
||||
export function activateSidebarSection(options: ActivateSidebarSectionOptions): void {
|
||||
const {
|
||||
isEditorTabActive,
|
||||
ensureEditorTabActive,
|
||||
activateSection,
|
||||
delayWhenOpeningEditorMs = 100,
|
||||
schedule,
|
||||
} = options;
|
||||
|
||||
const runLater = schedule ?? ((callback: () => void, delayMs: number) => {
|
||||
window.setTimeout(callback, delayMs);
|
||||
});
|
||||
|
||||
if (!isEditorTabActive) {
|
||||
ensureEditorTabActive();
|
||||
runLater(activateSection, delayWhenOpeningEditorMs);
|
||||
return;
|
||||
}
|
||||
|
||||
runLater(activateSection, 0);
|
||||
}
|
||||
24
src/renderer/navigation/sidebarUiPersistence.ts
Normal file
24
src/renderer/navigation/sidebarUiPersistence.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
type SidebarSectionOwner = 'settings' | 'tags';
|
||||
|
||||
const SIDEBAR_SECTION_KEY_PREFIX = 'bds-sidebar-section';
|
||||
|
||||
function getStorageKey(owner: SidebarSectionOwner): string {
|
||||
return `${SIDEBAR_SECTION_KEY_PREFIX}:${owner}`;
|
||||
}
|
||||
|
||||
export function getPersistedSidebarSection(owner: SidebarSectionOwner): string | null {
|
||||
try {
|
||||
const value = localStorage.getItem(getStorageKey(owner));
|
||||
return value || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function setPersistedSidebarSection(owner: SidebarSectionOwner, sectionId: string): void {
|
||||
try {
|
||||
localStorage.setItem(getStorageKey(owner), sectionId);
|
||||
} catch {
|
||||
// Ignore storage failures
|
||||
}
|
||||
}
|
||||
18
src/renderer/navigation/sidebarViewRegistry.ts
Normal file
18
src/renderer/navigation/sidebarViewRegistry.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export const SIDEBAR_VIEW_REGISTRY = [
|
||||
'posts',
|
||||
'pages',
|
||||
'media',
|
||||
'settings',
|
||||
'tags',
|
||||
'chat',
|
||||
'import',
|
||||
'git',
|
||||
] as const;
|
||||
|
||||
export type SidebarView = (typeof SIDEBAR_VIEW_REGISTRY)[number];
|
||||
|
||||
export const DEFAULT_SIDEBAR_VIEW: SidebarView = 'posts';
|
||||
|
||||
export function isSidebarView(value: string): value is SidebarView {
|
||||
return (SIDEBAR_VIEW_REGISTRY as readonly string[]).includes(value);
|
||||
}
|
||||
27
src/renderer/navigation/siteValidationPersistence.ts
Normal file
27
src/renderer/navigation/siteValidationPersistence.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { SiteValidationReport } from '../../main/shared/electronApi';
|
||||
|
||||
const SITE_VALIDATION_REPORT_PREFIX = 'bds-site-validation-report';
|
||||
|
||||
function getStorageKey(projectId: string): string {
|
||||
return `${SITE_VALIDATION_REPORT_PREFIX}:${projectId}`;
|
||||
}
|
||||
|
||||
export function persistSiteValidationReport(projectId: string, report: SiteValidationReport): void {
|
||||
try {
|
||||
localStorage.setItem(getStorageKey(projectId), JSON.stringify(report));
|
||||
} catch {
|
||||
// Ignore persistence failures.
|
||||
}
|
||||
}
|
||||
|
||||
export function getPersistedSiteValidationReport(projectId: string): SiteValidationReport | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(getStorageKey(projectId));
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(raw) as SiteValidationReport;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
35
src/renderer/navigation/tabPolicy.ts
Normal file
35
src/renderer/navigation/tabPolicy.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { TabType } from '../store/appStore';
|
||||
|
||||
export type SingletonToolTabKey =
|
||||
| 'settings'
|
||||
| 'tags'
|
||||
| 'style'
|
||||
| 'documentation'
|
||||
| 'metadata-diff'
|
||||
| 'site-validation';
|
||||
|
||||
export interface CanonicalTabSpec {
|
||||
type: TabType;
|
||||
id: string;
|
||||
isTransient: boolean;
|
||||
}
|
||||
|
||||
const SINGLETON_TOOL_TAB_REGISTRY: Record<SingletonToolTabKey, CanonicalTabSpec> = {
|
||||
settings: { type: 'settings', id: 'settings', isTransient: false },
|
||||
tags: { type: 'tags', id: 'tags', isTransient: false },
|
||||
style: { type: 'style', id: 'style', isTransient: false },
|
||||
documentation: { type: 'documentation', id: 'documentation', isTransient: false },
|
||||
'metadata-diff': { type: 'metadata-diff', id: 'metadata-diff', isTransient: false },
|
||||
'site-validation': { type: 'site-validation', id: 'site-validation', isTransient: false },
|
||||
};
|
||||
|
||||
export function getSingletonToolTabSpec(key: SingletonToolTabKey): CanonicalTabSpec {
|
||||
return SINGLETON_TOOL_TAB_REGISTRY[key];
|
||||
}
|
||||
|
||||
export function openSingletonToolTab(
|
||||
openTab: (tab: CanonicalTabSpec) => void,
|
||||
key: SingletonToolTabKey,
|
||||
): void {
|
||||
openTab(getSingletonToolTabSpec(key));
|
||||
}
|
||||
Reference in New Issue
Block a user