update at 2025-10-16 18:10:27

This commit is contained in:
douboer
2025-10-16 18:10:27 +08:00
parent 411b7bbdb4
commit 8d40fbb01f
10 changed files with 1030 additions and 29 deletions

View File

@@ -1,4 +1,16 @@
[ [
{
"name": "小红书哲学风2",
"className": "xhs-philosophy2",
"desc": "项飙访谈风格,大号标题+序号章节+引号装饰,适合深度思辨文章",
"author": "gavin"
},
{
"name": "小红书哲学风",
"className": "xhs-philosophy",
"desc": "适合哲学思辨类文章的现代排版风格,具有小红书平台特色",
"author": "gavin"
},
{ {
"name": "微信专业版", "name": "微信专业版",
"className": "wx-mp-pro", "className": "wx-mp-pro",

View File

@@ -0,0 +1,386 @@
/* xhs-philosophy.css
* 小红书哲学类文章主题样式
* 设计理念:
* - 现代简洁的排版风格
* - 适合哲学、思辨类长文阅读
* - 突出引用和重点内容
* - 舒适的阅读体验
* 特色:
* - 大标题设计,层次分明
* - 特色引用样式,带引号装饰
* - 适合小红书平台的视觉风格
*/
.note2any {
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
font-size: 17px;
line-height: 1.8;
color: #2c2c2c;
background: #ffffff;
margin: 0;
padding: 20px;
max-width: 750px;
margin: 0 auto;
}
/* 段落 */
.note2any p {
margin: 1.5em 0;
letter-spacing: 0.5px;
text-align: justify;
color: #333333;
}
/* 标题层级设计 */
.note2any h1,
.note2any h2,
.note2any h3,
.note2any h4,
.note2any h5,
.note2any h6 {
margin: 2.5em 0 1.2em;
line-height: 1.3;
color: #1a1a1a;
font-weight: 700;
letter-spacing: 1px;
}
/* H1主标题 - 大号粗体 */
.note2any h1 {
font-size: 32px;
font-weight: 800;
margin: 1.5em 0 1em;
text-align: center;
position: relative;
padding: 0 20px;
}
.note2any h1::before {
content: "";
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 3px;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
border-radius: 2px;
}
/* H2章节标题 - 带数字序号 */
.note2any h2 {
font-size: 24px;
font-weight: 800;
position: relative;
padding: 15px 0 15px 60px;
margin: 2em 0 1.5em;
counter-increment: section;
}
.note2any h2::before {
content: counter(section, decimal);
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: 40px;
background: #2c2c2c;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: 700;
}
/* H3小节标题 */
.note2any h3 {
font-size: 20px;
font-weight: 700;
border-left: 4px solid #ff6b6b;
padding-left: 15px;
margin: 2em 0 1em;
}
/* H4-H6次级标题 */
.note2any h4 {
font-size: 18px;
font-weight: 600;
color: #444444;
}
.note2any h5 {
font-size: 16px;
font-weight: 600;
color: #555555;
}
.note2any h6 {
font-size: 15px;
font-weight: 600;
color: #666666;
}
/* 初始化计数器 */
.note2any {
counter-reset: section;
}
/* 引用样式 - 仿小红书风格 */
.note2any blockquote {
position: relative;
margin: 2em 0;
padding: 25px 30px 25px 60px;
background: #f8f9fa;
border: none;
border-radius: 12px;
border-left: 5px solid #4ecdc4;
font-size: 16px;
line-height: 1.7;
color: #2c2c2c;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.note2any blockquote::before {
content: "\201C";
position: absolute;
left: 15px;
top: 10px;
font-size: 40px;
color: #4ecdc4;
font-family: Georgia, serif;
font-weight: bold;
line-height: 1;
}
.note2any blockquote::after {
content: "\201D";
position: absolute;
right: 15px;
bottom: 5px;
font-size: 40px;
color: #4ecdc4;
font-family: Georgia, serif;
font-weight: bold;
line-height: 1;
}
.note2any blockquote p {
margin: 0.8em 0;
font-style: normal;
}
/* 加粗文本 */
.note2any strong,
.note2any b {
font-weight: 700;
color: #1a1a1a;
background: linear-gradient(180deg, transparent 60%, #fff2cc 60%);
padding: 2px 4px;
border-radius: 3px;
}
/* 斜体 */
.note2any em,
.note2any i {
font-style: italic;
color: #666666;
}
/* 列表样式 */
.note2any ul,
.note2any ol {
margin: 1.5em 0;
padding-left: 2em;
}
.note2any ul li {
list-style: none;
position: relative;
margin: 0.8em 0;
padding-left: 1.5em;
}
.note2any ul li::before {
content: "▪";
position: absolute;
left: 0;
color: #4ecdc4;
font-size: 18px;
font-weight: bold;
}
.note2any ol li {
margin: 0.8em 0;
padding-left: 0.5em;
}
/* 分隔线 */
.note2any hr {
border: none;
height: 2px;
background: linear-gradient(90deg, transparent, #e0e0e0, transparent);
margin: 3em 0;
}
/* 代码样式 */
.note2any code {
background: #f1f3f4;
color: #d73a49;
padding: 3px 6px;
border-radius: 4px;
font-family: "SF Mono", "Monaco", "Inconsolata", "Fira Code", "Fira Mono", "Droid Sans Mono", "Source Code Pro", monospace;
font-size: 0.9em;
}
.note2any pre {
background: #f8f8f8;
border: 1px solid #e1e4e8;
border-radius: 8px;
padding: 20px;
margin: 2em 0;
overflow-x: auto;
line-height: 1.5;
}
.note2any pre code {
background: none;
color: #24292e;
padding: 0;
border-radius: 0;
font-size: 14px;
}
/* 表格样式 */
.note2any table {
width: 100%;
border-collapse: collapse;
margin: 2em 0;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.note2any th,
.note2any td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #e1e4e8;
}
.note2any th {
background: #f6f8fa;
font-weight: 600;
color: #24292e;
}
.note2any tr:hover {
background: #f6f8fa;
}
/* 图片样式 */
.note2any img {
max-width: 100%;
height: auto;
border-radius: 8px;
margin: 1.5em 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
display: block;
margin-left: auto;
margin-right: auto;
}
/* 链接样式 */
.note2any a {
color: #4ecdc4;
text-decoration: none;
border-bottom: 1px solid transparent;
transition: all 0.3s ease;
}
.note2any a:hover {
color: #ff6b6b;
border-bottom-color: #ff6b6b;
}
/* 高亮标记 */
.note2any mark {
background: linear-gradient(180deg, transparent 50%, #ffeb3b 50%);
color: #2c2c2c;
padding: 2px 4px;
border-radius: 3px;
}
/* 删除线 */
.note2any del,
.note2any s {
color: #999999;
text-decoration: line-through;
}
/* 特殊样式:次仁群宗风格的标题 */
.note2any .philosophy-title {
font-size: 28px;
font-weight: 800;
text-align: center;
margin: 2em 0 1.5em;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 12px;
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}
/* 特殊引用:专家观点 */
.note2any .expert-quote {
position: relative;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
padding: 25px 30px;
border-radius: 15px;
margin: 2em 0;
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}
.note2any .expert-quote::before {
content: "专家观点";
position: absolute;
top: -12px;
left: 20px;
background: #2c2c2c;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
}
/* 响应式设计 */
@media (max-width: 768px) {
.note2any {
padding: 15px;
font-size: 16px;
}
.note2any h1 {
font-size: 28px;
}
.note2any h2 {
font-size: 22px;
padding-left: 50px;
}
.note2any h2::before {
width: 35px;
height: 35px;
font-size: 16px;
}
.note2any blockquote {
padding: 20px 25px 20px 50px;
}
}

View File

@@ -0,0 +1,467 @@
/* xhs-philosophy2.css
* 小红书哲学思辨类文章主题 v2
* 设计灵感:项飙、哲学对话访谈风格
* 特点:
* - 大号标题,强烈视觉冲击
* - 带序号的章节设计(❶❷❸...
* - 引用块带引号装饰
* - 灰色调背景,适合长文阅读
* - 现代简约,适合小红书平台
*/
.note2any {
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
font-size: 16px;
line-height: 1.75;
color: #1a1a1a;
background: #f5f5f5;
margin: 0;
padding: 20px;
max-width: 750px;
margin: 0 auto;
}
/* 段落 */
.note2any p {
margin: 1.2em 0;
letter-spacing: 0.3px;
text-align: justify;
color: #2c2c2c;
line-height: 1.8;
}
/* 标题通用样式 */
.note2any h1,
.note2any h2,
.note2any h3,
.note2any h4,
.note2any h5,
.note2any h6 {
margin: 2em 0 1em;
line-height: 1.3;
color: #000000;
font-weight: 800;
letter-spacing: 0.5px;
}
/* H1超大标题 - 主标题 */
.note2any h1 {
font-size: 42px;
font-weight: 900;
margin: 1em 0 0.8em;
line-height: 1.2;
letter-spacing: 1px;
word-break: keep-all;
}
/* H2带数字序号的章节标题 */
.note2any h2 {
font-size: 28px;
font-weight: 900;
position: relative;
padding: 12px 0 12px 0;
margin: 2em 0 1.2em;
background: #ffffff;
border-radius: 8px;
padding: 20px 24px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
counter-increment: section;
}
/* H2序号样式 - 使用圆形数字 */
.note2any h2::before {
content: counter(section) " ";
display: inline-block;
width: 36px;
height: 36px;
line-height: 36px;
text-align: center;
background: #000000;
color: white;
border-radius: 50%;
font-size: 18px;
font-weight: 700;
margin-right: 12px;
vertical-align: middle;
}
/* H3小节标题 */
.note2any h3 {
font-size: 22px;
font-weight: 700;
color: #1a1a1a;
padding-left: 16px;
border-left: 4px solid #000000;
margin: 1.8em 0 1em;
}
/* H4-H6次级标题 */
.note2any h4 {
font-size: 18px;
font-weight: 600;
color: #2c2c2c;
}
.note2any h5 {
font-size: 16px;
font-weight: 600;
color: #3c3c3c;
}
.note2any h6 {
font-size: 15px;
font-weight: 600;
color: #4c4c4c;
}
/* 初始化计数器 */
.note2any {
counter-reset: section;
}
/* 引用样式 - 带引号装饰 */
.note2any blockquote {
position: relative;
margin: 2em 0;
padding: 24px 30px 24px 70px;
background: #ffffff;
border: none;
border-left: 5px solid #000000;
font-size: 15px;
line-height: 1.75;
color: #2c2c2c;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
border-radius: 4px;
}
/* 左上引号 */
.note2any blockquote::before {
content: "\201C";
position: absolute;
left: 20px;
top: 15px;
font-size: 48px;
color: #000000;
font-family: Georgia, serif;
font-weight: bold;
line-height: 1;
opacity: 0.3;
}
/* 右下引号 */
.note2any blockquote::after {
content: "\201D";
position: absolute;
right: 20px;
bottom: 10px;
font-size: 48px;
color: #000000;
font-family: Georgia, serif;
font-weight: bold;
line-height: 1;
opacity: 0.3;
}
.note2any blockquote p {
margin: 0.8em 0;
font-style: normal;
}
.note2any blockquote p:first-child {
margin-top: 0;
}
.note2any blockquote p:last-child {
margin-bottom: 0;
}
/* 加粗文本 - 黑色高亮 */
.note2any strong,
.note2any b {
font-weight: 700;
color: #000000;
}
/* 斜体 */
.note2any em,
.note2any i {
font-style: italic;
color: #4c4c4c;
}
/* 列表样式 */
.note2any ul,
.note2any ol {
margin: 1.5em 0;
padding-left: 2em;
}
.note2any ul li {
list-style: none;
position: relative;
margin: 0.8em 0;
padding-left: 1.5em;
}
.note2any ul li::before {
content: "▸";
position: absolute;
left: 0;
color: #000000;
font-size: 16px;
font-weight: bold;
}
.note2any ol li {
margin: 0.8em 0;
padding-left: 0.5em;
}
/* 分隔线 */
.note2any hr {
border: none;
height: 1px;
background: #d0d0d0;
margin: 3em 0;
}
/* 代码样式 */
.note2any code {
background: #e8e8e8;
color: #000000;
padding: 3px 6px;
border-radius: 3px;
font-family: "SF Mono", "Monaco", "Inconsolata", "Fira Code", monospace;
font-size: 0.9em;
font-weight: 500;
}
.note2any pre {
background: #ffffff;
border: 1px solid #d0d0d0;
border-radius: 6px;
padding: 20px;
margin: 2em 0;
overflow-x: auto;
line-height: 1.5;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
.note2any pre code {
background: none;
color: #2c2c2c;
padding: 0;
border-radius: 0;
font-size: 14px;
}
/* 表格样式 */
.note2any table {
width: 100%;
border-collapse: collapse;
margin: 2em 0;
background: white;
border-radius: 6px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.note2any th,
.note2any td {
padding: 12px 16px;
text-align: left;
border-bottom: 1px solid #e0e0e0;
}
.note2any th {
background: #f5f5f5;
font-weight: 600;
color: #000000;
}
.note2any tr:last-child td {
border-bottom: none;
}
.note2any tr:hover {
background: #fafafa;
}
/* 图片样式 */
.note2any img {
max-width: 100%;
height: auto;
border-radius: 6px;
margin: 2em 0;
display: block;
margin-left: auto;
margin-right: auto;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
/* 链接样式 */
.note2any a {
color: #000000;
text-decoration: none;
border-bottom: 2px solid #000000;
transition: all 0.3s ease;
font-weight: 500;
}
.note2any a:hover {
color: #4c4c4c;
border-bottom-color: #4c4c4c;
}
/* 高亮标记 */
.note2any mark {
background: #ffeb3b;
color: #000000;
padding: 2px 4px;
border-radius: 2px;
font-weight: 500;
}
/* 删除线 */
.note2any del,
.note2any s {
color: #888888;
text-decoration: line-through;
}
/* 特殊样式:访谈对话框 */
.note2any .interview-question {
background: #ffffff;
border-left: 6px solid #000000;
padding: 16px 20px;
margin: 2em 0;
border-radius: 4px;
box-shadow: 0 2px 6px rgba(0,0,0,0.06);
}
.note2any .interview-question::before {
content: "次仁群宗:";
display: block;
font-weight: 700;
color: #000000;
margin-bottom: 0.5em;
font-size: 14px;
}
.note2any .interview-answer {
background: #f8f8f8;
padding: 16px 20px;
margin: 1em 0;
border-radius: 4px;
border-left: 4px solid #666666;
}
.note2any .interview-answer::before {
content: "项飙:";
display: block;
font-weight: 700;
color: #000000;
margin-bottom: 0.5em;
font-size: 14px;
}
/* 特殊标注:观点卡片 */
.note2any .viewpoint-card {
position: relative;
background: linear-gradient(135deg, #1a1a1a 0%, #2c2c2c 100%);
color: white;
padding: 30px;
border-radius: 8px;
margin: 2.5em 0;
box-shadow: 0 8px 20px rgba(0,0,0,0.2);
}
.note2any .viewpoint-card::before {
content: "VIEWPOINT";
position: absolute;
top: -12px;
right: 20px;
background: #000000;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
letter-spacing: 1px;
}
/* 带三角形装饰的引用块 */
.note2any .quote-triangle {
position: relative;
background: #ffffff;
padding: 20px 25px;
margin: 2em 0;
border-radius: 6px;
box-shadow: 0 3px 10px rgba(0,0,0,0.1);
}
.note2any .quote-triangle::before {
content: "▶";
position: absolute;
left: -10px;
top: 20px;
color: #000000;
font-size: 20px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.note2any {
padding: 15px;
font-size: 15px;
}
.note2any h1 {
font-size: 32px;
}
.note2any h2 {
font-size: 24px;
padding: 16px 20px;
}
.note2any h2::before {
width: 32px;
height: 32px;
line-height: 32px;
font-size: 16px;
margin-right: 10px;
}
.note2any blockquote {
padding: 20px 25px 20px 60px;
}
.note2any blockquote::before,
.note2any blockquote::after {
font-size: 36px;
}
}
/* 确保在小红书平台的兼容性 */
.note2any * {
box-sizing: border-box;
}
/* 打印样式优化 */
@media print {
.note2any {
background: white;
color: black;
}
.note2any blockquote {
page-break-inside: avoid;
}
.note2any h1,
.note2any h2,
.note2any h3 {
page-break-after: avoid;
}
}

View File

@@ -11,28 +11,41 @@ export interface ProgressOptions {
autoHide?: boolean; autoHide?: boolean;
} }
export class ProgressIndicator { class GlobalProgressManager {
private notice: Notice | null = null; private static instance: GlobalProgressManager | null = null;
private currentNotice: Notice | null = null;
private startTime: number = 0; private startTime: number = 0;
start(message: string, options: ProgressOptions = {}): void { static getInstance(): GlobalProgressManager {
this.startTime = Date.now(); if (!GlobalProgressManager.instance) {
const { duration = 0 } = options; GlobalProgressManager.instance = new GlobalProgressManager();
}
return GlobalProgressManager.instance;
}
this.notice = new Notice(`🔄 ${message}...`, duration); start(message: string, options: ProgressOptions = {}): void {
// 如果已有通知,先关闭
if (this.currentNotice) {
this.currentNotice.hide();
}
this.startTime = Date.now();
const { duration = 10000 } = options; // 默认10秒自动消失防止卡住
this.currentNotice = new Notice(`🔄 ${message}...`, duration);
} }
update(message: string, progress?: number): void { update(message: string, progress?: number): void {
if (!this.notice) return; if (!this.currentNotice) return;
const progressText = progress ? ` (${Math.round(progress)}%)` : ''; const progressText = progress !== undefined ? ` (${Math.round(progress)}%)` : '';
this.notice.setMessage(`🔄 ${message}${progressText}...`); this.currentNotice.setMessage(`🔄 ${message}${progressText}...`);
} }
finish(message: string, success: boolean = true): void { finish(message: string, success: boolean = true): void {
if (this.notice) { if (this.currentNotice) {
this.notice.hide(); this.currentNotice.hide();
this.notice = null; this.currentNotice = null;
} }
const duration = Date.now() - this.startTime; const duration = Date.now() - this.startTime;
@@ -43,17 +56,49 @@ export class ProgressIndicator {
} }
error(message: string): void { error(message: string): void {
this.finish(message, false); if (this.currentNotice) {
this.currentNotice.hide();
this.currentNotice = null;
}
const duration = Date.now() - this.startTime;
const durationText = duration > 1000 ? ` (${(duration / 1000).toFixed(1)}s)` : '';
new Notice(`${message}${durationText}`, 5000);
} }
hide(): void { hide(): void {
if (this.notice) { if (this.currentNotice) {
this.notice.hide(); this.currentNotice.hide();
this.notice = null; this.currentNotice = null;
} }
} }
} }
export class ProgressIndicator {
private manager = GlobalProgressManager.getInstance();
start(message: string, options: ProgressOptions = {}): void {
this.manager.start(message, options);
}
update(message: string, progress?: number): void {
this.manager.update(message, progress);
}
finish(message: string, success: boolean = true): void {
this.manager.finish(message, success);
}
error(message: string): void {
this.manager.error(message);
}
hide(): void {
this.manager.hide();
}
}
export class BatchProgressIndicator { export class BatchProgressIndicator {
private currentProgress: ProgressIndicator | null = null; private currentProgress: ProgressIndicator | null = null;
private totalItems: number = 0; private totalItems: number = 0;

View File

@@ -204,6 +204,14 @@ export class PreviewManager {
this.showWechat(); this.showWechat();
this.hideXiaohongshu(); this.hideXiaohongshu();
// 同步主题设置
if (this.wechatPreview) {
this.wechatPreview.updateStyleAndHighlight(
this.settings.defaultStyle,
this.settings.defaultHighlight
);
}
// 如果有当前文件且是从其他平台切换过来,重新渲染 // 如果有当前文件且是从其他平台切换过来,重新渲染
if (this.currentFile && previousPlatform !== 'wechat') { if (this.currentFile && previousPlatform !== 'wechat') {
await this.renderForWechat(this.currentFile); await this.renderForWechat(this.currentFile);
@@ -213,6 +221,14 @@ export class PreviewManager {
this.showXiaohongshu(); this.showXiaohongshu();
this.hideWechat(); this.hideWechat();
// 同步主题设置
if (this.xhsPreview) {
this.xhsPreview.updateStyleAndHighlight(
this.settings.defaultStyle,
this.settings.defaultHighlight
);
}
// 如果有当前文件且是从其他平台切换过来,重新渲染 // 如果有当前文件且是从其他平台切换过来,重新渲染
if (this.currentFile && previousPlatform !== 'xiaohongshu') { if (this.currentFile && previousPlatform !== 'xiaohongshu') {
await this.renderForXiaohongshu(this.currentFile); await this.renderForXiaohongshu(this.currentFile);

View File

@@ -106,9 +106,6 @@ export class PreviewView extends ItemView {
async onOpen(): Promise<void> { async onOpen(): Promise<void> {
console.log('[PreviewView] 视图打开 layoutReady=', this.app.workspace.layoutReady); console.log('[PreviewView] 视图打开 layoutReady=', this.app.workspace.layoutReady);
const progress = new ProgressIndicator();
progress.start('初始化预览视图');
try { try {
// 不在未完成 layoutReady 时做重初始化,改为延迟 // 不在未完成 layoutReady 时做重初始化,改为延迟
if (!this.app.workspace.layoutReady) { if (!this.app.workspace.layoutReady) {
@@ -121,15 +118,14 @@ export class PreviewView extends ItemView {
return; return;
} }
await this.performInitialization(); await this.performInitialization();
progress.finish('预览视图初始化完成');
} catch (error) { } catch (error) {
progress.error('预览视图初始化失败');
ErrorHandler.handle(error as Error, 'PreviewView.onOpen'); ErrorHandler.handle(error as Error, 'PreviewView.onOpen');
} }
} }
private async performInitialization(): Promise<void> { private async performInitialization(): Promise<void> {
const progress = new ProgressIndicator(); const progress = new ProgressIndicator();
progress.start('初始化预览视图');
try { try {
const start = performance.now(); const start = performance.now();
@@ -162,10 +158,10 @@ export class PreviewView extends ItemView {
} }
console.log('[PreviewView] 初始化耗时(ms):', (performance.now() - start).toFixed(1)); console.log('[PreviewView] 初始化耗时(ms):', (performance.now() - start).toFixed(1));
progress.finish('视图初始化完成'); progress.finish('预览视图初始化完成');
uevent('open'); uevent('open');
} catch (error) { } catch (error) {
progress.error('视图初始化失败'); progress.error('预览视图初始化失败');
ErrorHandler.handle(error as Error, 'PreviewView.performInitialization'); ErrorHandler.handle(error as Error, 'PreviewView.performInitialization');
console.error('[PreviewView] 初始化失败', error); console.error('[PreviewView] 初始化失败', error);
this.showError('预览视图初始化失败,请检查插件设置'); this.showError('预览视图初始化失败,请检查插件设置');

View File

@@ -71,9 +71,7 @@ export class WechatPreview {
this.board = this.container.createDiv({ cls: 'wechat-board' }); this.board = this.container.createDiv({ cls: 'wechat-board' });
this.buildAccountRow(); this.buildAccountRow();
this.buildStyleRow();
//this.buildCoverRow();
//this.buildStyleRow();
this.contentCell = this.createCell('content'); this.contentCell = this.createCell('content');
this.contentCell.addClass('wechat-cell-content'); this.contentCell.addClass('wechat-cell-content');
@@ -203,7 +201,14 @@ export class WechatPreview {
const selectBtn = styleSelectCell.createEl('select', { cls: 'style-select wechat-style-select' }) as HTMLSelectElement; const selectBtn = styleSelectCell.createEl('select', { cls: 'style-select wechat-style-select' }) as HTMLSelectElement;
selectBtn.onchange = async () => { selectBtn.onchange = async () => {
this.currentTheme = selectBtn.value; this.currentTheme = selectBtn.value;
// 更新全局设置
this.settings.defaultStyle = selectBtn.value;
this.render.updateStyle(selectBtn.value); this.render.updateStyle(selectBtn.value);
// 保存设置
const plugin = (this.app as any)?.plugins?.getPlugin?.('note2any');
if (plugin?.saveSettings) {
await plugin.saveSettings();
}
}; };
for (let s of this.assetsManager.themes) { for (let s of this.assetsManager.themes) {
@@ -221,7 +226,14 @@ export class WechatPreview {
const highlightStyleBtn = highlightSelectCell.createEl('select', { cls: 'style-select wechat-style-select' }) as HTMLSelectElement; const highlightStyleBtn = highlightSelectCell.createEl('select', { cls: 'style-select wechat-style-select' }) as HTMLSelectElement;
highlightStyleBtn.onchange = async () => { highlightStyleBtn.onchange = async () => {
this.currentHighlight = highlightStyleBtn.value; this.currentHighlight = highlightStyleBtn.value;
// 更新全局设置
this.settings.defaultHighlight = highlightStyleBtn.value;
this.render.updateHighLight(highlightStyleBtn.value); this.render.updateHighLight(highlightStyleBtn.value);
// 保存设置
const plugin = (this.app as any)?.plugins?.getPlugin?.('note2any');
if (plugin?.saveSettings) {
await plugin.saveSettings();
}
}; };
const highlights = this.assetsManager.highlights; const highlights = this.assetsManager.highlights;

View File

@@ -37,6 +37,8 @@ export class XiaohongshuPreview {
templateSelect!: HTMLSelectElement; templateSelect!: HTMLSelectElement;
fontSizeInput!: HTMLInputElement; fontSizeInput!: HTMLInputElement;
previewWidthSelect!: HTMLSelectElement; previewWidthSelect!: HTMLSelectElement;
themeSelect!: HTMLSelectElement;
highlightSelect!: HTMLSelectElement;
pageContainer!: HTMLDivElement; pageContainer!: HTMLDivElement;
pageNumberInput!: HTMLInputElement; pageNumberInput!: HTMLInputElement;
@@ -132,6 +134,54 @@ export class XiaohongshuPreview {
const increaseBtn = fontSizeGroup.createEl('button', { text: '', cls: 'font-size-btn' }); const increaseBtn = fontSizeGroup.createEl('button', { text: '', cls: 'font-size-btn' });
increaseBtn.onclick = () => this.changeFontSize(1); increaseBtn.onclick = () => this.changeFontSize(1);
// 主题选择器
const themeCard = this.createGridCard(board, 'xhs-area-theme');
const themeLabel = themeCard.createDiv({ cls: 'xhs-label', text: '主题' });
this.themeSelect = themeCard.createEl('select', { cls: 'xhs-select' });
this.themeSelect.onchange = async () => {
// 更新全局设置
this.settings.defaultStyle = this.themeSelect.value;
this.applyThemeCSS();
await this.repaginateAndRender();
// 保存设置
const plugin = (this.app as any)?.plugins?.getPlugin?.('note2any');
if (plugin?.saveSettings) {
await plugin.saveSettings();
}
};
// 填充主题选项
for (let theme of this.assetsManager.themes) {
const option = this.themeSelect.createEl('option');
option.value = theme.className;
option.text = theme.name;
option.selected = theme.className === this.settings.defaultStyle;
}
// 高亮选择器
const highlightCard = this.createGridCard(board, 'xhs-area-highlight');
const highlightLabel = highlightCard.createDiv({ cls: 'xhs-label', text: '代码高亮' });
this.highlightSelect = highlightCard.createEl('select', { cls: 'xhs-select' });
this.highlightSelect.onchange = async () => {
// 更新全局设置
this.settings.defaultHighlight = this.highlightSelect.value;
this.applyThemeCSS();
await this.repaginateAndRender();
// 保存设置
const plugin = (this.app as any)?.plugins?.getPlugin?.('note2any');
if (plugin?.saveSettings) {
await plugin.saveSettings();
}
};
// 填充高亮选项
for (let highlight of this.assetsManager.highlights) {
const option = this.highlightSelect.createEl('option');
option.value = highlight.url;
option.text = highlight.name;
option.selected = highlight.url === this.settings.defaultHighlight;
}
const contentWrapper = board.createDiv({ cls: 'xhs-area-content' }); const contentWrapper = board.createDiv({ cls: 'xhs-area-content' });
this.pageContainer = contentWrapper.createDiv({ cls: 'xhs-page-container' }); this.pageContainer = contentWrapper.createDiv({ cls: 'xhs-page-container' });
@@ -547,4 +597,17 @@ export class XiaohongshuPreview {
document.body.removeChild(tempContainer); document.body.removeChild(tempContainer);
} }
} }
/**
* 更新主题和高亮选择器的值
*/
updateStyleAndHighlight(theme: string, highlight: string): void {
if (this.themeSelect) {
this.themeSelect.value = theme;
}
if (this.highlightSelect) {
this.highlightSelect.value = highlight;
}
this.applyThemeCSS();
}
} }

View File

@@ -591,7 +591,7 @@ label:hover { color: var(--c-primary); }
grid-template-rows: auto auto auto 1fr auto; grid-template-rows: auto auto auto 1fr auto;
grid-template-areas: grid-template-areas:
"template template preview preview font font" "template template preview preview font font"
"content content content content content content" "theme theme highlight highlight highlight highlight"
"content content content content content content" "content content content content content content"
"content content content content content content" "content content content content content content"
"pagination pagination pagination slice slice slice"; "pagination pagination pagination slice slice slice";
@@ -629,7 +629,8 @@ label:hover { color: var(--c-primary); }
background: white; background: white;
font-size: 13px; font-size: 13px;
cursor: pointer; cursor: pointer;
max-width: 100px; min-width: 80px;
max-width: 140px;
transition: border-color 0.2s ease; transition: border-color 0.2s ease;
} }
@@ -683,6 +684,8 @@ label:hover { color: var(--c-primary); }
grid-area: font; grid-area: font;
flex-wrap: nowrap; flex-wrap: nowrap;
} }
.xhs-area-theme { grid-area: theme; }
.xhs-area-highlight { grid-area: highlight; }
.xhs-area-pagination { grid-area: pagination; justify-content: center; gap: 16px; } .xhs-area-pagination { grid-area: pagination; justify-content: center; gap: 16px; }
.xhs-area-slice { grid-area: slice; justify-content: center; gap: 16px; } .xhs-area-slice { grid-area: slice; justify-content: center; gap: 16px; }

View File

@@ -161,7 +161,9 @@ SOLVEobsidian控制台打印信息定位在哪里阻塞AI修复。
1. 全量扫描系统,从设计、结构、冗余度、优雅、可维护性方便,检查是否有优化的地方。 1. 全量扫描系统,从设计、结构、冗余度、优雅、可维护性方便,检查是否有优化的地方。
2. 后续在主题切换和使用上的独立性和便捷性。 2. 后续在主题切换和使用上的独立性和便捷性。统一样式。
统一CSS处理流程。
添加平台无关的基础样式。
## 思路 ## 思路
1. 网上图片模版让AI快速生成css themes主题。快速套用。‼ 1. 网上图片模版让AI快速生成css themes主题。快速套用。‼
@@ -169,4 +171,3 @@ SOLVEobsidian控制台打印信息定位在哪里阻塞AI修复。