Files
note2any/src/settings.ts
2025-10-21 21:47:02 +08:00

237 lines
9.3 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.

/**
* 文件settings.ts
* 作用:插件全局设置模型(单例)与序列化/反序列化逻辑。
* 内容:
* - 默认值初始化
* - loadSettings: 反序列化存储数据并兼容旧字段
* - allSettings: 统一导出用于持久化
* - 会员 / 授权信息校验isAuthKeyVaild
* - 批量发布预设 / 图片处理 / 样式控制等选项
*/
import { wxKeyInfo } from './wechat/weixin-api';
export class NMPSettings {
defaultStyle: string;
defaultHighlight: string;
showStyleUI: boolean;
linkStyle: string;
embedStyle: string;
lineNumber: boolean;
authKey: string;
useCustomCss: boolean;
customCSSNote: string;
expertSettingsNote: string;
wxInfo: {name:string, appid:string, secret:string}[];
math: string;
expireat: Date | null = null;
isVip: boolean = false;
baseCSS: string;
watermark: string;
useFigcaption: boolean;
excalidrawToPNG: boolean;
isLoaded: boolean = false;
enableEmptyLine: boolean = false;
needOpenComment: boolean = true;
enableMarkdownImageToWikilink: boolean = true; // 自动将 ![alt](path/file.ext) 转为 ![[file.ext]]
// gallery 相关配置:根目录前缀 & 选取图片数量
galleryPrePath: string;
galleryNumPic: number;
// 无图片时的默认封面wikilink 或 URL 均可)
defaultCoverPic: string;
// 是否忽略 frontmatter 中的 cover/image 字段(用户要求:封面不使用 frontmatter image
ignoreFrontmatterImage: boolean;
// 批量发布筛选条件预设
batchPublishPresets: Array<{
name: string;
tags?: string[];
folders?: string[];
filenameKeywords?: string[];
}>;
// 切图相关配置
sliceImageSavePath: string; // 切图保存路径
sliceImageWidth: number; // 切图宽度(像素)
sliceImageAspectRatio: string; // 横竖比例,格式 "3:4"
xhsPreviewWidth: number; // 小红书预览宽度(像素)
private static instance: NMPSettings;
// 静态方法,用于获取实例
public static getInstance(): NMPSettings {
if (!NMPSettings.instance) {
NMPSettings.instance = new NMPSettings();
}
return NMPSettings.instance;
}
private constructor() {
this.defaultStyle = 'obsidian-light';
this.defaultHighlight = '默认';
this.showStyleUI = true;
this.linkStyle = 'inline';
this.embedStyle = 'content';
this.lineNumber = true;
this.useCustomCss = false;
this.authKey = '';
this.wxInfo = [];
this.math = 'latex';
this.baseCSS = '';
this.watermark = '';
this.useFigcaption = false;
this.customCSSNote = '';
this.excalidrawToPNG = false;
this.expertSettingsNote = '';
this.enableEmptyLine = false;
this.needOpenComment = true;
this.enableMarkdownImageToWikilink = true;
// 默认值:用户原先硬编码路径 & 前 2 张
this.galleryPrePath = '/Users/gavin/myweb/static';
this.galleryNumPic = 2;
// 默认封面:使用当前笔记同目录下的 cover.png (若存在会被后续流程正常解析;不存在则无效但可被用户覆盖)
this.defaultCoverPic = 'cover.png';
this.ignoreFrontmatterImage = false;
// 批量发布预设
this.batchPublishPresets = [
{
name: '篆刻文章',
tags: ['篆刻'],
folders: [],
filenameKeywords: []
}
];
// 切图配置默认值(使用 vault 相对路径)
this.sliceImageSavePath = 'xhs-images';
this.sliceImageWidth = 1080;
this.sliceImageAspectRatio = '3:4';
this.xhsPreviewWidth = 540;
}
resetStyelAndHighlight() {
this.defaultStyle = 'obsidian-light';
this.defaultHighlight = '默认';
}
public static loadSettings(data: any) {
if (!data) return;
const {
defaultStyle,
defaultHighlight,
showStyleUI,
linkStyle,
embedStyle,
lineNumber,
authKey,
wxInfo,
math,
useCustomCss,
baseCSS,
watermark,
useFigcaption,
customCSSNote,
excalidrawToPNG,
expertSettingsNote,
ignoreEmptyLine,
enableMarkdownImageToWikilink,
needOpenComment,
galleryPrePath,
galleryNumPic,
defaultCoverPic,
ignoreFrontmatterImage,
batchPublishPresets = [],
sliceImageSavePath,
sliceImageWidth,
sliceImageAspectRatio,
xhsPreviewWidth
} = data;
const settings = NMPSettings.getInstance();
if (defaultStyle) settings.defaultStyle = defaultStyle;
if (defaultHighlight) settings.defaultHighlight = defaultHighlight;
if (showStyleUI !== undefined) settings.showStyleUI = showStyleUI;
if (linkStyle) settings.linkStyle = linkStyle;
if (embedStyle) settings.embedStyle = embedStyle;
if (lineNumber !== undefined) settings.lineNumber = lineNumber;
if (authKey) settings.authKey = authKey;
if (wxInfo) settings.wxInfo = wxInfo;
if (math) settings.math = math;
if (useCustomCss !== undefined) settings.useCustomCss = useCustomCss;
if (baseCSS) settings.baseCSS = baseCSS;
if (watermark) settings.watermark = watermark;
if (useFigcaption !== undefined) settings.useFigcaption = useFigcaption;
if (customCSSNote) settings.customCSSNote = customCSSNote;
if (excalidrawToPNG !== undefined) settings.excalidrawToPNG = excalidrawToPNG;
if (expertSettingsNote) settings.expertSettingsNote = expertSettingsNote;
if (ignoreEmptyLine !== undefined) settings.enableEmptyLine = !!ignoreEmptyLine;
if (needOpenComment !== undefined) settings.needOpenComment = !!needOpenComment;
if (enableMarkdownImageToWikilink !== undefined) settings.enableMarkdownImageToWikilink = !!enableMarkdownImageToWikilink;
if (galleryPrePath) settings.galleryPrePath = galleryPrePath;
if (galleryNumPic !== undefined && Number.isFinite(galleryNumPic)) settings.galleryNumPic = Math.max(1, parseInt(galleryNumPic));
if (defaultCoverPic !== undefined) settings.defaultCoverPic = String(defaultCoverPic).trim();
if (ignoreFrontmatterImage !== undefined) settings.ignoreFrontmatterImage = !!ignoreFrontmatterImage;
if (Array.isArray(batchPublishPresets)) settings.batchPublishPresets = batchPublishPresets;
if (sliceImageSavePath) settings.sliceImageSavePath = sliceImageSavePath;
if (sliceImageWidth !== undefined && Number.isFinite(sliceImageWidth)) settings.sliceImageWidth = Math.max(100, parseInt(sliceImageWidth));
if (sliceImageAspectRatio) settings.sliceImageAspectRatio = sliceImageAspectRatio;
if (xhsPreviewWidth !== undefined && Number.isFinite(xhsPreviewWidth)) {
settings.xhsPreviewWidth = Math.max(100, parseInt(xhsPreviewWidth));
}
settings.getExpiredDate();
settings.isLoaded = true;
}
public static allSettings() {
const settings = NMPSettings.getInstance();
return {
'defaultStyle': settings.defaultStyle,
'defaultHighlight': settings.defaultHighlight,
'showStyleUI': settings.showStyleUI,
'linkStyle': settings.linkStyle,
'embedStyle': settings.embedStyle,
'lineNumber': settings.lineNumber,
'authKey': settings.authKey,
'wxInfo': settings.wxInfo,
'math': settings.math,
'useCustomCss': settings.useCustomCss,
'baseCSS': settings.baseCSS,
'watermark': settings.watermark,
'useFigcaption': settings.useFigcaption,
'customCSSNote': settings.customCSSNote,
'excalidrawToPNG': settings.excalidrawToPNG,
'expertSettingsNote': settings.expertSettingsNote,
'ignoreEmptyLine': settings.enableEmptyLine,
'needOpenComment': settings.needOpenComment,
'enableMarkdownImageToWikilink': settings.enableMarkdownImageToWikilink,
'galleryPrePath': settings.galleryPrePath,
'galleryNumPic': settings.galleryNumPic,
'defaultCoverPic': settings.defaultCoverPic,
'ignoreFrontmatterImage': settings.ignoreFrontmatterImage,
'batchPublishPresets': settings.batchPublishPresets,
'sliceImageSavePath': settings.sliceImageSavePath,
'sliceImageWidth': settings.sliceImageWidth,
'sliceImageAspectRatio': settings.sliceImageAspectRatio,
'xhsPreviewWidth': settings.xhsPreviewWidth,
}
}
getExpiredDate() {
if (this.authKey.length == 0) return;
wxKeyInfo(this.authKey).then((res) => {
if (res.status == 200) {
if (res.json.vip) {
this.isVip = true;
}
this.expireat = new Date(res.json.expireat);
}
})
}
isAuthKeyVaild() {
if (this.authKey.length == 0) return false;
if (this.isVip) return true;
if (this.expireat == null) return false;
return this.expireat > new Date();
}
}