/** * 文件:preview-manager.ts * 作用:预览管理器,负责协调所有平台预览组件 * * 职责: * 1. 创建和管理所有子组件(platform-chooser, wechat-preview, xhs-preview) * 2. 处理平台切换逻辑(唯一入口) * 3. 管理文章渲染和状态同步 * 4. 提供统一的对外接口 * * 设计模式: * - 中介者模式(Mediator): 协调各组件交互 * - 外观模式(Facade): 提供简单的对外接口 */ import { TFile, Notice, App } from 'obsidian'; import { PlatformType } from './platform-chooser'; import { WechatPreview } from './wechat/wechat-preview'; import { XiaohongshuPreview } from './xiaohongshu/xhs-preview'; import { ArticleRender } from './article-render'; import { NMPSettings } from './settings'; export class PreviewManager { private container: HTMLElement; private app: App; private render: ArticleRender; private settings: NMPSettings; // 子组件 private wechatPreview: WechatPreview | null = null; private xhsPreview: XiaohongshuPreview | null = null; // UI 容器 private mainDiv: HTMLDivElement | null = null; private wechatContainer: HTMLDivElement | null = null; private xhsContainer: HTMLDivElement | null = null; // 默认平台 private currentPlatform: PlatformType = 'wechat'; private currentFile: TFile | null = null; constructor(container: HTMLElement, app: App, render: ArticleRender) { this.container = container; this.app = app; this.render = render; this.settings = NMPSettings.getInstance(); } /** * 构建界面(主入口) */ async build(): Promise { console.log('[PreviewManager] 开始构建界面'); // 清空容器 this.container.empty(); // 创建主容器 this.mainDiv = this.container.createDiv({ cls: 'note-preview' }); // 1. 创建并构建微信预览 this.createWechatPreview(); // 2. 创建并构建小红书预览 this.createXiaohongshuPreview(); // 3. 初始显示公众号平台 await this.switchPlatform('wechat'); console.log('[PreviewManager] 界面构建完成'); } /** * 创建微信预览组件 */ private createWechatPreview(): void { if (!this.mainDiv) return; // 创建微信预览容器 this.wechatContainer = this.mainDiv.createDiv({ cls: 'wechat-preview-container' }); // 创建微信预览实例 this.wechatPreview = new WechatPreview( this.wechatContainer, this.app, this.render ); // 设置回调函数 this.wechatPreview.onRefreshCallback = async () => { await this.refresh(); }; this.wechatPreview.onAppIdChangeCallback = (appId: string) => { console.log(`[PreviewManager] 公众号切换: ${appId}`); // 可以在这里处理公众号切换的额外逻辑 }; this.wechatPreview.onPlatformChangeCallback = (platform: string) => { this.switchPlatform(platform as PlatformType); }; // 构建 UI this.wechatPreview.build(); } private async publishCurrentPlatform(): Promise { if (this.currentPlatform === 'wechat') { if (!this.wechatPreview) { new Notice('微信预览未初始化'); return; } await this.wechatPreview.publish(); } else if (this.currentPlatform === 'xiaohongshu') { if (!this.xhsPreview) { new Notice('小红书预览未初始化'); return; } await this.xhsPreview.publish(); } } /** * 创建小红书预览组件 */ private createXiaohongshuPreview(): void { if (!this.mainDiv) return; // 创建小红书预览容器 this.xhsContainer = this.mainDiv.createDiv({ cls: 'xiaohongshu-preview-container' }); // 创建小红书预览实例 this.xhsPreview = new XiaohongshuPreview(this.xhsContainer, this.app); // 设置回调函数 this.xhsPreview.onRefreshCallback = async () => { await this.refresh(); }; this.xhsPreview.onPublishCallback = async () => { await this.publishToXiaohongshu(); }; this.xhsPreview.onPlatformChangeCallback = async (platform: string) => { if (platform === 'wechat') { await this.switchPlatform('wechat'); } }; // 构建 UI this.xhsPreview.build(); } /** * 平台切换的唯一入口 */ // 平台切换:公开以便外部(例如上下文菜单)调用 async switchPlatform(platform: PlatformType): Promise { console.log(`[PreviewManager] 平台切换: ${this.currentPlatform} → ${platform}`); const previousPlatform = this.currentPlatform; this.currentPlatform = platform; if (platform === 'wechat') { // 显示微信,隐藏小红书 this.showWechat(); this.hideXiaohongshu(); // 同步主题设置 if (this.wechatPreview) { this.wechatPreview.updateStyleAndHighlight( this.settings.defaultStyle, this.settings.defaultHighlight ); } // 如果有当前文件且是从其他平台切换过来,重新渲染 if (this.currentFile && previousPlatform !== 'wechat') { await this.renderForWechat(this.currentFile); } } else if (platform === 'xiaohongshu') { // 显示小红书,隐藏微信 this.showXiaohongshu(); this.hideWechat(); // 同步主题设置 if (this.xhsPreview) { this.xhsPreview.updateStyleAndHighlight( this.settings.defaultStyle, this.settings.defaultHighlight ); } // 如果有当前文件且是从其他平台切换过来,重新渲染 if (this.currentFile && previousPlatform !== 'xiaohongshu') { await this.renderForXiaohongshu(this.currentFile); } } } /** * 显示微信预览 */ private showWechat(): void { if (this.wechatContainer) { this.wechatContainer.style.display = 'flex'; } if (this.wechatPreview) { this.wechatPreview.show(); } } /** * 隐藏微信预览 */ private hideWechat(): void { if (this.wechatContainer) { this.wechatContainer.style.display = 'none'; } if (this.wechatPreview) { this.wechatPreview.hide(); } } /** * 显示小红书预览 */ private showXiaohongshu(): void { if (this.xhsContainer) { this.xhsContainer.style.display = 'flex'; } if (this.xhsPreview) { this.xhsPreview.show(); } } /** * 隐藏小红书预览 */ private hideXiaohongshu(): void { if (this.xhsContainer) { this.xhsContainer.style.display = 'none'; } if (this.xhsPreview) { this.xhsPreview.hide(); } } /** * 设置当前文件(对外接口) */ async setFile(file: TFile | null): Promise { if (!file) { this.currentFile = null; this.wechatPreview?.setFile(null); return; } // 只处理 Markdown 文件 if (file.extension.toLowerCase() !== 'md') { return; } console.log(`[PreviewManager] 设置文件: ${file.path}`); this.currentFile = file; this.wechatPreview?.setFile(file); // 根据当前平台渲染 if (this.currentPlatform === 'wechat') { await this.renderForWechat(file); } else if (this.currentPlatform === 'xiaohongshu') { await this.renderForXiaohongshu(file); } } /** * 刷新预览(对外接口) */ async refresh(): Promise { if (!this.currentFile) { new Notice('请先打开一个笔记文件'); return; } console.log(`[PreviewManager] 刷新预览: ${this.currentFile.path}`); await this.setFile(this.currentFile); } /** * 渲染微信预览 */ private async renderForWechat(file: TFile): Promise { try { console.log(`[PreviewManager] 渲染微信预览: ${file.path}`); // 使用 ArticleRender 渲染 Markdown await this.render.renderMarkdown(file); // 确保预览持有当前文件引用 this.wechatPreview?.setFile(file); // 微信预览已经通过 ArticleRender 更新了 // 这里可以添加额外的微信特定逻辑 console.log('[PreviewManager] 微信预览渲染完成'); } catch (error) { console.error('[PreviewManager] 渲染微信预览失败:', error); new Notice('渲染失败: ' + (error instanceof Error ? error.message : String(error))); } } /** * 渲染小红书预览 */ private async renderForXiaohongshu(file: TFile): Promise { try { console.log(`[PreviewManager] 渲染小红书预览: ${file.path}`); // 使用 ArticleRender 渲染 Markdown await this.render.renderMarkdown(file); const articleHTML = this.render.articleHTML; if (articleHTML && this.xhsPreview) { // 渲染到小红书预览 await this.xhsPreview.renderArticle(articleHTML, file); console.log('[PreviewManager] 小红书预览渲染完成'); } else { console.warn('[PreviewManager] 没有可渲染的内容'); } } catch (error) { console.error('[PreviewManager] 渲染小红书预览失败:', error); new Notice('渲染失败: ' + (error instanceof Error ? error.message : String(error))); } } /** * 发布到小红书 */ private async publishToXiaohongshu(): Promise { console.log('[PreviewManager] 发布到小红书'); // 这里实现发布逻辑 // 可以调用 xhsPreview 的相关方法 new Notice('发布功能开发中...'); } /** * 获取当前平台 */ getCurrentPlatform(): PlatformType { return this.currentPlatform; } /** * 获取当前文件 */ getCurrentFile(): TFile | null { return this.currentFile; } /** * 清理资源 */ destroy(): void { console.log('[PreviewManager] 清理资源'); if (this.wechatPreview) { this.wechatPreview.destroy(); this.wechatPreview = null; } if (this.xhsPreview) { this.xhsPreview.destroy(); this.xhsPreview = null; } this.mainDiv = null; this.wechatContainer = null; this.xhsContainer = null; this.currentFile = null; } /** 获取微信预览实例(发布操作需要) */ getWechatPreview(): WechatPreview | null { return this.wechatPreview; } }