diff --git a/plugin/src/styles.scss b/plugin/src/styles.scss index 1de9a20b..2db2e632 100644 --- a/plugin/src/styles.scss +++ b/plugin/src/styles.scss @@ -1,21 +1,25 @@ +@mixin number-card { + padding: var(--size-2-1) var(--size-4-1); + border-radius: var(--radius-s); + background-color: var(--color-base-30); + font-size: var(--font-ui-small); + + &.good { + background-color: rgba(var(--color-green-rgb), 0.35); + } + + &.bad { + background-color: rgba(var(--color-red-rgb), 0.35); + } +} + .status-description { margin: var(--p-spacing) 0; .number { - padding: var(--size-2-1) var(--size-4-1); - border-radius: var(--radius-s); - background-color: var(--color-base-30); + @include number-card; font-family: var(--font-monospace); font-weight: var(--bold-weight); - font-size: var(--font-ui-small); - - &.good { - background-color: rgba(var(--color-green-rgb), 0.35); - } - - &.bad { - background-color: rgba(var(--color-red-rgb), 0.35); - } } .error { @@ -34,14 +38,11 @@ font-size: var(--h2-size); .version { - display: block; - font-size: var(--font-ui-smaller); - margin-top: var(--size-2-2); - margin-left: var(--size-4-2); - padding: var(--size-2-1) var(--size-4-1); + @include number-card; + margin: var(--size-2-2) 0 0 var(--size-4-2); background-color: var(--color-base-30); color: var(--color-base-70); - border-radius: var(--radius-s); + font-size: var(--font-ui-smaller); } } @@ -84,23 +85,41 @@ } } -.log-message { - font: var(--font-monospace); +.logs-view { + .logs-container { + max-height: 100%; + max-width: 100%; + overflow-y: auto; - &.DEBUG { - color: var(--color-base-50); - } + .log-message { + font: var(--font-monospace); + margin-bottom: var(--size-2-1); + overflow-wrap: break-word; + white-space: pre-wrap; - &.INFO { - color: var(--color-green-rgb); - } + .timestamp { + @include number-card; + font-family: var(--font-monospace); + font-weight: var(--bold-weight); + margin-right: var(--size-4-1); + } - &.WARNING { - color: var(--color-yellow-rgb); - } + &.DEBUG { + color: var(--color-base-50); + } - &.ERROR { - color: var(--color-red-rgb); + &.INFO { + color: var(--color-green-rgb); + } + + &.WARNING { + color: var(--color-yellow-rgb); + } + + &.ERROR { + color: var(--color-red-rgb); + } + } } } diff --git a/plugin/src/views/logs-view.ts b/plugin/src/views/logs-view.ts index f39ba481..3671de96 100644 --- a/plugin/src/views/logs-view.ts +++ b/plugin/src/views/logs-view.ts @@ -1,17 +1,29 @@ import type { WorkspaceLeaf } from "obsidian"; import { ItemView } from "obsidian"; +import type VaultLinkPlugin from "src/vault-link-plugin"; import { LogLevel, Logger } from "src/tracing/logger"; +import { Database } from "src/database/database"; export class LogsView extends ItemView { public static readonly TYPE = "logs-view"; public static readonly ICON = "logs"; - public constructor(leaf: WorkspaceLeaf) { + public constructor( + private readonly plugin: VaultLinkPlugin, + private readonly database: Database, + leaf: WorkspaceLeaf + ) { super(leaf); this.icon = LogsView.ICON; Logger.getInstance().addOnMessageListener(() => { this.updateView(); }); + + database.addOnSettingsChangeHandlers((newSettings, oldSettings) => { + if (newSettings.minimumLogLevel !== oldSettings.minimumLogLevel) { + this.updateView(); + } + }); } private static formatTimestamp(timestamp: Date): string { @@ -28,6 +40,16 @@ export class LogsView extends ItemView { public async onOpen(): Promise { this.updateView(); + + const container = this.containerEl.children[1]; + container.addClass("logs-view"); + + const logsContainer = container + .getElementsByClassName("logs-container") + .item(0); + if (logsContainer) { + logsContainer.scrollTop = logsContainer.scrollHeight; + } } private updateView(): void { @@ -35,19 +57,54 @@ export class LogsView extends ItemView { container.empty(); container.createEl("h4", { text: "VaultLink logs" }); + container.createEl( + "p", + { + text: "This view displays logs generated by VaultLink. You can set the log level in the ", + }, + (p) => { + p.createEl( + "a", + { + text: "settings", + }, + (button) => { + button.addEventListener("click", () => { + this.plugin.openSettings(); + }); + } + ); - Logger.getInstance() - .getMessages(LogLevel.DEBUG) - .forEach((message) => { - const messageContainer = container.createDiv({ - cls: ["log-message", message.level], - }); - messageContainer.createEl("span", { - text: ` | ${LogsView.formatTimestamp( - message.timestamp - )} | `, - }); - messageContainer.createEl("span", { text: message.message }); - }); + p.createSpan({ text: "." }); + } + ); + + const logs = Logger.getInstance().getMessages( + this.database.getSettings().minimumLogLevel + ); + + if (logs.length === 0) { + container.createEl("p", { text: "No logs available yet." }); + return; + } + + container.createDiv({ cls: "logs-container" }, (logsContainer) => { + logs.forEach((message) => + logsContainer.createDiv( + { + cls: ["log-message", message.level], + }, + (messageContainer) => { + messageContainer.createEl("span", { + text: LogsView.formatTimestamp(message.timestamp), + cls: "timestamp", + }); + messageContainer.createEl("span", { + text: message.message, + }); + } + ) + ); + }); } }