mirror of
https://github.com/woodchen-ink/obsidian-publish-to-discourse.git
synced 2025-07-18 05:42:05 +08:00
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:
parent
f7c532d686
commit
65444caad1
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -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
|
||||
|
113
src/main.ts
113
src/main.ts
@ -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
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
return { message: "Error publishing to Discourse" };
|
||||
}
|
||||
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})`
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
message: "Error",
|
||||
error: `发布失败: ${error.message || '未知错误'}`
|
||||
};
|
||||
}
|
||||
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 = '发布中...';
|
||||
|
||||
try {
|
||||
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') {
|
||||
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 = '发布';
|
||||
}
|
||||
|
64
style.css
64
style.css
@ -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
143
styles.css
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user