diff --git a/src/config.ts b/src/config.ts index d6cafca..2a63427 100644 --- a/src/config.ts +++ b/src/config.ts @@ -7,6 +7,7 @@ export interface DiscourseSyncSettings { category: number; skipH1: boolean; userApiKey: string; + lastNotifiedVersion?: string; // 记录上次显示更新通知的版本 } export const DEFAULT_SETTINGS: DiscourseSyncSettings = { diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 79954db..fbab349 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -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' } \ No newline at end of file diff --git a/src/i18n/zh-CN.ts b/src/i18n/zh-CN.ts index 7d53caa..34b6d66 100644 --- a/src/i18n/zh-CN.ts +++ b/src/i18n/zh-CN.ts @@ -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': '我知道了' } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 8e78e10..85e07c6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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) => { diff --git a/src/ui.ts b/src/ui.ts index ddbf8d5..116a58d 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -344,4 +344,60 @@ export class CategoryConflictModal extends Modal { this.resolve(false); } } +} + +// 版本更新通知模态框 +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(); + } } \ No newline at end of file diff --git a/styles.css b/styles.css index e5458d4..0f564ff 100644 --- a/styles.css +++ b/styles.css @@ -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); +}