update at 2025-10-08 17:32:31
This commit is contained in:
@@ -76,9 +76,7 @@ export class XiaohongshuWebAPI implements XiaohongshuAPI {
|
||||
private initializeWebview(): void {
|
||||
// 创建隐藏的webview元素
|
||||
this.webview = document.createElement('webview');
|
||||
this.webview.style.display = 'none';
|
||||
this.webview.style.width = '1200px';
|
||||
this.webview.style.height = '800px';
|
||||
this.webview.addClass('xhs-webview');
|
||||
|
||||
// 设置webview属性
|
||||
this.webview.setAttribute('nodeintegration', 'false');
|
||||
|
||||
@@ -67,20 +67,16 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
contentEl.empty();
|
||||
contentEl.addClass('xiaohongshu-login-modal');
|
||||
|
||||
// 设置对话框样式
|
||||
contentEl.style.width = '400px';
|
||||
contentEl.style.padding = '20px';
|
||||
|
||||
// 标题
|
||||
contentEl.createEl('h2', {
|
||||
text: '登录小红书',
|
||||
attr: { style: 'text-align: center; margin-bottom: 20px; color: #ff4757;' }
|
||||
cls: 'xhs-login-title'
|
||||
});
|
||||
|
||||
// 说明文字
|
||||
const descEl = contentEl.createEl('p', {
|
||||
text: '请使用手机号码和验证码登录小红书',
|
||||
attr: { style: 'text-align: center; color: #666; margin-bottom: 30px;' }
|
||||
cls: 'xhs-login-desc'
|
||||
});
|
||||
|
||||
// 手机号输入
|
||||
@@ -97,23 +93,16 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
});
|
||||
|
||||
// 设置输入框样式
|
||||
text.inputEl.style.width = '100%';
|
||||
text.inputEl.style.fontSize = '16px';
|
||||
text.inputEl.addClass('xhs-input-full');
|
||||
});
|
||||
|
||||
// 验证码输入和发送按钮
|
||||
const codeContainer = contentEl.createDiv({ cls: 'code-container' });
|
||||
codeContainer.style.display = 'flex';
|
||||
codeContainer.style.alignItems = 'center';
|
||||
codeContainer.style.gap = '10px';
|
||||
codeContainer.style.marginBottom = '20px';
|
||||
const codeContainer = contentEl.createDiv({ cls: 'xhs-code-container' });
|
||||
|
||||
const codeLabel = codeContainer.createDiv({ cls: 'setting-item-name' });
|
||||
const codeLabel = codeContainer.createDiv({ cls: 'setting-item-name xhs-code-label' });
|
||||
codeLabel.textContent = '验证码';
|
||||
codeLabel.style.minWidth = '80px';
|
||||
|
||||
const codeInputWrapper = codeContainer.createDiv();
|
||||
codeInputWrapper.style.flex = '1';
|
||||
const codeInputWrapper = codeContainer.createDiv({ cls: 'xhs-code-input-wrapper' });
|
||||
|
||||
new Setting(codeInputWrapper)
|
||||
.addText(text => {
|
||||
@@ -125,8 +114,7 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
this.updateLoginButtonState();
|
||||
});
|
||||
|
||||
text.inputEl.style.width = '100%';
|
||||
text.inputEl.style.fontSize = '16px';
|
||||
text.inputEl.addClass('xhs-input-full');
|
||||
text.inputEl.disabled = true; // 初始禁用
|
||||
|
||||
// 回车键登录
|
||||
@@ -142,22 +130,13 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
.setButtonText('发送验证码')
|
||||
.onClick(() => this.handleSendCode());
|
||||
|
||||
this.sendCodeButton.buttonEl.style.minWidth = '120px';
|
||||
this.sendCodeButton.buttonEl.style.marginLeft = '10px';
|
||||
this.sendCodeButton.buttonEl.addClass('xhs-send-code-btn');
|
||||
|
||||
// 状态显示区域
|
||||
this.statusDiv = contentEl.createDiv({ cls: 'status-message' });
|
||||
this.statusDiv.style.minHeight = '30px';
|
||||
this.statusDiv.style.marginBottom = '20px';
|
||||
this.statusDiv.style.textAlign = 'center';
|
||||
this.statusDiv.style.fontSize = '14px';
|
||||
this.statusDiv = contentEl.createDiv({ cls: 'xhs-status-message' });
|
||||
|
||||
// 按钮区域
|
||||
const buttonContainer = contentEl.createDiv({ cls: 'button-container' });
|
||||
buttonContainer.style.display = 'flex';
|
||||
buttonContainer.style.justifyContent = 'center';
|
||||
buttonContainer.style.gap = '15px';
|
||||
buttonContainer.style.marginTop = '20px';
|
||||
const buttonContainer = contentEl.createDiv({ cls: 'xhs-button-container' });
|
||||
|
||||
// 登录按钮
|
||||
this.loginButton = new ButtonComponent(buttonContainer)
|
||||
@@ -166,7 +145,7 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
.setDisabled(true)
|
||||
.onClick(() => this.handleLogin());
|
||||
|
||||
this.loginButton.buttonEl.style.minWidth = '100px';
|
||||
this.loginButton.buttonEl.addClass('xhs-login-btn');
|
||||
|
||||
// 取消按钮
|
||||
new ButtonComponent(buttonContainer)
|
||||
@@ -389,21 +368,7 @@ export class XiaohongshuLoginModal extends Modal {
|
||||
private showStatus(message: string, type: 'info' | 'success' | 'error' = 'info') {
|
||||
this.statusDiv.empty();
|
||||
|
||||
const messageEl = this.statusDiv.createSpan({ text: message });
|
||||
|
||||
// 设置不同类型的样式
|
||||
switch (type) {
|
||||
case 'success':
|
||||
messageEl.style.color = '#27ae60';
|
||||
break;
|
||||
case 'error':
|
||||
messageEl.style.color = '#e74c3c';
|
||||
break;
|
||||
case 'info':
|
||||
default:
|
||||
messageEl.style.color = '#3498db';
|
||||
break;
|
||||
}
|
||||
const messageEl = this.statusDiv.createSpan({ text: message, cls: type || 'info' });
|
||||
}
|
||||
|
||||
onClose() {
|
||||
|
||||
@@ -51,14 +51,13 @@ export class XiaohongshuPreviewView {
|
||||
*/
|
||||
build(): void {
|
||||
this.container.empty();
|
||||
this.container.style.cssText = 'display: flex; flex-direction: column; height: 100%; background: linear-gradient(135deg, #f5f7fa 0%, #e8eaf6 100%);';
|
||||
this.container.addClass('xhs-preview-container');
|
||||
|
||||
// 顶部工具栏
|
||||
this.buildTopToolbar();
|
||||
|
||||
// 页面容器
|
||||
this.pageContainer = this.container.createDiv({ cls: 'xhs-page-container' });
|
||||
this.pageContainer.style.cssText = 'flex: 1; overflow: auto; display: flex; justify-content: center; align-items: center; padding: 20px; background: radial-gradient(ellipse at top, rgba(255,255,255,0.1) 0%, transparent 70%);';
|
||||
|
||||
// 分页导航
|
||||
this.buildPageNavigation();
|
||||
@@ -72,32 +71,22 @@ export class XiaohongshuPreviewView {
|
||||
*/
|
||||
private buildTopToolbar(): void {
|
||||
this.topToolbar = this.container.createDiv({ cls: 'xhs-top-toolbar' });
|
||||
this.topToolbar.style.cssText = 'display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); border-bottom: 1px solid #e8eaed; box-shadow: 0 2px 4px rgba(0,0,0,0.04); flex-wrap: wrap;';
|
||||
|
||||
// 刷新按钮
|
||||
const refreshBtn = this.topToolbar.createEl('button', { text: '🔄 刷新' });
|
||||
refreshBtn.style.cssText = 'padding: 6px 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.2s ease; box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);';
|
||||
refreshBtn.onmouseenter = () => refreshBtn.style.transform = 'translateY(-1px)';
|
||||
refreshBtn.onmouseleave = () => refreshBtn.style.transform = 'translateY(0)';
|
||||
const refreshBtn = this.topToolbar.createEl('button', { text: '🔄 刷新', cls: 'toolbar-button purple-gradient' });
|
||||
refreshBtn.onclick = () => this.onRefresh();
|
||||
|
||||
// 发布按钮
|
||||
const publishBtn = this.topToolbar.createEl('button', { text: '📤 发布' });
|
||||
publishBtn.style.cssText = 'padding: 6px 14px; background: linear-gradient(135deg, #1e88e5 0%, #1565c0 100%); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.2s ease; box-shadow: 0 2px 6px rgba(30, 136, 229, 0.3);';
|
||||
publishBtn.onmouseenter = () => publishBtn.style.transform = 'translateY(-1px)';
|
||||
publishBtn.onmouseleave = () => publishBtn.style.transform = 'translateY(0)';
|
||||
const publishBtn = this.topToolbar.createEl('button', { text: '📤 发布', cls: 'toolbar-button' });
|
||||
publishBtn.onclick = () => this.onPublish();
|
||||
|
||||
// 分隔线
|
||||
const separator2 = this.topToolbar.createDiv({ cls: 'toolbar-separator' });
|
||||
separator2.style.cssText = 'width: 1px; height: 24px; background: #dadce0; margin: 0 4px;';
|
||||
|
||||
// 模板选择
|
||||
const templateLabel = this.topToolbar.createDiv({ cls: 'toolbar-label' });
|
||||
templateLabel.innerText = '模板';
|
||||
templateLabel.style.cssText = 'font-size: 11px; color: #5f6368; font-weight: 500; white-space: nowrap;';
|
||||
this.templateSelect = this.topToolbar.createEl('select');
|
||||
this.templateSelect.style.cssText = 'padding: 4px 8px; border: 1px solid #dadce0; border-radius: 4px; background: white; font-size: 11px; cursor: pointer; transition: border-color 0.2s ease;';
|
||||
this.templateSelect = this.topToolbar.createEl('select', { cls: 'xhs-select' });
|
||||
['默认模板', '简约模板', '杂志模板'].forEach(name => {
|
||||
const option = this.templateSelect.createEl('option');
|
||||
option.value = name;
|
||||
@@ -107,9 +96,7 @@ export class XiaohongshuPreviewView {
|
||||
// 主题选择
|
||||
const themeLabel = this.topToolbar.createDiv({ cls: 'toolbar-label' });
|
||||
themeLabel.innerText = '主题';
|
||||
themeLabel.style.cssText = 'font-size: 11px; color: #5f6368; font-weight: 500; white-space: nowrap;';
|
||||
this.themeSelect = this.topToolbar.createEl('select');
|
||||
this.themeSelect.style.cssText = 'padding: 4px 8px; border: 1px solid #dadce0; border-radius: 4px; background: white; font-size: 11px; cursor: pointer; transition: border-color 0.2s ease;';
|
||||
this.themeSelect = this.topToolbar.createEl('select', { cls: 'xhs-select' });
|
||||
const themes = this.assetsManager.themes;
|
||||
themes.forEach(theme => {
|
||||
const option = this.themeSelect.createEl('option');
|
||||
@@ -122,9 +109,7 @@ export class XiaohongshuPreviewView {
|
||||
// 字体选择
|
||||
const fontLabel = this.topToolbar.createDiv({ cls: 'toolbar-label' });
|
||||
fontLabel.innerText = '字体';
|
||||
fontLabel.style.cssText = 'font-size: 11px; color: #5f6368; font-weight: 500; white-space: nowrap;';
|
||||
this.fontSelect = this.topToolbar.createEl('select');
|
||||
this.fontSelect.style.cssText = 'padding: 4px 8px; border: 1px solid #dadce0; border-radius: 4px; background: white; font-size: 11px; cursor: pointer; transition: border-color 0.2s ease;';
|
||||
this.fontSelect = this.topToolbar.createEl('select', { cls: 'xhs-select' });
|
||||
['系统默认', '宋体', '黑体', '楷体', '仿宋'].forEach(name => {
|
||||
const option = this.fontSelect.createEl('option');
|
||||
option.value = name;
|
||||
@@ -135,23 +120,14 @@ export class XiaohongshuPreviewView {
|
||||
// 字号控制
|
||||
const fontSizeLabel = this.topToolbar.createDiv({ cls: 'toolbar-label' });
|
||||
fontSizeLabel.innerText = '字号';
|
||||
fontSizeLabel.style.cssText = 'font-size: 11px; color: #5f6368; font-weight: 500; white-space: nowrap;';
|
||||
const fontSizeGroup = this.topToolbar.createDiv({ cls: 'font-size-group' });
|
||||
fontSizeGroup.style.cssText = 'display: flex; align-items: center; gap: 6px; background: white; border: 1px solid #dadce0; border-radius: 4px; padding: 2px;';
|
||||
|
||||
const decreaseBtn = fontSizeGroup.createEl('button', { text: '−' });
|
||||
decreaseBtn.style.cssText = 'width: 24px; height: 24px; border: none; background: transparent; border-radius: 3px; cursor: pointer; font-size: 16px; color: #5f6368; transition: background 0.2s ease;';
|
||||
decreaseBtn.onmouseenter = () => decreaseBtn.style.background = '#f1f3f4';
|
||||
decreaseBtn.onmouseleave = () => decreaseBtn.style.background = 'transparent';
|
||||
const decreaseBtn = fontSizeGroup.createEl('button', { text: '−', cls: 'font-size-btn' });
|
||||
decreaseBtn.onclick = () => this.changeFontSize(-1);
|
||||
|
||||
this.fontSizeDisplay = fontSizeGroup.createEl('span', { text: '16' });
|
||||
this.fontSizeDisplay.style.cssText = 'min-width: 24px; text-align: center; font-size: 12px; color: #202124; font-weight: 500;';
|
||||
this.fontSizeDisplay = fontSizeGroup.createEl('span', { text: '16', cls: 'font-size-display' });
|
||||
|
||||
const increaseBtn = fontSizeGroup.createEl('button', { text: '+' });
|
||||
increaseBtn.style.cssText = 'width: 24px; height: 24px; border: none; background: transparent; border-radius: 3px; cursor: pointer; font-size: 14px; color: #5f6368; transition: background 0.2s ease;';
|
||||
increaseBtn.onmouseenter = () => increaseBtn.style.background = '#f1f3f4';
|
||||
increaseBtn.onmouseleave = () => increaseBtn.style.background = 'transparent';
|
||||
const increaseBtn = fontSizeGroup.createEl('button', { text: '+', cls: 'font-size-btn' });
|
||||
increaseBtn.onclick = () => this.changeFontSize(1);
|
||||
}
|
||||
|
||||
@@ -160,37 +136,13 @@ export class XiaohongshuPreviewView {
|
||||
*/
|
||||
private buildPageNavigation(): void {
|
||||
this.pageNavigation = this.container.createDiv({ cls: 'xhs-page-navigation' });
|
||||
this.pageNavigation.style.cssText = 'display: flex; justify-content: center; align-items: center; gap: 16px; padding: 12px; background: white; border-bottom: 1px solid #e8eaed;';
|
||||
|
||||
const prevBtn = this.pageNavigation.createEl('button', { text: '‹' });
|
||||
prevBtn.style.cssText = 'width: 36px; height: 36px; border: 1px solid #dadce0; border-radius: 50%; cursor: pointer; font-size: 20px; background: white; color: #5f6368; transition: all 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.08);';
|
||||
prevBtn.onmouseenter = () => {
|
||||
prevBtn.style.background = 'linear-gradient(135deg, #1e88e5 0%, #1565c0 100%)';
|
||||
prevBtn.style.color = 'white';
|
||||
prevBtn.style.borderColor = '#1e88e5';
|
||||
};
|
||||
prevBtn.onmouseleave = () => {
|
||||
prevBtn.style.background = 'white';
|
||||
prevBtn.style.color = '#5f6368';
|
||||
prevBtn.style.borderColor = '#dadce0';
|
||||
};
|
||||
const prevBtn = this.pageNavigation.createEl('button', { text: '‹', cls: 'xhs-nav-btn' });
|
||||
prevBtn.onclick = () => this.previousPage();
|
||||
|
||||
this.pageNumberDisplay = this.pageNavigation.createEl('span', { text: '1/1' });
|
||||
this.pageNumberDisplay.style.cssText = 'font-size: 14px; min-width: 50px; text-align: center; color: #202124; font-weight: 500;';
|
||||
this.pageNumberDisplay = this.pageNavigation.createEl('span', { text: '1/1', cls: 'xhs-page-number' });
|
||||
|
||||
const nextBtn = this.pageNavigation.createEl('button', { text: '›' });
|
||||
nextBtn.style.cssText = 'width: 36px; height: 36px; border: 1px solid #dadce0; border-radius: 50%; cursor: pointer; font-size: 20px; background: white; color: #5f6368; transition: all 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.08);';
|
||||
nextBtn.onmouseenter = () => {
|
||||
nextBtn.style.background = 'linear-gradient(135deg, #1e88e5 0%, #1565c0 100%)';
|
||||
nextBtn.style.color = 'white';
|
||||
nextBtn.style.borderColor = '#1e88e5';
|
||||
};
|
||||
nextBtn.onmouseleave = () => {
|
||||
nextBtn.style.background = 'white';
|
||||
nextBtn.style.color = '#5f6368';
|
||||
nextBtn.style.borderColor = '#dadce0';
|
||||
};
|
||||
const nextBtn = this.pageNavigation.createEl('button', { text: '›', cls: 'xhs-nav-btn' });
|
||||
nextBtn.onclick = () => this.nextPage();
|
||||
}
|
||||
|
||||
@@ -199,30 +151,11 @@ export class XiaohongshuPreviewView {
|
||||
*/
|
||||
private buildBottomToolbar(): void {
|
||||
this.bottomToolbar = this.container.createDiv({ cls: 'xhs-bottom-toolbar' });
|
||||
this.bottomToolbar.style.cssText = 'display: flex; justify-content: center; gap: 12px; padding: 12px 16px; background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border-top: 1px solid #e8eaed; box-shadow: 0 -2px 4px rgba(0,0,0,0.04);';
|
||||
|
||||
const currentPageBtn = this.bottomToolbar.createEl('button', { text: '⬇ 当前页切图' });
|
||||
currentPageBtn.style.cssText = 'padding: 8px 20px; background: linear-gradient(135deg, #1e88e5 0%, #1565c0 100%); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.2s ease; box-shadow: 0 2px 6px rgba(30, 136, 229, 0.3);';
|
||||
currentPageBtn.onmouseenter = () => {
|
||||
currentPageBtn.style.transform = 'translateY(-2px)';
|
||||
currentPageBtn.style.boxShadow = '0 4px 12px rgba(30, 136, 229, 0.4)';
|
||||
};
|
||||
currentPageBtn.onmouseleave = () => {
|
||||
currentPageBtn.style.transform = 'translateY(0)';
|
||||
currentPageBtn.style.boxShadow = '0 2px 6px rgba(30, 136, 229, 0.3)';
|
||||
};
|
||||
const currentPageBtn = this.bottomToolbar.createEl('button', { text: '⬇ 当前页切图', cls: 'xhs-slice-btn' });
|
||||
currentPageBtn.onclick = () => this.sliceCurrentPage();
|
||||
|
||||
const allPagesBtn = this.bottomToolbar.createEl('button', { text: '⇓ 全部页切图' });
|
||||
allPagesBtn.style.cssText = 'padding: 8px 20px; background: linear-gradient(135deg, #42a5f5 0%, #1e88e5 100%); color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.2s ease; box-shadow: 0 2px 6px rgba(66, 165, 245, 0.3);';
|
||||
allPagesBtn.onmouseenter = () => {
|
||||
allPagesBtn.style.transform = 'translateY(-2px)';
|
||||
allPagesBtn.style.boxShadow = '0 4px 12px rgba(66, 165, 245, 0.4)';
|
||||
};
|
||||
allPagesBtn.onmouseleave = () => {
|
||||
allPagesBtn.style.transform = 'translateY(0)';
|
||||
allPagesBtn.style.boxShadow = '0 2px 6px rgba(66, 165, 245, 0.3)';
|
||||
};
|
||||
const allPagesBtn = this.bottomToolbar.createEl('button', { text: '⇓ 全部页切图', cls: 'xhs-slice-btn secondary' });
|
||||
allPagesBtn.onclick = () => this.sliceAllPages();
|
||||
}
|
||||
|
||||
@@ -238,7 +171,7 @@ export class XiaohongshuPreviewView {
|
||||
// 创建临时容器用于分页
|
||||
const tempContainer = document.createElement('div');
|
||||
tempContainer.innerHTML = articleHTML;
|
||||
tempContainer.style.cssText = `width: ${this.settings.sliceImageWidth}px;`;
|
||||
tempContainer.style.width = `${this.settings.sliceImageWidth}px`;
|
||||
document.body.appendChild(tempContainer);
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user