diff --git a/CHANGELOG.md b/CHANGELOG.md index e91ac06..1050323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,4 +69,4 @@ Pretty Home is a VS Code extension designed to enhance the appearance of your re ### Version 1.1.5 (2024-07-31) -- Update open instance logic \ No newline at end of file +- Update open instance logic, added logger in output channel and performance improvment. \ No newline at end of file diff --git a/README.md b/README.md index ef6d2c5..37217bd 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ After installing the extension, navigate to the command palette in VS Code and s - **1.1.2**: Fix Load on startup by default. - **1.1.3**: Fix Pretty home instance open multiple instances on profile switch. - **1.1.4**: Fix State issue to memorize opening tab instance. -- **1.1.5**: Update open instance logic. +- **1.1.5**: Update open instance logic, added logger in output channel and performance improvment. **Contributing:** Contributions are welcome. Feel free to submit issues or pull requests on [GitHub](https://github.com/sefatanam/vscode-pretty-home). diff --git a/js/broker.js b/js/broker.js index f4620c1..358a384 100644 --- a/js/broker.js +++ b/js/broker.js @@ -1,4 +1,4 @@ -const projectOpenButtons = document.querySelectorAll(".projectOpenButton"); + const searchInput = document.querySelector("#seachInput"); const vscode = acquireVsCodeApi(); @@ -42,9 +42,14 @@ const debouncedTriggerSearchProjectCommand = debounce( 300 ); -Array.from(projectOpenButtons).forEach((projectOpenButton) => - projectOpenButton?.addEventListener("click", triggerOpenProjectCommand) -); +function attachEventListeners() { + const projectOpenButtonsSelector = ".projectOpenButton"; + const projectOpenButtons = document.querySelectorAll(projectOpenButtonsSelector); + Array.from(projectOpenButtons).forEach((projectOpenButton) => + projectOpenButton?.addEventListener("click", triggerOpenProjectCommand) + ); +} + searchInput.addEventListener("input", () => debouncedTriggerSearchProjectCommand(searchInput) ); @@ -54,6 +59,10 @@ window.addEventListener("message", (event) => { switch (message.command) { case "renderCards": document.querySelector("#cardsContainer").innerHTML = message.html; + attachEventListeners() break; } }); + + +window.addEventListener('DOMContentLoaded', () => attachEventListeners()) \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index cb1aa6b..5c9d163 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,28 +1,34 @@ -import * as vscode from "vscode"; -import { openProjectInGithub, shouldOpenInstance, showPrettyHomeCommand, showPrettyHomeSettingsCommand } from "./lib"; +import { commands, ExtensionContext, window, WindowState, workspace } from "vscode"; +import { Logger, openProjectInGithub, shouldOpenInstance, showPrettyHomeCommand, showPrettyHomeSettingsCommand } from "./lib"; +const logger = Logger.GetInstance(); // This method is called when your extension is activated // Your extension is activated the very first time the command is executed -export async function activate(context: vscode.ExtensionContext) { +export async function activate(context: ExtensionContext) { + + logger.log('Extension Pretty Home is now active!'); await showPrettyHomeCommand(context); await showPrettyHomeSettingsCommand(context); await openProjectInGithub(context); // Open the webview by default when VS Code starts and no folder/workspace is loaded - vscode.window.onDidChangeWindowState((e: vscode.WindowState) => { + window.onDidChangeWindowState((e: WindowState) => { try { + if (workspace.workspaceFolders) return; if (shouldOpenInstance() && e.focused) return; - vscode.commands.executeCommand('extension.prettyHome'); + commands.executeCommand('extension.prettyHome'); } catch (err: any) { - vscode.window.showErrorMessage("Something went wront to load by default."); + logger.log(`${JSON.stringify(err)}. Please report to admin. Github link https://github.com/sefatanam/pretty-home`); + window.showErrorMessage("Something went wrong. Checkout detail in the Output channel."); } }); (function init() { + if (workspace.workspaceFolders) return; if (shouldOpenInstance()) return; - vscode.commands.executeCommand('extension.prettyHome'); + commands.executeCommand('extension.prettyHome'); })() } diff --git a/src/lib/command.ts b/src/lib/command.ts index 3ae8cba..6ab35f3 100644 --- a/src/lib/command.ts +++ b/src/lib/command.ts @@ -1,29 +1,28 @@ import path from 'path'; -import * as vscode from 'vscode'; +import { commands, env, ExtensionContext, Uri, ViewColumn, window } from 'vscode'; import { APP, COMMAND, REPO_URL } from "./constant"; -import { gerRecentProjects, isTabInstanceOpen, openProject, showSettingsDialog } from "./engine"; -import { RecentProject } from "./types"; +import { filterProjects, gerRecentProjects, isTabInstanceOpen, openProject, showSettingsDialog } from "./engine"; import { getWebviewContent, makeProjectCards } from "./views"; -export async function showPrettyHomeCommand(context: vscode.ExtensionContext) { - const disposable = vscode.commands.registerCommand( +export async function showPrettyHomeCommand(context: ExtensionContext) { + const disposable = commands.registerCommand( "extension.prettyHome", async () => { if (isTabInstanceOpen()) { - vscode.window.showInformationMessage('Pretty Home already initialized ✨'); + window.showInformationMessage('Pretty Home already initialized ✨'); return }; const panelIconPath = { - light: vscode.Uri.file(path.join(context.extensionPath, 'assets', 'icon.png')), - dark: vscode.Uri.file(path.join(context.extensionPath, 'assets', 'icon.png')) + light: Uri.file(path.join(context.extensionPath, 'assets', 'icon.png')), + dark: Uri.file(path.join(context.extensionPath, 'assets', 'icon.png')) }; - const webviewPanel = vscode.window.createWebviewPanel( + const webviewPanel = window.createWebviewPanel( APP.WEB_VIEW_TYPE, APP.TITLE, - vscode.ViewColumn.One, + ViewColumn.One, { enableScripts: true, retainContextWhenHidden: true, @@ -36,7 +35,7 @@ export async function showPrettyHomeCommand(context: vscode.ExtensionContext) { try { switch (message.command) { case COMMAND.INVALID_PROJECT: - vscode.window.showInformationMessage('Path is not valid !'); + window.showInformationMessage('Path is not valid !'); break; case COMMAND.OPEN_PROJECT: openProject(message.path); @@ -47,7 +46,7 @@ export async function showPrettyHomeCommand(context: vscode.ExtensionContext) { webviewPanel.webview.postMessage({ command: COMMAND.RENDER_CARDS, html: productCards }); } } catch (err: any) { - vscode.window.showInformationMessage(JSON.stringify(err)); + window.showInformationMessage(JSON.stringify(err)); } }, undefined, @@ -60,8 +59,8 @@ export async function showPrettyHomeCommand(context: vscode.ExtensionContext) { } -export async function showPrettyHomeSettingsCommand(context: vscode.ExtensionContext) { - const defaultSettingDisposable = vscode.commands.registerCommand( +export async function showPrettyHomeSettingsCommand(context: ExtensionContext) { + const defaultSettingDisposable = commands.registerCommand( "extension.prettyHomeSettings", async () => { await showSettingsDialog(context); @@ -69,18 +68,11 @@ export async function showPrettyHomeSettingsCommand(context: vscode.ExtensionCon context.subscriptions.push(defaultSettingDisposable); } -export async function openProjectInGithub(context: vscode.ExtensionContext) { - const disposable = vscode.commands.registerCommand( +export async function openProjectInGithub(context: ExtensionContext) { + const disposable = commands.registerCommand( "extension.prettyHomeGiveStar", async () => { - vscode.env.openExternal(vscode.Uri.parse(REPO_URL)); + env.openExternal(Uri.parse(REPO_URL)); }); context.subscriptions.push(disposable); } - -function filterProjects(projects: RecentProject[], name: string) { - if (!name) { return projects; } - - name = name.toLowerCase().trim(); - return projects.filter(project => project.name.toLowerCase().trim().includes(name)); -} \ No newline at end of file diff --git a/src/lib/engine.ts b/src/lib/engine.ts index 04d82b7..63e1dfb 100644 --- a/src/lib/engine.ts +++ b/src/lib/engine.ts @@ -1,9 +1,10 @@ -import * as vscode from "vscode"; +import { commands, ConfigurationTarget, ExtensionContext, Uri, window, workspace } from "vscode"; +import { Logger } from "./logger"; import { RecentProject, RecentWorkspaces, Workspace } from "./types"; export async function gerRecentProjects(): Promise { - const recentWorkspaces: RecentWorkspaces = await vscode.commands.executeCommand("_workbench.getRecentlyOpened"); + const recentWorkspaces: RecentWorkspaces = await commands.executeCommand("_workbench.getRecentlyOpened"); if (!recentWorkspaces) return [] const recentFolders = recentWorkspaces.workspaces || []; @@ -13,24 +14,38 @@ export async function gerRecentProjects(): Promise { } +export function filterProjects(projects: RecentProject[], name: string) { + if (!name) { return projects; } + + name = name.toLowerCase().trim(); + return projects.filter(project => project.name.toLowerCase().trim().includes(name)); +} + export function getWorkspaceName(workspace: Workspace): string { if ("configPath" in workspace) { - return vscode.workspace.name || "Workspace"; + return workspace.configPath?.path || "Workspace"; } return workspace.folderUri.path.split("/").pop() || "Untitled"; } export function openProject(path: string) { try { - vscode.commands.executeCommand('vscode.openFolder', vscode.Uri.file(path), true); + commands.executeCommand('vscode.openFolder', Uri.file(path)).then(() => { + Logger.GetInstance().log(`Successfully opened project at path: ${JSON.stringify(path)}`); + }, + (err) => { + Logger.GetInstance().log(`Failed to open project at path: ${JSON.stringify(path)}, error: ${err.message}`); + window.showInformationMessage(`Failed to open project: ${err.message}`); + }); } catch (err: any) { - vscode.window.showInformationMessage(JSON.stringify(err)); + Logger.GetInstance().log(`Exception opening project at path: ${JSON.stringify(path)}, error: ${err.message}`); + window.showInformationMessage(`Exception opening project: ${JSON.stringify(err)}`); } } -export async function showSettingsDialog(context: vscode.ExtensionContext) { - const config = vscode.workspace.getConfiguration('prettyHome'); - const selectedOption = await vscode.window.showQuickPick( +export async function showSettingsDialog(context: ExtensionContext) { + const config = workspace.getConfiguration('prettyHome'); + const selectedOption = await window.showQuickPick( ['Yes', 'No'], { placeHolder: 'Do you want to load Pretty Home by default on startup?', @@ -40,12 +55,12 @@ export async function showSettingsDialog(context: vscode.ExtensionContext) { if (selectedOption === 'Yes' || selectedOption === 'No') { const newValue = selectedOption === 'Yes'; - await config.update('showOnStartup', newValue, vscode.ConfigurationTarget.Global); + await config.update('showOnStartup', newValue, ConfigurationTarget.Global); } } export function isTabInstanceOpen(): boolean { - const isInstanceOpen = vscode.window.tabGroups.all + const isInstanceOpen = window.tabGroups.all .flatMap(group => group.tabs) .find(tab => tab.label.trim().includes('Pretty-Home')) if (!isInstanceOpen) return false; @@ -53,10 +68,9 @@ export function isTabInstanceOpen(): boolean { } export function shouldStartInStartup(): boolean { - const config = vscode.workspace.getConfiguration('prettyHome'); + const config = workspace.getConfiguration('prettyHome'); const showOnStartup = config.get('showOnStartup', false); - const shouldOpen = !vscode.workspace.workspaceFolders && showOnStartup; - return shouldOpen; + return showOnStartup; } export function shouldOpenInstance() { diff --git a/src/lib/index.ts b/src/lib/index.ts index 94e5204..7f6c888 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,6 +1,7 @@ export * from './command'; export * from './constant'; export * from './engine'; +export * from './logger'; export * from './types'; export * from './views'; diff --git a/src/lib/logger.ts b/src/lib/logger.ts new file mode 100644 index 0000000..4e174e8 --- /dev/null +++ b/src/lib/logger.ts @@ -0,0 +1,18 @@ +import { window } from 'vscode'; + +const outputChannel = window.createOutputChannel('Pretty Home'); + +export class Logger { + static instance: Logger ; + static { + this.instance = new Logger() + } + + static GetInstance() { + return this.instance; + } + + log(message: string) { + outputChannel.appendLine(message); + } +} \ No newline at end of file diff --git a/src/lib/views.ts b/src/lib/views.ts index 26e4194..f8158b7 100644 --- a/src/lib/views.ts +++ b/src/lib/views.ts @@ -1,20 +1,19 @@ -import * as vscode from 'vscode'; -import { ExtensionContext, WebviewPanel } from "vscode"; +import { ExtensionContext, Uri, WebviewPanel } from 'vscode'; import { WEB_VIEW_ID } from "./constant"; import { RecentProject } from "./types"; export const getWebviewContent = (projects: RecentProject[], context: ExtensionContext, panel: WebviewPanel) => { let htmlContent = generateWebView(makeProjectCards(projects)); - const iconFilePath = vscode.Uri.joinPath(context.extensionUri, 'assets', 'icon.png'); + const iconFilePath = Uri.joinPath(context.extensionUri, 'assets', 'icon.png'); const iconUri = panel.webview.asWebviewUri(iconFilePath); htmlContent = htmlContent.replace('favicon.png', iconUri.toString()); - const cssFilePath = vscode.Uri.joinPath(context.extensionUri, 'css', 'style.css'); + const cssFilePath = Uri.joinPath(context.extensionUri, 'css', 'style.css'); const cssUri = panel.webview.asWebviewUri(cssFilePath); htmlContent = htmlContent.replace('style.css', cssUri.toString()); - const jsFilePath = vscode.Uri.joinPath(context.extensionUri, 'js', 'broker.js'); + const jsFilePath = Uri.joinPath(context.extensionUri, 'js', 'broker.js'); const visUri = panel.webview.asWebviewUri(jsFilePath); htmlContent = htmlContent.replace('broker.js', visUri.toString()); return htmlContent;