mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
Add release notes viewer
- New dedicated view displays release notes when plugin updates - Automatically opens after version updates - Available via command palette and settings - Uses native Obsidian markdown rendering - Auto-generation system loads correct version automatically - Fully internationalized
This commit is contained in:
parent
88ae6e0ce9
commit
4f28dfa98a
14 changed files with 249 additions and 3 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -16,6 +16,9 @@ main.js
|
|||
# It's built from source files in styles/ directory during CI/build process.
|
||||
styles.css
|
||||
|
||||
# Don't include the auto-generated release notes import file
|
||||
src/releaseNotes.ts
|
||||
|
||||
# Exclude sourcemaps
|
||||
*.map
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,17 @@ Example:
|
|||
|
||||
-->
|
||||
|
||||
## Added
|
||||
|
||||
- Added release notes viewer
|
||||
- New view displays release notes in a dedicated tab when plugin updates
|
||||
- Automatically opens after updating to a new version
|
||||
- Access anytime via command palette "TaskNotes: View release notes" or Settings > General
|
||||
- Release notes are rendered using native Obsidian markdown rendering
|
||||
- Includes link to view all releases on GitHub
|
||||
- Fully internationalized with i18n support
|
||||
- Auto-generation system ensures correct version is loaded without manual updates
|
||||
|
||||
## Fixed
|
||||
|
||||
- (#814) Fixed markdown links in projects field not being recognized on Project notes
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import esbuild from "esbuild";
|
||||
import process from "process";
|
||||
import builtins from "builtin-modules";
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
const banner =
|
||||
`/*
|
||||
|
|
@ -11,6 +12,20 @@ if you want to view the source, please visit the github repository of this plugi
|
|||
|
||||
const prod = (process.argv[2] === "production");
|
||||
|
||||
// Plugin to import markdown files as strings
|
||||
const markdownPlugin = {
|
||||
name: 'markdown',
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /\.md$/ }, async (args) => {
|
||||
const text = readFileSync(args.path, 'utf8');
|
||||
return {
|
||||
contents: `export default ${JSON.stringify(text)}`,
|
||||
loader: 'js',
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const context = await esbuild.context({
|
||||
banner: {
|
||||
js: banner,
|
||||
|
|
@ -39,6 +54,7 @@ const context = await esbuild.context({
|
|||
treeShaking: true,
|
||||
outfile: "main.js",
|
||||
minify: prod,
|
||||
plugins: [markdownPlugin],
|
||||
});
|
||||
|
||||
if (prod) {
|
||||
|
|
|
|||
20
generate-release-notes-import.mjs
Normal file
20
generate-release-notes-import.mjs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { readFileSync, writeFileSync } from "fs";
|
||||
|
||||
// Read current version from manifest.json
|
||||
const manifest = JSON.parse(readFileSync("manifest.json", "utf8"));
|
||||
const version = manifest.version;
|
||||
|
||||
// Generate the TypeScript file that imports the current version's release notes
|
||||
const content = `// Auto-generated file - do not edit manually
|
||||
// This file is regenerated during the build process to import the current version's release notes
|
||||
|
||||
import releaseNotes from "../docs/releases/${version}.md";
|
||||
|
||||
export const CURRENT_VERSION = "${version}";
|
||||
export const CURRENT_RELEASE_NOTES = releaseNotes;
|
||||
`;
|
||||
|
||||
// Write to src/releaseNotes.ts
|
||||
writeFileSync("src/releaseNotes.ts", content);
|
||||
|
||||
console.log(`✓ Generated release notes import for version ${version}`);
|
||||
|
|
@ -127,6 +127,9 @@
|
|||
"views.stats.sections.projectBreakdown": "c856b0f89a0d1f51f02f82726206cb07cd1ae95e",
|
||||
"views.stats.sections.dateRange": "6bb4b674b3232e32feb264e11f19ee1dbed354a3",
|
||||
"views.stats.filters.minTime": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"views.releaseNotes.title": "5939771f391859041bc57e5e05b04235b1ef8ee7",
|
||||
"views.releaseNotes.header": "5939771f391859041bc57e5e05b04235b1ef8ee7",
|
||||
"views.releaseNotes.viewAllLink": "b37e5d2fb2faa630817557713df6363f4bd0f5cc",
|
||||
"settings.tabs.general": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"settings.tabs.taskProperties": "770bd2ee4e0a455df6d1332def9c6c58f44994bc",
|
||||
"settings.tabs.defaults": "809ab386aa1c870ee286190b1af3eace7f0bfe30",
|
||||
|
|
@ -845,6 +848,7 @@
|
|||
"commands.pauseResumePomodoro": "1ac6f3fd60f918b25cfb95be70b9d43f3b3281bb",
|
||||
"commands.refreshCache": "0b56ae2b187bdf931d24258272f284d7046ad543",
|
||||
"commands.exportAllTasksIcs": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"commands.viewReleaseNotes": "04c2072af97cf70c22fbf9efa9b62eb2574d23d6",
|
||||
"modals.task.titlePlaceholder": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"modals.task.titleLabel": "768e0c1c69573fb588f61f1308a015c11468e05f",
|
||||
"modals.task.titleDetailedPlaceholder": "da3700738242c039de32d3f5e3a0ba10bc28ba0b",
|
||||
|
|
|
|||
|
|
@ -512,6 +512,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "a6bce6cf45ab6987a0491268052e0770559f80a4"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "21a7b4ecae6d99d7c9ae0fe00f0cc0a33f1e2b6f"
|
||||
|
|
@ -3372,6 +3375,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "2b3a3551e913a0618f09a1378c63fa6b832fe6cf"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "03f97eff6f24910100617f3fcbc4665e2e65cd7e"
|
||||
|
|
@ -6042,6 +6046,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "01c1479a894b4e8a3b6e679bd3630c1389c7cd60"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "9239ee2cda84eca4c3440e2a7b50148af67da3d4"
|
||||
|
|
@ -8902,6 +8909,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "8f93640a115b91031d8f53e89543cc0bf04e300b"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "dee0035d1027b937237c8bbdd6e77288df356ff4"
|
||||
|
|
@ -11572,6 +11580,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "b6a500e983b64d611aab3a9d5b2ec65fd4511f10"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "5376df989fac86247d5cd9f983d11ece28e75fcd"
|
||||
|
|
@ -14432,6 +14443,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "e4c5963ce721f4bb182d474d1a9c0c604325c274"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "4ad6efca173a22d4bf622d5729c3ad13612e6902"
|
||||
|
|
@ -17036,6 +17048,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "7deced4ee8b6e75d5dcafff58c7bd89905c98fd6"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "f0aaccbc0dcda37daa045cb4cda85177bedafdb0"
|
||||
|
|
@ -19890,6 +19905,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "4f7b9505464a8b039fee24745afe2a1c951b81d3"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "0e65840f941f2c5e030cf553e4e5a3cc315fe73d"
|
||||
|
|
@ -22419,6 +22435,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "a82231aecd1ee2ec08d32031cf19b6f6a4f2842e"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "fdd17d17b54069e4f68253b0af0b1a50d389b199"
|
||||
|
|
@ -25246,6 +25265,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "1ce699b6bccf33a45ff58320f4dfeb2593c3111e"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "fb99b9f5be8916e4a7b038e3d1d9d9087f8a5653"
|
||||
|
|
@ -27850,6 +27870,9 @@
|
|||
"source": "77f4b7a081b20f78557dd404e14d91b89b52a27c",
|
||||
"translation": "227f72b88ebec3e37158e855352776b82662a27c"
|
||||
},
|
||||
"views.releaseNotes.title": null,
|
||||
"views.releaseNotes.header": null,
|
||||
"views.releaseNotes.viewAllLink": null,
|
||||
"settings.tabs.general": {
|
||||
"source": "9239ee2cda84eca4c3440e2a7b50148af67da3d4",
|
||||
"translation": "f1484fa78b69777c083f5b19555ee4d232d70163"
|
||||
|
|
@ -30695,6 +30718,7 @@
|
|||
"source": "3f3714587b4802efeb6baf380a59615b8faf0c10",
|
||||
"translation": "f4fa2d18fff78b531c07f83bbc7753c26dbc05d9"
|
||||
},
|
||||
"commands.viewReleaseNotes": null,
|
||||
"modals.task.titlePlaceholder": {
|
||||
"source": "c8196f1d1039c2fb290add52ee990c571173d6f1",
|
||||
"translation": "37d9b0a0a59872345ce5e206027f8eccf793e6fa"
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"build": "npm run build-css && tsc -noEmit --skipLibCheck && node esbuild.config.mjs production",
|
||||
"build": "npm run build-css && node generate-release-notes-import.mjs && tsc -noEmit --skipLibCheck && node esbuild.config.mjs production",
|
||||
"dev": "npm run build && npm run copy-files",
|
||||
"dev:watch": "npm run build-css && node esbuild.config.mjs",
|
||||
"dev:watch": "npm run build-css && node generate-release-notes-import.mjs && node esbuild.config.mjs",
|
||||
"copy-files": "node copy-files.mjs",
|
||||
"build-css": "node build-css.mjs",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
||||
"version": "node version-bump.mjs && node generate-release-notes-import.mjs && git add manifest.json versions.json src/releaseNotes.ts",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage",
|
||||
|
|
|
|||
|
|
@ -204,6 +204,11 @@ export const en: TranslationTree = {
|
|||
minTime: "Min Time (minutes)",
|
||||
},
|
||||
},
|
||||
releaseNotes: {
|
||||
title: "What's new in TaskNotes {version}",
|
||||
header: "What's new in TaskNotes {version}",
|
||||
viewAllLink: "View all release notes on GitHub →",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
tabs: {
|
||||
|
|
@ -1496,6 +1501,7 @@ export const en: TranslationTree = {
|
|||
pauseResumePomodoro: "Pause/resume pomodoro timer",
|
||||
refreshCache: "Refresh cache",
|
||||
exportAllTasksIcs: "Export all tasks as ICS file",
|
||||
viewReleaseNotes: "View release notes",
|
||||
},
|
||||
modals: {
|
||||
task: {
|
||||
|
|
|
|||
51
src/main.ts
51
src/main.ts
|
|
@ -94,6 +94,8 @@ import { AutoExportService } from "./services/AutoExportService";
|
|||
// Type-only import for HTTPAPIService (actual import is dynamic on desktop only)
|
||||
import type { HTTPAPIService } from "./services/HTTPAPIService";
|
||||
import { createI18nService, I18nService, TranslationKey } from "./i18n";
|
||||
import { ReleaseNotesView, RELEASE_NOTES_VIEW_TYPE } from "./views/ReleaseNotesView";
|
||||
import { CURRENT_RELEASE_NOTES } from "./releaseNotes";
|
||||
|
||||
interface TranslatedCommandDefinition {
|
||||
id: string;
|
||||
|
|
@ -461,6 +463,11 @@ export default class TaskNotesPlugin extends Plugin {
|
|||
|
||||
this.registerView(KANBAN_VIEW_TYPE, (leaf) => new KanbanView(leaf, this));
|
||||
|
||||
this.registerView(
|
||||
RELEASE_NOTES_VIEW_TYPE,
|
||||
(leaf) => new ReleaseNotesView(leaf, this, CURRENT_RELEASE_NOTES, this.manifest.version)
|
||||
);
|
||||
|
||||
// Register essential editor extensions (now safe after layout ready)
|
||||
this.registerEditorExtension(createTaskLinkOverlay(this));
|
||||
|
||||
|
|
@ -639,6 +646,9 @@ export default class TaskNotesPlugin extends Plugin {
|
|||
|
||||
// Migration check was moved to early startup - just show prompts here if needed
|
||||
await this.showMigrationPromptsIfNeeded();
|
||||
|
||||
// Check for version updates and show release notes if needed
|
||||
await this.checkForVersionUpdate();
|
||||
} catch (error) {
|
||||
console.error("Error during lazy service initialization:", error);
|
||||
}
|
||||
|
|
@ -886,6 +896,36 @@ export default class TaskNotesPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for version updates and show release notes if needed
|
||||
*/
|
||||
private async checkForVersionUpdate(): Promise<void> {
|
||||
try {
|
||||
const currentVersion = this.manifest.version;
|
||||
const lastSeenVersion = this.settings.lastSeenVersion;
|
||||
|
||||
// If this is a new install or version has changed, show release notes
|
||||
if (lastSeenVersion && lastSeenVersion !== currentVersion) {
|
||||
// Show release notes after a delay to ensure UI is ready
|
||||
setTimeout(async () => {
|
||||
await this.activateReleaseNotesView();
|
||||
// Update lastSeenVersion immediately after showing the release notes
|
||||
// This ensures they only show once per version
|
||||
this.settings.lastSeenVersion = currentVersion;
|
||||
await this.saveSettings();
|
||||
}, 1500); // Slightly longer delay than migration to avoid conflicts
|
||||
}
|
||||
|
||||
// Update lastSeenVersion if it hasn't been set yet (new install)
|
||||
if (!lastSeenVersion) {
|
||||
this.settings.lastSeenVersion = currentVersion;
|
||||
await this.saveSettings();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking for version update:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method for views to wait for migration completion
|
||||
*/
|
||||
|
|
@ -1429,6 +1469,13 @@ export default class TaskNotesPlugin extends Plugin {
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "view-release-notes",
|
||||
nameKey: "commands.viewReleaseNotes",
|
||||
callback: async () => {
|
||||
await this.activateReleaseNotesView();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
this.registerCommands();
|
||||
|
|
@ -1560,6 +1607,10 @@ export default class TaskNotesPlugin extends Plugin {
|
|||
return this.activateView(KANBAN_VIEW_TYPE);
|
||||
}
|
||||
|
||||
async activateReleaseNotesView() {
|
||||
return this.activateView(RELEASE_NOTES_VIEW_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open and activate the search pane with a tag query
|
||||
* (Renamed from openSearchPaneWithTag for cleaner API)
|
||||
|
|
|
|||
5
src/markdown.d.ts
vendored
Normal file
5
src/markdown.d.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Type declarations for importing markdown files as strings
|
||||
declare module "*.md" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
|
@ -238,6 +238,8 @@ export const DEFAULT_SETTINGS: TaskNotesSettings = {
|
|||
customPriorities: DEFAULT_PRIORITIES,
|
||||
// Migration defaults
|
||||
recurrenceMigrated: false,
|
||||
// Release notes defaults
|
||||
lastSeenVersion: undefined,
|
||||
// Status bar defaults
|
||||
showTrackedTasksInStatusBar: false,
|
||||
// Time tracking defaults
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// import { TAbstractFile } from 'obsidian';
|
||||
import { Setting } from "obsidian";
|
||||
import TaskNotesPlugin from "../../main";
|
||||
import {
|
||||
createSectionHeader,
|
||||
|
|
@ -226,4 +227,20 @@ export function renderGeneralTab(
|
|||
save();
|
||||
},
|
||||
});
|
||||
|
||||
// Release Notes Section
|
||||
createSectionHeader(container, "Release Notes");
|
||||
createHelpText(container, `Current version: ${plugin.manifest.version}`);
|
||||
|
||||
new Setting(container)
|
||||
.setName("View release notes")
|
||||
.setDesc("See what's new in the latest version of TaskNotes")
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("View release notes")
|
||||
.setCta()
|
||||
.onClick(async () => {
|
||||
await plugin.activateReleaseNotesView();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ export interface TaskNotesSettings {
|
|||
customPriorities: PriorityConfig[];
|
||||
// Migration tracking
|
||||
recurrenceMigrated?: boolean;
|
||||
// Release notes tracking
|
||||
lastSeenVersion?: string;
|
||||
// Status bar settings
|
||||
showTrackedTasksInStatusBar: boolean;
|
||||
// Time tracking settings
|
||||
|
|
|
|||
85
src/views/ReleaseNotesView.ts
Normal file
85
src/views/ReleaseNotesView.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import { ItemView, WorkspaceLeaf, MarkdownRenderer } from "obsidian";
|
||||
import TaskNotesPlugin from "../main";
|
||||
|
||||
export const RELEASE_NOTES_VIEW_TYPE = "tasknotes-release-notes";
|
||||
|
||||
const GITHUB_RELEASES_URL = "https://github.com/callumalpass/tasknotes/releases";
|
||||
|
||||
export class ReleaseNotesView extends ItemView {
|
||||
plugin: TaskNotesPlugin;
|
||||
private releaseNotes: string;
|
||||
private version: string;
|
||||
|
||||
constructor(leaf: WorkspaceLeaf, plugin: TaskNotesPlugin, releaseNotes: string, version: string) {
|
||||
super(leaf);
|
||||
this.plugin = plugin;
|
||||
this.releaseNotes = releaseNotes;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
getViewType(): string {
|
||||
return RELEASE_NOTES_VIEW_TYPE;
|
||||
}
|
||||
|
||||
getDisplayText(): string {
|
||||
return this.plugin.i18n.translate("views.releaseNotes.title", { version: this.version });
|
||||
}
|
||||
|
||||
getIcon(): string {
|
||||
return "book-open";
|
||||
}
|
||||
|
||||
async onOpen() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
contentEl.addClass("tasknotes-release-notes-view");
|
||||
|
||||
// Create a container for the markdown content
|
||||
const container = contentEl.createDiv({ cls: "tasknotes-release-notes-container" });
|
||||
container.style.padding = "20px";
|
||||
container.style.maxWidth = "900px";
|
||||
container.style.margin = "0 auto";
|
||||
|
||||
// Header with version
|
||||
const header = container.createEl("div", { cls: "release-notes-header" });
|
||||
header.style.marginBottom = "20px";
|
||||
header.createEl("h1", {
|
||||
text: this.plugin.i18n.translate("views.releaseNotes.header", { version: this.version })
|
||||
});
|
||||
|
||||
// Markdown content
|
||||
const markdownContainer = container.createEl("div", { cls: "release-notes-content" });
|
||||
markdownContainer.style.marginBottom = "30px";
|
||||
|
||||
// Render the markdown
|
||||
await MarkdownRenderer.render(
|
||||
this.plugin.app,
|
||||
this.releaseNotes,
|
||||
markdownContainer,
|
||||
"",
|
||||
this as any
|
||||
);
|
||||
|
||||
// Footer with link to all releases
|
||||
const footer = container.createEl("div", { cls: "release-notes-footer" });
|
||||
footer.style.borderTop = "1px solid var(--background-modifier-border)";
|
||||
footer.style.paddingTop = "20px";
|
||||
footer.style.textAlign = "center";
|
||||
|
||||
const link = footer.createEl("a", {
|
||||
text: this.plugin.i18n.translate("views.releaseNotes.viewAllLink"),
|
||||
href: GITHUB_RELEASES_URL,
|
||||
});
|
||||
link.style.color = "var(--text-accent)";
|
||||
link.style.textDecoration = "none";
|
||||
link.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
window.open(GITHUB_RELEASES_URL, "_blank");
|
||||
});
|
||||
}
|
||||
|
||||
async onClose() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue