Remove unused style.css file and update release workflow to reference styles.css instead of style.css. Enhance error handling in postTopic method to provide detailed feedback on publishing errors in DiscourseSyncPlugin.

This commit is contained in:
wood chen 2025-01-23 23:21:53 +08:00
parent f7c532d686
commit 65444caad1
4 changed files with 256 additions and 98 deletions

View File

@ -32,7 +32,7 @@ jobs:
tag="${GITHUB_REF#refs/tags/}"
files=()
for file in main.js manifest.json style.css; do
for file in main.js manifest.json styles.css; do
if [ -f "$file" ]; then
files+=("$file")
else

View File

@ -104,7 +104,7 @@ export default class DiscourseSyncPlugin extends Plugin {
return imageUrls;
}
async postTopic(): Promise<{ message: string }> {
async postTopic(): Promise<{ message: string; error?: string }> {
const url = `${this.settings.baseUrl}/posts.json`;
const headers = {
"Content-Type": "application/json",
@ -131,21 +131,51 @@ export default class DiscourseSyncPlugin extends Plugin {
category: this.settings.category
});
const response = await requestUrl({
url: url,
method: "POST",
contentType: "application/json",
body,
headers,
});
try {
const response = await requestUrl({
url: url,
method: "POST",
contentType: "application/json",
body,
headers,
throw: false // 设置为 false 以获取错误响应
});
if (response.status !== 200) {
if (response.status == 422) {
new NotifyUser(this.app, `There's an error with this post, could be a duplicate or the title is too short: ${response.status}`).open();
if (response.status === 200) {
return { message: "Success" };
} else {
// 尝试从响应中获取错误信息
try {
const errorResponse = response.json;
// Discourse 通常会在 errors 数组中返回错误信息
if (errorResponse.errors && errorResponse.errors.length > 0) {
return {
message: "Error",
error: errorResponse.errors.join('\n')
};
}
// 有些错误可能在 error 字段中
if (errorResponse.error) {
return {
message: "Error",
error: errorResponse.error
};
}
} catch (parseError) {
// 如果无法解析错误响应
return {
message: "Error",
error: `发布失败 (${response.status})`
};
}
}
return { message: "Error publishing to Discourse" };
} catch (error) {
return {
message: "Error",
error: `发布失败: ${error.message || '未知错误'}`
};
}
return { message: "Success" };
return { message: "Error", error: "发布失败,请重试" };
}
private async fetchCategories() {
@ -258,20 +288,21 @@ export class SelectCategoryModal extends Modal {
constructor(app: App, plugin: DiscourseSyncPlugin, categories: {id: number; name: string }[]) {
super(app);
this.plugin = plugin;
this.categories = categories
this.categories = categories;
}
onOpen() {
// 添加模态框基础样式
this.modalEl.addClass('mod-discourse-sync');
const { contentEl } = this;
contentEl.empty();
contentEl.addClass('discourse-sync-modal');
contentEl.createEl("h1", { text: '选择发布分类' });
// 创建选择器容器
const selectContainer = contentEl.createEl('div', { cls: 'select-container' });
const selectLabel = selectContainer.createEl('label', { text: '分类' });
selectLabel.style.display = 'block';
selectLabel.style.marginBottom = '8px';
selectContainer.createEl('label', { text: '分类' });
const selectEl = selectContainer.createEl('select');
@ -297,22 +328,70 @@ export class SelectCategoryModal extends Modal {
submitButton.disabled = true;
submitButton.textContent = '发布中...';
const reply = await this.plugin.postTopic();
// 显示提示信息
noticeContainer.empty();
noticeContainer.createEl('div', {
cls: `notice ${reply.message === 'Success' ? 'success' : 'error'}`,
text: reply.message === 'Success' ? '发布成功!' : '发布失败,请重试。'
});
if (reply.message === 'Success') {
// 成功后延迟关闭
setTimeout(() => {
this.close();
}, 1500);
} else {
// 失败时重置按钮状态
try {
const reply = await this.plugin.postTopic();
// 显示提示信息
noticeContainer.empty();
if (reply.message === 'Success') {
noticeContainer.createEl('div', {
cls: 'notice success',
text: '✓ 发布成功!'
});
// 成功后延迟关闭
setTimeout(() => {
this.close();
}, 1500);
} else {
const errorContainer = noticeContainer.createEl('div', { cls: 'notice error' });
errorContainer.createEl('div', {
cls: 'error-title',
text: '发布失败'
});
// 显示 Discourse 返回的具体错误信息
errorContainer.createEl('div', {
cls: 'error-message',
text: reply.error || '发布失败,请重试'
});
// 添加重试按钮
const retryButton = errorContainer.createEl('button', {
cls: 'retry-button',
text: '重试'
});
retryButton.onclick = () => {
noticeContainer.empty();
submitButton.disabled = false;
submitButton.textContent = '发布';
};
}
} catch (error) {
noticeContainer.empty();
const errorContainer = noticeContainer.createEl('div', { cls: 'notice error' });
errorContainer.createEl('div', {
cls: 'error-title',
text: '发布出错'
});
errorContainer.createEl('div', {
cls: 'error-message',
text: error.message || '未知错误'
});
// 添加重试按钮
const retryButton = errorContainer.createEl('button', {
cls: 'retry-button',
text: '重试'
});
retryButton.onclick = () => {
noticeContainer.empty();
submitButton.disabled = false;
submitButton.textContent = '发布';
};
}
// 如果发生错误,重置按钮状态
if (submitButton.disabled) {
submitButton.disabled = false;
submitButton.textContent = '发布';
}

View File

@ -1,64 +0,0 @@
/*
This CSS file will be included with your plugin, and
available in the app when your plugin is enabled.
If your plugin does not need CSS, delete this file.
*/
.discourse-sync-modal {
padding: 20px;
}
.discourse-sync-modal h1 {
margin-bottom: 20px;
color: var(--text-normal);
}
.discourse-sync-modal .select-container {
margin-bottom: 24px;
}
.discourse-sync-modal select {
width: 100%;
padding: 8px 12px;
height: 42px;
line-height: 1.5;
border: 1px solid var(--background-modifier-border);
border-radius: 4px;
background-color: var(--background-primary);
color: var(--text-normal);
}
.discourse-sync-modal .submit-button {
width: 100%;
padding: 10px;
background-color: var(--interactive-accent);
color: var(--text-on-accent);
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
}
.discourse-sync-modal .submit-button:hover {
background-color: var(--interactive-accent-hover);
}
.discourse-sync-modal .notice {
margin-top: 16px;
padding: 10px;
border-radius: 4px;
text-align: center;
}
.discourse-sync-modal .notice.success {
background-color: var(--background-modifier-success);
color: var(--text-success);
}
.discourse-sync-modal .notice.error {
background-color: var(--background-modifier-error);
color: var(--text-error);
}

143
styles.css Normal file
View File

@ -0,0 +1,143 @@
/*
This CSS file will be included with your plugin, and
available in the app when your plugin is enabled.
If your plugin does not need CSS, delete this file.
*/
/* 基础模态框样式覆盖 */
.modal.mod-discourse-sync {
max-width: 500px;
max-height: 80vh;
background-color: var(--background-primary);
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
/* 内容区域样式 */
.discourse-sync-modal {
padding: 24px;
width: 100%;
}
.discourse-sync-modal h1 {
margin: 0 0 24px 0;
font-size: 1.5em;
font-weight: 600;
color: var(--text-normal);
}
.discourse-sync-modal .select-container {
margin-bottom: 24px;
}
.discourse-sync-modal .select-container label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--text-normal);
}
.discourse-sync-modal select {
width: 100%;
padding: 8px 12px;
height: 42px;
line-height: 1.5;
border: 2px solid var(--background-modifier-border);
border-radius: 4px;
background-color: var(--background-primary);
color: var(--text-normal);
font-size: 14px;
}
.discourse-sync-modal select:focus {
border-color: var(--interactive-accent);
outline: none;
}
.discourse-sync-modal .submit-button {
width: 100%;
padding: 10px 16px;
background-color: var(--interactive-accent);
color: var(--text-on-accent);
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
font-size: 14px;
transition: background-color 0.2s ease;
}
.discourse-sync-modal .submit-button:hover {
background-color: var(--interactive-accent-hover);
}
.discourse-sync-modal .submit-button:disabled {
opacity: 0.7;
cursor: not-allowed;
}
/* 提示信息样式 */
.discourse-sync-modal .notice {
margin-top: 16px;
padding: 16px;
border-radius: 8px;
text-align: left;
font-size: 14px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.discourse-sync-modal .notice.success {
background-color: var(--background-modifier-success-hover);
color: var(--text-success);
text-align: center;
font-weight: 500;
}
.discourse-sync-modal .notice.error {
background: rgb(255, 235, 235);
border: 1px solid rgba(255, 82, 82, 0.2);
color: rgb(255, 82, 82);
}
.discourse-sync-modal .error-title {
font-size: 15px;
font-weight: 600;
margin-bottom: 8px;
color: rgb(255, 82, 82);
display: flex;
align-items: center;
gap: 6px;
}
.discourse-sync-modal .error-title::before {
content: "⚠️";
font-size: 16px;
}
.discourse-sync-modal .error-message {
color: rgb(255, 82, 82);
opacity: 0.8;
font-size: 13px;
line-height: 1.5;
}
.discourse-sync-modal .retry-button {
margin-top: 12px;
padding: 6px 16px;
background-color: transparent;
color: rgb(255, 82, 82);
border: 1px solid rgb(255, 82, 82);
border-radius: 4px;
cursor: pointer;
font-size: 13px;
font-weight: 500;
transition: all 0.2s ease;
}
.discourse-sync-modal .retry-button:hover {
background-color: rgb(255, 82, 82);
color: white;
}