新增版本更新通知功能,包含更新提示模态框样式和逻辑,用户首次运行新版本时将显示更新通知,提示用户重新配置 User-API-Key。更新国际化文件以支持多语言提示。

This commit is contained in:
wood chen 2025-07-11 23:55:04 +08:00
parent b98cb24e56
commit 9914ca9fd8
6 changed files with 162 additions and 3 deletions

View File

@ -7,6 +7,7 @@ export interface DiscourseSyncSettings {
category: number;
skipH1: boolean;
userApiKey: string;
lastNotifiedVersion?: string; // 记录上次显示更新通知的版本
}
export const DEFAULT_SETTINGS: DiscourseSyncSettings = {

View File

@ -86,5 +86,11 @@ export default {
'USER_API_KEY_DESC': 'Current configured User-API-Key (read-only)',
'USER_API_KEY_EMPTY': 'Please use the process below to obtain one',
'COPY_API_KEY': 'Copy',
'API_KEY_COPIED': '✅ API Key copied to clipboard'
'API_KEY_COPIED': '✅ API Key copied to clipboard',
// Version update notice
'UPDATE_NOTICE_TITLE': '🔄 Plugin Updated - Reconfiguration Required',
'UPDATE_NOTICE_MESSAGE': 'Due to major changes in authentication method, you need to reconfigure your User-API-Key. The old API Key and username method has been removed. Please go to settings to reconfigure.',
'UPDATE_NOTICE_BUTTON': 'Go to Settings',
'UPDATE_NOTICE_DISMISS': 'I understand'
}

View File

@ -86,5 +86,11 @@ export default {
'USER_API_KEY_DESC': '当前配置的 User-API-Key只读',
'USER_API_KEY_EMPTY': '请使用下面的流程获取',
'COPY_API_KEY': '复制',
'API_KEY_COPIED': '✅ API Key 已复制到剪贴板'
'API_KEY_COPIED': '✅ API Key 已复制到剪贴板',
// 版本更新提示
'UPDATE_NOTICE_TITLE': '🔄 插件已更新 - 需要重新配置',
'UPDATE_NOTICE_MESSAGE': '由于认证方式的重大变化,您需要重新配置 User-API-Key。旧的 API Key 和用户名方式已被移除,请前往设置页面重新配置。',
'UPDATE_NOTICE_BUTTON': '前往设置',
'UPDATE_NOTICE_DISMISS': '我知道了'
}

View File

@ -5,7 +5,7 @@ import { t, setLocale } from './i18n';
import { expandEmbeds } from './expand-embeds';
import { DiscourseAPI } from './api';
import { EmbedHandler } from './embed-handler';
import { SelectCategoryModal, CategoryConflictModal } from './ui';
import { SelectCategoryModal, CategoryConflictModal, UpdateNoticeModal } from './ui';
import { NotifyUser } from './notification';
import { getFrontMatter, removeFrontMatter } from './utils';
import { ActiveFile, PluginInterface } from './types';
@ -30,6 +30,9 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
// 加载设置
await this.loadSettings();
// 检查是否需要显示更新通知
await this.checkForUpdateNotice();
// 初始化API和嵌入处理器
this.api = new DiscourseAPI(this.app, this.settings);
this.embedHandler = new EmbedHandler(this.app, this.api);
@ -71,6 +74,29 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
await this.saveData(this.settings);
}
// 检查是否需要显示更新通知
private async checkForUpdateNotice() {
const currentVersion = this.manifest.version;
const lastNotifiedVersion = this.settings.lastNotifiedVersion;
// 如果是首次运行当前版本,显示更新通知
if (lastNotifiedVersion !== currentVersion) {
// 延迟显示,确保界面已完全加载
setTimeout(() => {
const modal = new UpdateNoticeModal(this.app, this, () => {
// 打开设置页面
(this.app as any).setting.open();
(this.app as any).setting.openTabById(this.manifest.id);
});
modal.open();
}, 1000);
// 更新记录的版本
this.settings.lastNotifiedVersion = currentVersion;
await this.saveSettings();
}
}
// 注册目录菜单
registerDirMenu(menu: Menu, file: TFile) {
const syncDiscourse = (item: MenuItem) => {

View File

@ -345,3 +345,59 @@ export class CategoryConflictModal extends Modal {
}
}
}
// 版本更新通知模态框
export class UpdateNoticeModal extends Modal {
plugin: PluginInterface;
onSettingsClick: () => void;
constructor(app: App, plugin: PluginInterface, onSettingsClick: () => void) {
super(app);
this.plugin = plugin;
this.onSettingsClick = onSettingsClick;
}
onOpen() {
const { contentEl } = this;
contentEl.empty();
contentEl.addClass('discourse-update-notice-modal');
// 标题
contentEl.createEl('h2', {
text: t('UPDATE_NOTICE_TITLE'),
cls: 'update-notice-title'
});
// 消息内容
const messageEl = contentEl.createEl('div', {
cls: 'update-notice-message'
});
messageEl.createEl('p', { text: t('UPDATE_NOTICE_MESSAGE') });
// 按钮区域
const buttonArea = contentEl.createEl('div', { cls: 'update-notice-buttons' });
// 前往设置按钮
const settingsButton = buttonArea.createEl('button', {
cls: 'mod-cta',
text: t('UPDATE_NOTICE_BUTTON')
});
settingsButton.onclick = () => {
this.close();
this.onSettingsClick();
};
// 我知道了按钮
const dismissButton = buttonArea.createEl('button', {
text: t('UPDATE_NOTICE_DISMISS')
});
dismissButton.onclick = () => {
this.close();
};
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}

View File

@ -483,3 +483,67 @@ If your plugin does not need CSS, delete this file.
max-width: none;
}
}
/* Update Notice Modal Styles */
.discourse-update-notice-modal {
padding: var(--size-4-4);
max-width: 500px;
background-color: var(--background-primary);
border-radius: var(--radius-l);
}
.discourse-update-notice-modal .update-notice-title {
margin: 0 0 var(--size-2-3) 0;
font-size: var(--font-text-size);
font-weight: var(--font-weight-bold);
color: var(--text-accent);
text-align: center;
}
.discourse-update-notice-modal .update-notice-message {
margin-bottom: var(--size-4-4);
text-align: left;
}
.discourse-update-notice-modal .update-notice-message p {
margin: 0;
color: var(--text-normal);
line-height: var(--line-height-normal);
font-size: var(--font-ui-medium);
}
.discourse-update-notice-modal .update-notice-buttons {
display: flex;
gap: var(--size-2-3);
justify-content: center;
}
.discourse-update-notice-modal .update-notice-buttons button {
flex: 1;
max-width: 150px;
padding: var(--size-2-2) var(--size-2-4);
border-radius: var(--radius-m);
cursor: pointer;
font-weight: var(--font-weight-medium);
font-size: var(--font-ui-medium);
transition: all 0.2s ease;
min-height: 36px;
border: 1px solid var(--background-modifier-border);
background-color: var(--background-secondary);
color: var(--text-normal);
}
.discourse-update-notice-modal .update-notice-buttons button:hover {
background-color: var(--background-modifier-hover);
}
.discourse-update-notice-modal .update-notice-buttons button.mod-cta {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
border-color: var(--interactive-accent);
}
.discourse-update-notice-modal .update-notice-buttons button.mod-cta:hover {
background-color: var(--interactive-accent-hover);
border-color: var(--interactive-accent-hover);
}