Files
note2any/src/platform-chooser.ts
2025-10-10 17:00:09 +08:00

232 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 文件platform-chooser.ts
* 作用:平台选择器组件,负责渲染平台选择 UI 并处理平台切换事件
*
* 这是一个公共组件,独立于具体平台实现,便于未来扩展新平台
*/
import { Platform as ObsidianPlatform } from 'obsidian';
export type PlatformType = 'wechat' | 'xiaohongshu';
/**
* 平台选择器配置
*/
export interface PlatformChooserOptions {
/** 默认选中的平台 */
defaultPlatform?: PlatformType;
/** 平台切换回调 */
onPlatformChange?: (platform: PlatformType) => Promise<void>;
}
export interface PlatformActionLabels {
refresh: string;
publish: string;
}
export interface PlatformChooserActions {
onRefresh?: () => void | Promise<void>;
onPublish?: () => void | Promise<void>;
getLabels?: (platform: PlatformType) => PlatformActionLabels;
}
/**
* 平台信息接口
*/
interface PlatformInfo {
value: PlatformType;
label: string;
icon?: string;
}
/**
* 支持的平台列表
*/
const SUPPORTED_PLATFORMS: PlatformInfo[] = [
{ value: 'wechat', label: '微信公众号', icon: '📱' },
{ value: 'xiaohongshu', label: '小红书', icon: '📔' }
];
/**
* 平台选择器类
*
* 职责:
* 1. 渲染平台选择 UI
* 2. 处理用户的平台切换操作
* 3. 触发平台切换回调
* 4. 维护当前选中的平台状态
*/
export class PlatformChooser {
private container: HTMLElement;
private selectElement: HTMLSelectElement | null = null;
private refreshButton: HTMLButtonElement | null = null;
private publishButton: HTMLButtonElement | null = null;
private currentPlatform: PlatformType;
private onChange?: (platform: PlatformType) => void;
private actions: PlatformChooserActions | null = null;
constructor(container: HTMLElement, options: PlatformChooserOptions = {}) {
this.container = container;
this.currentPlatform = options.defaultPlatform || 'xiaohongshu';
if (options.onPlatformChange) {
this.onChange = (platform) => {
options.onPlatformChange!(platform);
};
}
}
/**
* 设置平台切换回调
*/
setOnChange(callback: (platform: PlatformType) => void): void {
this.onChange = callback;
}
/**
* 渲染平台选择器 UI
*/
render(): void {
// 将容器作为单层 Grid 行使用
this.container.addClass('platform-selector-line');
this.container.addClass('platform-chooser-grid');
// 创建标签
const platformLabel = this.container.createDiv({ cls: 'style-label' });
platformLabel.innerText = '发布平台';
// 创建选择器
const platformSelect = this.container.createEl('select', { cls: 'platform-select' });
this.selectElement = platformSelect;
// 添加平台选项
SUPPORTED_PLATFORMS.forEach(platform => {
const option = platformSelect.createEl('option');
option.value = platform.value;
option.text = platform.icon ? `${platform.icon} ${platform.label}` : platform.label;
// 设置默认选中
if (platform.value === this.currentPlatform) {
option.selected = true;
}
});
// 绑定切换事件
platformSelect.onchange = () => {
const newPlatform = platformSelect.value as PlatformType;
this.switchPlatformInternal(newPlatform);
};
// 刷新按钮
this.refreshButton = this.container.createEl('button', { cls: 'toolbar-button purple-gradient' });
this.refreshButton.onclick = () => this.handleRefreshClick();
// 发布按钮
this.publishButton = this.container.createEl('button', { cls: 'toolbar-button' });
this.publishButton.onclick = () => this.handlePublishClick();
this.updateActionLabels();
}
/**
* 切换平台(内部方法)
*/
private switchPlatformInternal(platform: PlatformType): void {
if (platform === this.currentPlatform) {
return; // 相同平台,不需要切换
}
console.log(`[PlatformChooser] 切换平台: ${this.currentPlatform} -> ${platform}`);
this.currentPlatform = platform;
// 触发平台切换回调
if (this.onChange) {
try {
this.onChange(platform);
} catch (error) {
console.error('[PlatformChooser] 平台切换失败:', error);
}
}
this.updateActionLabels();
}
/**
* 切换平台(公共方法,供 PreviewManager 调用)
*/
switchPlatform(platform: PlatformType): void {
this.currentPlatform = platform;
if (this.selectElement) {
this.selectElement.value = platform;
}
this.updateActionLabels();
}
/**
* 获取当前选中的平台
*/
getCurrentPlatform(): PlatformType {
return this.currentPlatform;
}
/**
* 程序化设置平台(不触发回调)
*/
setPlatform(platform: PlatformType): void {
this.currentPlatform = platform;
if (this.selectElement) {
this.selectElement.value = platform;
}
}
/**
* 清理资源
*/
destroy(): void {
if (this.selectElement) {
this.selectElement.onchange = null;
this.selectElement = null;
}
if (this.refreshButton) {
this.refreshButton.onclick = null;
this.refreshButton = null;
}
if (this.publishButton) {
this.publishButton.onclick = null;
this.publishButton = null;
}
}
/**
* 设置通用操作按钮
*/
setActions(actions: PlatformChooserActions): void {
this.actions = actions;
this.updateActionLabels();
}
private handleRefreshClick(): void {
if (!this.actions?.onRefresh) return;
Promise.resolve(this.actions.onRefresh()).catch((error) => {
console.error('[PlatformChooser] 刷新操作失败:', error);
});
}
private handlePublishClick(): void {
if (!this.actions?.onPublish) return;
Promise.resolve(this.actions.onPublish()).catch((error) => {
console.error('[PlatformChooser] 发布操作失败:', error);
});
}
private updateActionLabels(): void {
if (!this.refreshButton || !this.publishButton) return;
const labels = this.actions?.getLabels?.(this.currentPlatform) ?? {
refresh: '🔄 刷新',
publish: '📤 发布',
};
this.refreshButton.innerText = labels.refresh;
this.publishButton.innerText = labels.publish;
}
}