update at 2025-10-08 14:08:36
This commit is contained in:
134
src/platform-chooser.ts
Normal file
134
src/platform-chooser.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* 平台选择器组件
|
||||
* 提供统一的平台选择界面和切换逻辑
|
||||
*/
|
||||
|
||||
import { Platform, PlatformInfo, PlatformChangeCallback, SUPPORTED_PLATFORMS } from './types';
|
||||
|
||||
export class PlatformChooser {
|
||||
private container: HTMLElement;
|
||||
private selectElement: HTMLSelectElement;
|
||||
private currentPlatform: Platform;
|
||||
private onChangeCallback?: PlatformChangeCallback;
|
||||
|
||||
constructor(container: HTMLElement, defaultPlatform: Platform = 'wechat') {
|
||||
this.container = container;
|
||||
this.currentPlatform = defaultPlatform;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建平台选择器UI
|
||||
*/
|
||||
public build(): HTMLElement {
|
||||
const lineDiv = this.container.createDiv({ cls: 'toolbar-line platform-selector-line' });
|
||||
lineDiv.style.cssText = 'display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: linear-gradient(135deg, #fff3e0 0%, #ffffff 100%); border-left: 4px solid #1e88e5; border-radius: 6px; margin: 8px 10px;';
|
||||
|
||||
// 标签
|
||||
const platformLabel = lineDiv.createDiv({ cls: 'style-label' });
|
||||
platformLabel.innerText = '发布平台';
|
||||
platformLabel.style.cssText = 'font-size: 13px; color: #5f6368; font-weight: 500; white-space: nowrap;';
|
||||
|
||||
// 选择器
|
||||
this.selectElement = lineDiv.createEl('select', { cls: 'style-select' });
|
||||
this.selectElement.style.cssText = 'padding: 6px 12px; border: 1px solid #dadce0; border-radius: 6px; background: white; font-size: 13px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.1); min-width: 150px; font-weight: 500;';
|
||||
|
||||
// 添加平台选项
|
||||
SUPPORTED_PLATFORMS.forEach(platform => {
|
||||
const option = this.selectElement.createEl('option');
|
||||
option.value = platform.id;
|
||||
option.text = `${platform.icon || ''} ${platform.name}`.trim();
|
||||
if (platform.id === this.currentPlatform) {
|
||||
option.selected = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 绑定切换事件
|
||||
this.selectElement.onchange = async () => {
|
||||
const newPlatform = this.selectElement.value as Platform;
|
||||
await this.switchPlatform(newPlatform);
|
||||
};
|
||||
|
||||
return lineDiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置平台切换回调
|
||||
*/
|
||||
public onPlatformChange(callback: PlatformChangeCallback): void {
|
||||
this.onChangeCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选择的平台
|
||||
*/
|
||||
public getCurrentPlatform(): Platform {
|
||||
return this.currentPlatform;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前平台(程序化切换)
|
||||
*/
|
||||
public setCurrentPlatform(platform: Platform): void {
|
||||
this.currentPlatform = platform;
|
||||
if (this.selectElement) {
|
||||
this.selectElement.value = platform;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换平台
|
||||
*/
|
||||
private async switchPlatform(platform: Platform): Promise<void> {
|
||||
if (platform === this.currentPlatform) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[PlatformChooser] 切换平台: ${this.currentPlatform} -> ${platform}`);
|
||||
|
||||
const oldPlatform = this.currentPlatform;
|
||||
this.currentPlatform = platform;
|
||||
|
||||
// 调用回调函数
|
||||
if (this.onChangeCallback) {
|
||||
try {
|
||||
await this.onChangeCallback(platform);
|
||||
} catch (error) {
|
||||
console.error('[PlatformChooser] 平台切换失败:', error);
|
||||
// 回滚到旧平台
|
||||
this.currentPlatform = oldPlatform;
|
||||
this.selectElement.value = oldPlatform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示选择器
|
||||
*/
|
||||
public show(): void {
|
||||
if (this.container) {
|
||||
const line = this.container.querySelector('.platform-selector-line') as HTMLElement;
|
||||
if (line) {
|
||||
line.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏选择器
|
||||
*/
|
||||
public hide(): void {
|
||||
if (this.container) {
|
||||
const line = this.container.querySelector('.platform-selector-line') as HTMLElement;
|
||||
if (line) {
|
||||
line.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理资源
|
||||
*/
|
||||
public cleanup(): void {
|
||||
this.onChangeCallback = undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user