Files
note2any/src/preview-view-backup.ts
2025-10-08 19:45:28 +08:00

895 lines
32 KiB
TypeScript
Raw Permalink 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.

/**
* 文件note-preview.ts
* 功能:侧边预览视图;支持多平台预览(公众号/小红书)与发布触发。
* - 渲染 Markdown
* - 平台切换下拉
* - 单篇发布入口
* - 与批量发布/图片处理集成预留
*/
import { EventRef, ItemView, Workspace, WorkspaceLeaf, Notice, Platform, TFile, TFolder, TAbstractFile, Plugin } from 'obsidian';
import { uevent, debounce, waitForLayoutReady } from './utils';
import { NMPSettings } from './settings';
import AssetsManager from './assets';
import { MarkedParser } from './markdown/parser';
import { LocalImageManager, LocalFile } from './markdown/local-file';
import { CardDataManager } from './markdown/code';
import { ArticleRender } from './article-render';
// 平台选择组件
import { PlatformChooser, PlatformType } from './platform-chooser';
// 微信公众号功能模块
import { WechatPreview } from './wechat/wechat-preview';
// 小红书功能模块
import { XiaohongshuContentAdapter } from './xiaohongshu/adapter';
import { XiaohongshuImageManager } from './xiaohongshu/image';
import { XiaohongshuAPIManager } from './xiaohongshu/api';
import { XiaohongshuPost } from './xiaohongshu/types';
import { XiaohongshuPreview } from './xiaohongshu/xhs-preview';
// 切图功能
import { sliceArticleImage } from './slice-image';
export const VIEW_TYPE_NOTE_PREVIEW = 'note-preview';
export class NotePreview extends ItemView {
workspace: Workspace;
plugin: Plugin;
mainDiv: HTMLDivElement;
toolbar: HTMLDivElement;
renderDiv: HTMLDivElement;
articleDiv: HTMLDivElement;
styleEl: HTMLElement;
coverEl: HTMLInputElement;
useDefaultCover: HTMLInputElement;
useLocalCover: HTMLInputElement;
msgView: HTMLDivElement;
wechatSelect: HTMLSelectElement;
platformSelect: HTMLSelectElement; // 新增:平台选择器
themeSelect: HTMLSelectElement;
highlightSelect: HTMLSelectElement;
listeners?: EventRef[];
container: Element;
settings: NMPSettings;
assetsManager: AssetsManager;
articleHTML: string;
title: string;
currentFile?: TFile;
currentTheme: string;
currentHighlight: string;
currentAppId: string;
currentPlatform: string = 'wechat'; // 新增:当前选择的平台,默认微信
markedParser: MarkedParser;
cachedElements: Map<string, string> = new Map();
_articleRender: ArticleRender | null = null;
_xiaohongshuPreview: XiaohongshuPreview | null = null;
_wechatPreview: WechatPreview | null = null;
_platformChooser: PlatformChooser | null = null;
isCancelUpload: boolean = false;
isBatchRuning: boolean = false;
constructor(leaf: WorkspaceLeaf, plugin: Plugin) {
super(leaf);
this.workspace = this.app.workspace;
this.plugin = plugin;
this.settings = NMPSettings.getInstance();
this.assetsManager = AssetsManager.getInstance();
this.currentTheme = this.settings.defaultStyle;
this.currentHighlight = this.settings.defaultHighlight;
}
getViewType() {
return VIEW_TYPE_NOTE_PREVIEW;
}
getIcon() {
return 'clipboard-paste';
}
getDisplayText() {
return '笔记预览';
}
get render() {
if (!this._articleRender) {
this._articleRender = new ArticleRender(this.app, this, this.styleEl, this.articleDiv);
this._articleRender.currentTheme = this.currentTheme;
this._articleRender.currentHighlight = this.currentHighlight;
}
return this._articleRender;
}
async onOpen() {
this.viewLoading();
this.setup();
uevent('open');
}
async setup() {
await waitForLayoutReady(this.app);
if (!this.settings.isLoaded) {
const data = await this.plugin.loadData();
NMPSettings.loadSettings(data);
}
if (!this.assetsManager.isLoaded) {
await this.assetsManager.loadAssets();
}
this.buildUI();
this.listeners = [
this.workspace.on('file-open', () => {
this.update();
}),
this.app.vault.on("modify", (file) => {
if (this.currentFile?.path == file.path) {
this.renderMarkdown();
}
} )
];
this.renderMarkdown();
}
async onClose() {
this.listeners?.forEach(listener => this.workspace.offref(listener));
LocalFile.fileCache.clear();
uevent('close');
}
onAppIdChanged() {
// 清理上传过的图片
this.cleanArticleData();
}
async update() {
if (this.isBatchRuning) {
return;
}
this.cleanArticleData();
this.renderMarkdown();
}
cleanArticleData() {
LocalImageManager.getInstance().cleanup();
CardDataManager.getInstance().cleanup();
}
buildMsgView(parent: HTMLDivElement) {
this.msgView = parent.createDiv({ cls: 'msg-view' });
const title = this.msgView.createDiv({ cls: 'msg-title' });
title.id = 'msg-title';
title.innerText = '加载中...';
const okBtn = this.msgView.createEl('button', { cls: 'msg-ok-btn' }, async (button) => {
});
okBtn.id = 'msg-ok-btn';
okBtn.innerText = '确定';
okBtn.onclick = async () => {
this.msgView.setAttr('style', 'display: none;');
}
const cancelBtn = this.msgView.createEl('button', { cls: 'msg-ok-btn' }, async (button) => {
});
cancelBtn.id = 'msg-cancel-btn';
cancelBtn.innerText = '取消';
cancelBtn.onclick = async () => {
this.isCancelUpload = true;
this.msgView.setAttr('style', 'display: none;');
}
}
showLoading(msg: string, cancelable: boolean = false) {
const title = this.msgView.querySelector('#msg-title') as HTMLElement;
title!.innerText = msg;
const btn = this.msgView.querySelector('#msg-ok-btn') as HTMLElement;
btn.setAttr('style', 'display: none;');
this.msgView.setAttr('style', 'display: flex;');
const cancelBtn = this.msgView.querySelector('#msg-cancel-btn') as HTMLElement;
cancelBtn.setAttr('style', cancelable ? 'display: block;': 'display: none;');
this.msgView.setAttr('style', 'display: flex;');
}
showMsg(msg: string) {
const title = this.msgView.querySelector('#msg-title') as HTMLElement;
title!.innerText = msg;
const btn = this.msgView.querySelector('#msg-ok-btn') as HTMLElement;
btn.setAttr('style', 'display: block;');
this.msgView.setAttr('style', 'display: flex;');
const cancelBtn = this.msgView.querySelector('#msg-cancel-btn') as HTMLElement;
cancelBtn.setAttr('style', 'display: none;');
this.msgView.setAttr('style', 'display: flex;');
}
buildToolbar(parent: HTMLDivElement) {
this.toolbar = parent.createDiv({ cls: 'preview-toolbar' });
let lineDiv;
// 平台选择器(新增)- 始终显示
lineDiv = this.toolbar.createDiv({ cls: 'toolbar-line platform-selector-line' });
const platformLabel = lineDiv.createDiv({ cls: 'style-label' });
platformLabel.innerText = '发布平台';
const platformSelect = lineDiv.createEl('select', { cls: 'platform-select' });
// 添加平台选项
const wechatOption = platformSelect.createEl('option');
wechatOption.value = 'wechat';
wechatOption.text = '微信公众号';
wechatOption.selected = true;
const xiaohongshuOption = platformSelect.createEl('option');
xiaohongshuOption.value = 'xiaohongshu';
xiaohongshuOption.text = '小红书';
platformSelect.onchange = async () => {
this.currentPlatform = platformSelect.value;
await this.onPlatformChanged();
};
this.platformSelect = platformSelect;
// 公众号
if (this.settings.wxInfo.length > 1 || Platform.isDesktop) {
lineDiv = this.toolbar.createDiv({ cls: 'toolbar-line wechat-only' });
const wxLabel = lineDiv.createDiv({ cls: 'style-label' });
wxLabel.innerText = '公众号';
const wxSelect = lineDiv.createEl('select', { cls: 'wechat-select' });
wxSelect.onchange = async () => {
this.currentAppId = wxSelect.value;
this.onAppIdChanged();
}
const defautlOp =wxSelect.createEl('option');
defautlOp.value = '';
defautlOp.text = '请在设置里配置公众号';
for (let i = 0; i < this.settings.wxInfo.length; i++) {
const op = wxSelect.createEl('option');
const wx = this.settings.wxInfo[i];
op.value = wx.appid;
op.text = wx.name;
if (i== 0) {
op.selected = true
this.currentAppId = wx.appid;
}
}
this.wechatSelect = wxSelect;
if (Platform.isDesktop) {
// 分隔线
const separator = lineDiv.createDiv({ cls: 'toolbar-separator' });
const openBtn = lineDiv.createEl('button', { text: '🌐 去公众号后台', cls: 'toolbar-button purple-gradient' });
openBtn.onclick = async () => {
const { shell } = require('electron');
shell.openExternal('https://mp.weixin.qq.com')
uevent('open-mp');
}
}
}
else if (this.settings.wxInfo.length > 0) {
this.currentAppId = this.settings.wxInfo[0].appid;
}
// 复制,刷新,带图片复制,发草稿箱
lineDiv = this.toolbar.createDiv({ cls: 'toolbar-line wechat-only flex-wrap' });
const refreshBtn = lineDiv.createEl('button', { text: '🔄 刷新', cls: 'toolbar-button purple-gradient' });
refreshBtn.onclick = async () => {
await this.assetsManager.loadCustomCSS();
await this.assetsManager.loadExpertSettings();
this.render.reloadStyle();
await this.renderMarkdown();
uevent('refresh');
}
if (Platform.isDesktop) {
const copyBtn = lineDiv.createEl('button', { text: '📋 复制', cls: 'toolbar-button' });
copyBtn.onclick = async() => {
try {
await this.render.copyArticle();
new Notice('复制成功,请到公众号编辑器粘贴。');
uevent('copy');
} catch (error) {
console.error(error);
new Notice('复制失败: ' + error);
}
}
}
const uploadImgBtn = lineDiv.createEl('button', { text: '📤 上传图片', cls: 'toolbar-button' });
uploadImgBtn.onclick = async() => {
await this.uploadImages();
uevent('upload');
}
const postBtn = lineDiv.createEl('button', { text: '📝 发草稿', cls: 'toolbar-button' });
postBtn.onclick = async() => {
await this.postArticle();
uevent('pub');
}
const imagesBtn = lineDiv.createEl('button', { text: '🖼️ 图片/文字', cls: 'toolbar-button' });
imagesBtn.onclick = async() => {
await this.postImages();
uevent('pub-images');
}
if (Platform.isDesktop && this.settings.isAuthKeyVaild()) {
const htmlBtn = lineDiv.createEl('button', { text: '💾 导出HTML', cls: 'toolbar-button' });
htmlBtn.onclick = async() => {
await this.exportHTML();
uevent('export-html');
}
}
// 封面
lineDiv = this.toolbar.createDiv({ cls: 'toolbar-line wechat-only' });
const coverTitle = lineDiv.createDiv({ cls: 'style-label' });
coverTitle.innerText = '封面';
this.useDefaultCover = lineDiv.createEl('input', { cls: 'input-style' });
this.useDefaultCover.setAttr('type', 'radio');
this.useDefaultCover.setAttr('name', 'cover');
this.useDefaultCover.setAttr('value', 'default');
this.useDefaultCover.setAttr('checked', true);
this.useDefaultCover.id = 'default-cover';
this.useDefaultCover.onchange = async () => {
if (this.useDefaultCover.checked) {
this.coverEl.setAttr('style', 'visibility:hidden;width:0px;');
}
else {
this.coverEl.setAttr('style', 'visibility:visible;width:180px;');
}
}
const defaultLable = lineDiv.createEl('label');
defaultLable.innerText = '默认';
defaultLable.setAttr('for', 'default-cover');
this.useLocalCover = lineDiv.createEl('input', { cls: 'input-style' });
this.useLocalCover.setAttr('type', 'radio');
this.useLocalCover.setAttr('name', 'cover');
this.useLocalCover.setAttr('value', 'local');
this.useLocalCover.id = 'local-cover';
this.useLocalCover.setAttr('style', 'margin-left:20px;');
this.useLocalCover.onchange = async () => {
if (this.useLocalCover.checked) {
this.coverEl.setAttr('style', 'visibility:visible;width:180px;');
}
else {
this.coverEl.setAttr('style', 'visibility:hidden;width:0px;');
}
}
const localLabel = lineDiv.createEl('label');
localLabel.setAttr('for', 'local-cover');
localLabel.innerText = '上传';
this.coverEl = lineDiv.createEl('input', { cls: 'upload-input' });
this.coverEl.setAttr('type', 'file');
this.coverEl.setAttr('placeholder', '封面图片');
this.coverEl.setAttr('accept', '.png, .jpg, .jpeg');
this.coverEl.setAttr('name', 'cover');
this.coverEl.id = 'cover-input';
// 样式
if (this.settings.showStyleUI) {
lineDiv = this.toolbar.createDiv({ cls: 'toolbar-line wechat-only flex-wrap' });
const cssStyle = lineDiv.createDiv({ cls: 'style-label' });
cssStyle.innerText = '样式';
const selectBtn = lineDiv.createEl('select', { cls: 'style-select' });
selectBtn.onchange = async () => {
this.currentTheme = selectBtn.value;
this.render.updateStyle(selectBtn.value);
}
for (let s of this.assetsManager.themes) {
const op = selectBtn.createEl('option');
op.value = s.className;
op.text = s.name;
op.selected = s.className == this.settings.defaultStyle;
}
this.themeSelect = selectBtn;
// 分隔线
const separator = lineDiv.createDiv({ cls: 'toolbar-separator' });
const highlightStyle = lineDiv.createDiv({ cls: 'style-label' });
highlightStyle.innerText = '代码高亮';
const highlightStyleBtn = lineDiv.createEl('select', { cls: 'style-select' });
highlightStyleBtn.onchange = async () => {
this.currentHighlight = highlightStyleBtn.value;
this.render.updateHighLight(highlightStyleBtn.value);
}
for (let s of this.assetsManager.highlights) {
const op = highlightStyleBtn.createEl('option');
op.value = s.name;
op.text = s.name;
op.selected = s.name == this.settings.defaultHighlight;
}
this.highlightSelect = highlightStyleBtn;
}
this.buildMsgView(this.toolbar);
}
async buildUI() {
this.container = this.containerEl.children[1];
this.container.empty();
this.mainDiv = this.container.createDiv({ cls: 'note-preview' });
this.buildToolbar(this.mainDiv);
this.renderDiv = this.mainDiv.createDiv({cls: 'render-div'});
this.renderDiv.id = 'render-div';
this.styleEl = this.renderDiv.createEl('style');
this.styleEl.setAttr('title', 'note-to-mp-style');
this.articleDiv = this.renderDiv.createEl('div');
}
async viewLoading() {
const container = this.containerEl.children[1]
container.empty();
const loading = container.createDiv({cls: 'loading-wrapper'})
loading.createDiv({cls: 'loading-spinner'})
}
async renderMarkdown(af: TFile | null = null) {
if (!af) {
af = this.app.workspace.getActiveFile();
}
if (!af || af.extension.toLocaleLowerCase() !== 'md') {
return;
}
this.currentFile = af;
// 如果关闭了样式 UI则在渲染前强制使用全局默认样式/高亮(忽略 frontmatter 中的 theme/highlight
if (!this.settings.showStyleUI) {
const globalStyle = this.settings.defaultStyle;
const globalHighlight = this.settings.defaultHighlight;
// 仅当变更时更新当前与 articleRender 中的值,避免不必要的刷新
if (this.currentTheme !== globalStyle) {
this.currentTheme = globalStyle;
if (this._articleRender) {
this._articleRender.currentTheme = globalStyle;
}
}
if (this.currentHighlight !== globalHighlight) {
this.currentHighlight = globalHighlight;
if (this._articleRender) {
this._articleRender.currentHighlight = globalHighlight;
}
}
}
await this.render.renderMarkdown(af);
const metadata = this.render.getMetadata();
if (metadata.appid) {
this.wechatSelect.value = metadata.appid;
}
else {
this.wechatSelect.value = this.currentAppId;
}
// 仅当 UI 开启时才允许 frontmatter 覆盖与下拉同步;关闭时忽略 frontmatter 的 theme/highlight
if (this.settings.showStyleUI) {
if (metadata.theme) {
this.assetsManager.themes.forEach(theme => {
if (theme.name === metadata.theme) {
this.currentTheme = theme.className;
if (this.themeSelect) this.themeSelect.value = theme.className;
if (this._articleRender) this._articleRender.currentTheme = theme.className;
}
});
} else if (this.themeSelect) {
this.themeSelect.value = this.currentTheme;
}
if (metadata.highlight) {
this.currentHighlight = metadata.highlight;
if (this.highlightSelect) this.highlightSelect.value = metadata.highlight;
if (this._articleRender) this._articleRender.currentHighlight = metadata.highlight;
} else if (this.highlightSelect) {
this.highlightSelect.value = this.currentHighlight;
}
}
// 如果当前是小红书平台,更新小红书预览
if (this.currentPlatform === 'xiaohongshu' && this._xiaohongshuPreview) {
this.articleHTML = this.render.articleHTML;
await this._xiaohongshuPreview.renderArticle(this.articleHTML, af);
}
}
/**
* 平台切换处理
* 当用户切换发布平台时调用
*/
async onPlatformChanged() {
console.log(`[NotePreview] 平台切换至: ${this.currentPlatform}`);
if (this.currentPlatform === 'xiaohongshu') {
// 切换到小红书预览模式
await this.switchToXiaohongshuMode();
} else {
// 切换到微信公众号模式
this.switchToWechatMode();
}
}
/**
* 切换到小红书预览模式
*/
private async switchToXiaohongshuMode() {
// 隐藏微信相关的工具栏行和平台选择器
if (this.toolbar) {
const wechatLines = this.toolbar.querySelectorAll('.wechat-only');
wechatLines.forEach((line: HTMLElement) => {
line.style.display = 'none';
});
// 也隐藏平台选择器行
// const platformLine = this.toolbar.querySelector('.platform-selector-line') as HTMLElement;
// if (platformLine) {
// platformLine.style.display = 'none';
// }
}
// 隐藏渲染区域
if (this.renderDiv) this.renderDiv.style.display = 'none';
// 创建或显示小红书预览视图
if (!this._xiaohongshuPreview) {
const xhsContainer = this.mainDiv.createDiv({ cls: 'xiaohongshu-preview-container' });
this._xiaohongshuPreview = new XiaohongshuPreview(xhsContainer, this.app);
// 设置回调函数
this._xiaohongshuPreview.onRefreshCallback = async () => {
await this.onXiaohongshuRefresh();
};
this._xiaohongshuPreview.onPublishCallback = async () => {
await this.onXiaohongshuPublish();
};
this._xiaohongshuPreview.onPlatformChangeCallback = async (platform: string) => {
this.currentPlatform = platform;
if (platform === 'wechat') {
await this.onPlatformChanged();
}
};
this._xiaohongshuPreview.build();
} else {
const xhsContainer = this.mainDiv.querySelector('.xiaohongshu-preview-container') as HTMLElement;
if (xhsContainer) xhsContainer.style.display = 'flex';
}
// 如果有当前文件,渲染小红书预览
if (this.currentFile) {
// 如果还没有生成 articleHTML先生成它
if (!this.articleHTML) {
await this.render.renderMarkdown(this.currentFile);
this.articleHTML = this.render.articleHTML;
}
// 渲染到小红书预览
if (this.articleHTML) {
await this._xiaohongshuPreview.renderArticle(this.articleHTML, this.currentFile);
}
}
}
/**
* 切换到微信公众号模式
*/
private switchToWechatMode() {
// 显示微信相关的工具栏行和平台选择器
if (this.toolbar) {
const wechatLines = this.toolbar.querySelectorAll('.wechat-only');
wechatLines.forEach((line: HTMLElement) => {
line.style.display = 'flex';
});
// 也显示平台选择器行
const platformLine = this.toolbar.querySelector('.platform-selector-line') as HTMLElement;
if (platformLine) {
platformLine.style.display = 'flex';
}
}
// 显示渲染区域
if (this.renderDiv) this.renderDiv.style.display = 'block';
// 隐藏小红书预览视图
const xhsContainer = this.mainDiv.querySelector('.xiaohongshu-preview-container') as HTMLElement;
if (xhsContainer) xhsContainer.style.display = 'none';
}
/**
* 更新按钮文本为微信公众号相关
*/
private updateButtonsForWechat() {
const buttons = this.toolbar.querySelectorAll('button');
buttons.forEach(button => {
const text = button.textContent;
if (text === '发布到小红书') {
button.textContent = '发草稿';
} else if (text === '上传图片(小红书)') {
button.textContent = '上传图片';
}
});
}
/**
* 更新按钮文本为小红书相关
*/
private updateButtonsForXiaohongshu() {
const buttons = this.toolbar.querySelectorAll('button');
buttons.forEach(button => {
const text = button.textContent;
if (text === '发草稿') {
button.textContent = '发布到小红书';
} else if (text === '上传图片') {
button.textContent = '上传图片(小红书)';
}
});
}
async uploadImages() {
if (this.currentPlatform === 'wechat') {
await this.uploadImagesToWechat();
} else if (this.currentPlatform === 'xiaohongshu') {
await this.uploadImagesToXiaohongshu();
}
}
/**
* 上传图片到微信公众号
*/
async uploadImagesToWechat() {
this.showLoading('图片上传中...');
try {
await this.render.uploadImages(this.currentAppId);
this.showMsg('图片上传成功,并且文章内容已复制,请到公众号编辑器粘贴。');
} catch (error) {
this.showMsg('图片上传失败: ' + error.message);
}
}
/**
* 上传图片到小红书
*/
async uploadImagesToXiaohongshu() {
this.showLoading('处理图片中...');
try {
// 获取小红书适配器和图片处理器
const adapter = new XiaohongshuContentAdapter();
const imageHandler = XiaohongshuImageManager.getInstance();
// 获取当前文档的图片
const imageManager = LocalImageManager.getInstance();
const images = imageManager.getImageInfos(this.articleDiv);
if (images.length === 0) {
this.showMsg('当前文档没有图片需要处理');
return;
}
// 处理图片转换为PNG格式
const imageBlobs: { name: string; blob: Blob }[] = [];
for (const img of images) {
// 从filePath获取文件
const file = this.app.vault.getAbstractFileByPath(img.filePath);
if (file && file instanceof TFile) {
const fileData = await this.app.vault.readBinary(file);
imageBlobs.push({
name: file.name,
blob: new Blob([fileData])
});
}
}
const processedImages = await imageHandler.processImages(imageBlobs);
this.showMsg(`成功处理 ${processedImages.length} 张图片已转换为PNG格式`);
} catch (error) {
this.showMsg('图片处理失败: ' + error.message);
}
}
async postArticle() {
if (this.currentPlatform === 'wechat') {
await this.postToWechat();
} else if (this.currentPlatform === 'xiaohongshu') {
await this.postToXiaohongshu();
}
}
/**
* 发布到微信公众号草稿
*/
async postToWechat() {
let localCover = null;
if (this.useLocalCover.checked) {
const fileInput = this.coverEl;
if (!fileInput.files || fileInput.files.length === 0) {
this.showMsg('请选择封面文件');
return;
}
localCover = fileInput.files[0];
if (!localCover) {
this.showMsg('请选择封面文件');
return;
}
}
this.showLoading('发布中...');
try {
await this.render.postArticle(this.currentAppId, localCover);
this.showMsg('发布成功');
}
catch (error) {
this.showMsg('发布失败: ' + error.message);
}
}
/**
* 发布到小红书
*/
async postToXiaohongshu() {
this.showLoading('发布到小红书中...');
try {
if (!this.currentFile) {
this.showMsg('没有可发布的文件');
return;
}
// 读取文件内容
const fileContent = await this.app.vault.read(this.currentFile);
// 使用小红书适配器转换内容
const adapter = new XiaohongshuContentAdapter();
const xiaohongshuPost = adapter.adaptMarkdownToXiaohongshu(fileContent, {
addStyle: true,
generateTitle: true
});
// 验证内容
const validation = adapter.validatePost(xiaohongshuPost);
if (!validation.valid) {
this.showMsg('内容验证失败: ' + validation.errors.join('; '));
return;
}
// 获取小红书API实例
const api = XiaohongshuAPIManager.getInstance(false); // 暂时使用false
// 检查登录状态
const isLoggedIn = await api.checkLoginStatus();
if (!isLoggedIn) {
this.showMsg('请先登录小红书,或检查登录状态');
return;
}
// 发布内容
const result = await api.createPost(xiaohongshuPost);
if (result.success) {
this.showMsg('发布到小红书成功!');
} else {
this.showMsg('发布失败: ' + result.message);
}
}
catch (error) {
this.showMsg('发布失败: ' + error.message);
}
}
/**
* 小红书预览的刷新回调
*/
async onXiaohongshuRefresh() {
await this.assetsManager.loadCustomCSS();
await this.assetsManager.loadExpertSettings();
// 更新小红书预览的样式
if (this._xiaohongshuPreview) {
this._xiaohongshuPreview.assetsManager = this.assetsManager;
}
await this.renderMarkdown();
new Notice('刷新成功');
}
/**
* 小红书预览的发布回调
*/
async onXiaohongshuPublish() {
await this.postToXiaohongshu();
}
async postImages() {
this.showLoading('发布图片中...');
try {
await this.render.postImages(this.currentAppId);
this.showMsg('图片发布成功');
} catch (error) {
this.showMsg('图片发布失败: ' + error.message);
}
}
async exportHTML() {
this.showLoading('导出HTML中...');
try {
await this.render.exportHTML();
this.showMsg('HTML导出成功');
} catch (error) {
this.showMsg('HTML导出失败: ' + error.message);
}
}
async sliceArticleImage() {
if (!this.currentFile) {
new Notice('请先打开一个笔记文件');
return;
}
this.showLoading('切图处理中...');
try {
const articleSection = this.render.getArticleSection();
if (!articleSection) {
throw new Error('未找到预览区域');
}
await sliceArticleImage(articleSection, this.currentFile, this.app);
this.showMsg('切图完成');
} catch (error) {
console.error('切图失败:', error);
this.showMsg('切图失败: ' + error.message);
}
}
async batchPost(folder: TFolder) {
const files = folder.children.filter((child: TAbstractFile) => child.path.toLocaleLowerCase().endsWith('.md'));
if (!files) {
new Notice('没有可渲染的笔记或文件不支持渲染');
return;
}
this.isCancelUpload = false;
this.isBatchRuning = true;
try {
for (let file of files) {
this.showLoading(`即将发布: ${file.name}`, true);
await sleep(5000);
if (this.isCancelUpload) {
break;
}
this.cleanArticleData();
await this.renderMarkdown(file as TFile);
await this.postArticle();
}
if (!this.isCancelUpload) {
this.showMsg(`批量发布完成:成功发布 ${files.length} 篇笔记`);
}
}
catch (e) {
console.error(e);
new Notice('批量发布失败: ' + e.message);
}
finally {
this.isBatchRuning = false;
this.isCancelUpload = false;
}
}
}