Asper Header  1.0.16
The header injector extension
Loading...
Searching...
No Matches
randomLogo.ts
Go to the documentation of this file.
1
83import * as fs from 'fs/promises';
84import * as path from 'path';
85import * as vscode from 'vscode';
86import { logger } from "./logger";
87import { getMessage } from "./messageProvider";
88import { LazyFileLoader } from "./lazyFileLoad";
89
98export interface logo {
100 logoContent: string[],
102 fileName: string
103}
104
132export class RandomLogo {
134 private cwd: string | undefined = undefined;
136 private rootDir: string | undefined = undefined;
138 private liveLogoFiles: LazyFileLoader[] = [];
139
150 constructor(rootDir: string | undefined = undefined, cwd: string | undefined = undefined) {
151 logger.debug(getMessage("inFunction", "constructor", "RandomLogo"));
152 if (rootDir) {
153 this.rootDir = rootDir;
154 this.gatherAllLogoFiles(this.rootDir);
155 }
156 if (cwd) {
157 this.cwd = cwd;
158 }
159 }
160
180 async updateRootDir(basePath: string, alternateBasePath: string | undefined = undefined): Promise<boolean> {
181 logger.debug(getMessage("inFunction", "updateRootDir", "RandomLogo"));
182 this.rootDir = basePath;
183 try {
184 await this.gatherAllLogoFiles(this.rootDir);
185 logger.debug(getMessage("foundLogoRootDir", basePath));
186 return true;
187 } catch (e) {
188 logger.error(getMessage("logoRootDirUpdateError", String(e)));
189 if (alternateBasePath === undefined) {
190 logger.warning(getMessage("alternateLogoDirectoryNotProvided"));
191 return false;
192 }
193 this.rootDir = alternateBasePath;
194 try {
195 await this.gatherAllLogoFiles(this.rootDir);
196 logger.debug(getMessage("foundAlternateLogoRootDir", alternateBasePath));
197 return true;
198 } catch (e) {
199 logger.error(getMessage("alternateLogoDirectoryNotFound", alternateBasePath, String(e)));
200 return false;
201 }
202 }
203 }
204
214 updateCurrentWorkingDirectory(cwd: string): boolean {
215 logger.debug(getMessage("inFunction", "updateCurrentWorkingDirectory", "RandomLogo"));
216 this.cwd = cwd;
217 return true;
218 }
219
229 private getRandomNumber(maxValue: number): number {
230 logger.debug(getMessage("inFunction", "getRandomNumber", "RandomLogo"));
231 return Math.floor(Math.random() * maxValue);
232 }
233
260 private async gatherAllLogoFiles(rootDir: string | undefined = undefined): Promise<void> {
261 logger.debug(getMessage("inFunction", "gatherAllLogoFiles", "RandomLogo"));
262 if (!rootDir && !this.rootDir) {
263 throw Error(getMessage("logoNoRootDir"));
264 }
265 if (!rootDir && this.rootDir) {
266 rootDir = this.rootDir;
267 }
268 if (rootDir) {
269 const dirents = await fs.readdir(rootDir, { withFileTypes: true });
270
271 for (const dirent of dirents) {
272 const resolvedPath = path.resolve(rootDir, dirent.name);
273 if (dirent.isDirectory()) {
274 await this.gatherAllLogoFiles(resolvedPath);
275 } else if (resolvedPath.endsWith(".txt")) {
276 this.liveLogoFiles.push(new LazyFileLoader(resolvedPath, this.cwd));
277 } else {
278 logger.info(getMessage("logoMessage", resolvedPath));
279 }
280 }
281 }
282 }
302 private copyButtonScript(): string {
303 logger.debug(getMessage("inFunction", "copyButtonScript", "RandomLogo"));
304 return `
305<script>
306 const vscode = acquireVsCodeApi();
307 console.log(\`vscode = \${vscode}\`);
308 document.getElementById('copyBtn').addEventListener('click', () => {
309 const content = document.getElementById('ascii').innerText;
310 navigator.clipboard.writeText(content).then(() => {
311 vscode.postMessage({ type: 'copied' });
312 });
313 });
314</script>
315 `;
316 }
317
338 private zoomScript(): string {
339 logger.debug(getMessage("inFunction", "zoomScript", "RandomLogo"));
340 return `
341<script>
342 let currentSize = 20;
343 function updateFontSize(sizeDifference) {
344 console.log(\`sizeDifference = \${sizeDifference}\`);
345 const asciiPre = document.getElementById('ascii');
346 console.log(\`asciiPre = \${JSON.stringify(asciiPre)}\`);
347 console.log(\`currentSize = \${currentSize}\`);
348 if (currentSize + sizeDifference >= 2) {
349 currentSize += sizeDifference;
350 console.log(\`currentSize (after update) = \${currentSize}\`);
351 } else {
352 console.log(\`currentSize (no update) = \${currentSize}\`);
353 }
354 asciiPre.style.fontSize = currentSize + "px";
355 asciiPre.style.lineHeight = currentSize + "px";
356 console.log(\`newSize = \${asciiPre.style.fontSize}\`);
357 }
358
359 document.getElementById('zoomInBtn').addEventListener('click', () => {
360 updateFontSize((2));
361 });
362
363 document.getElementById('zoomOutBtn').addEventListener('click', () => {
364 updateFontSize((-2));
365 });
366
367 // init
368 updateFontSize();
369</script>
370 `;
371 }
372
388 private pageStyle(): string {
389 logger.debug(getMessage("inFunction", "pageStyle", "RandomLogo"));
390 return `
391 <style>
392 body { font-family: sans-serif; padding: 20px; }
393 h1 { font-size: 20px; margin-bottom: 0.2em; }
394 h2 { margin-top: 1.2em; }
395 pre { font-size: 10px; line-height: 10px; white-space: pre; }
396 button { margin: 10px 0; padding: 5px 12px; font-size: 14px; }
397 </style>
398 `;
399 }
400
428 async getRandomLogoFromFolder(): Promise<logo> {
429 logger.debug(getMessage("inFunction", "getRandomLogoFromFolder", "RandomLogo"));
430 if (this.liveLogoFiles.length === 0) {
431 await this.gatherAllLogoFiles();
432 }
433
434 if (this.liveLogoFiles.length === 0) {
435 const errMsg = getMessage("watermarkJsonFileInvalid");
436 logger.Gui.error(errMsg);
437 throw new Error(errMsg);
438 }
439
440 const chosenIndex = this.getRandomNumber(this.liveLogoFiles.length);
441 const chosenFile = this.liveLogoFiles[chosenIndex];
442 const content = await chosenFile.get();
443
444 // Assuming logos are stored as array of lines, otherwise fallback to single string
445 const lines = content.split(/\r?\n/);
446
447 return {
448 fileName: path.basename(chosenFile.getFilePath() || ""),
449 logoContent: lines
450 };
451 }
452
453
486 async displayRandomLogoInWindow() {
487 logger.debug(getMessage("inFunction", "displayRandomLogoInWindow", "RandomLogo"));
488 const randomLogo: logo = await this.getRandomLogoFromFolder();
489
490 const panel = vscode.window.createWebviewPanel(
491 getMessage("logoView"),
492 randomLogo.fileName,
493 vscode.ViewColumn.One,
494 { enableScripts: true }
495 );
496
497 const watermark = randomLogo.logoContent;
498 logger.info(getMessage("logoChosen", watermark));
499 let asciiArt = "";
500 if (typeof watermark === "string") {
501 asciiArt = watermark;
502 } else if (Array.isArray(watermark)) {
503 asciiArt = watermark.join("\n");
504 } else if (watermark === undefined) {
505 asciiArt = getMessage("logoNotFound");
506 }
507
508 const copyButton: string = this.copyButtonScript();
509 const pageStyle: string = this.pageStyle();
510 const zoomScript: string = this.zoomScript();
511
512 panel.webview.html = `
513<!DOCTYPE html>
514<html lang="en">
515<head>
516 <meta charset="UTF-8">
517 ${pageStyle}
518</head>
519<body>
520 <div>
521 <button id="copyBtn">${getMessage('logoCopyAscii')}</button>
522 <button id="zoomInBtn">${getMessage('logoZoomIn')}</button>
523 <button id="zoomOutBtn">${getMessage('logoZoomOut')}</button>
524 </div>
525 <h1>${getMessage('logoName')}: ${randomLogo.fileName}</h1>
526 <pre id="ascii">${asciiArt}</pre>
527 ${copyButton}
528 ${zoomScript}
529</body>
530</html>
531`;
532
533 panel.webview.onDidReceiveMessage(message => {
534 if (message.type === "copied") {
535 logger.Gui.info(getMessage("logoCopied", randomLogo.fileName));
536 }
537 });
538
539 logger.Gui.info(getMessage("logoDisplayed", randomLogo.fileName));
540 }
541}
Generic lazy file loader with caching and type safety @template T The expected type of the loaded fil...
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAv3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbEsMgCPznFD2CAho5jknTmd6gx qtNJMEqCKH4h lRj6dADxVZugptTqwzYer65UeIe5DWUctXFzIXEu5EdIHqrWYry UL6xZmlG7UnJa57b oHlEkAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDUBSFT1OlKhWHFhFxyFA72UVFHGsVilAh1AqtOpi89A aNCQpLo6Ca8HBn8Wqg4uzrg6ugiD4A IuOCm6SIn3JYUWsT64vI z3jncdx8gNCpMs3rigKbbZjqZELO5VTHwin4MU4UQlZllzElSCl3X1z18fL L8azu9 Ma56LLAM8NmJj1PHCYWix2sdDArmRrxNHFE1XTKF7Ieq5y3OGuVGmv1yV8YzOsry1ynGkMSi1iCBBEKaiijAhsx2nVSLKTpPNHFP r6JXIp5CqDkWMBVWiQXT yerVWYmvSSggmg98VxPsaBwC7QrDvO97HjNE8A zNwpbf91QYw KqFQAN7P6JtyQOgWGFjz5tY6x kDkKFZpW6Ag0MgWqTs9S7v7uuc2793WvP7AZKlcrMQx gGAAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDowOWQ3ODk3OS03YjNiLTRhMTgtODM5ZS1lMDgwOGNjMmUzY2EiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTM2YWE3YmMtN2QzZS00ZDJkLWIxMjItYTFhZjQwMjkzYjI5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTc2ZWEzNTgtNTNlNy00ODZkLWIzMzQtMjhmZWY1N2IyZWIzIgogICBHSU1QOkFQST0iMy4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NTg1MzI3OTM2NzA4NzIiCiAgIEdJTVA6VmVyc2lvbj0iMy4wLjQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MjJUMTE6MTk6NTArMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjIyVDExOjE5OjUwKzAyOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGE1MDJhZWEtNDM0MS00NjdjLTgwMzEtYjUwMmU2OGFhYjkwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMjJUMTE6MTk6NTMrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8 QZaInQAAAAZiS0dEAAAAAAAA UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB kJFgkTNb1wNOYAABokSURBVHja7V15dFRF1r9V7 WW7mwsAZJ0SJpElARhUBM0gKNwjsM2gIMw oF Ss4MHy5DmBEB56g4Is6ZIQGRJYownzIalCUzLnj0Cx7GBZhAWISIMGaTYIBgku5Od7 t7vdH8pruTifpzkaAd8 pk8573fWqbv3q3lu3bt1HEPEkAAyAThLf8uNBna2AQhfJW4EkSV2rgOd5SEpKavWF yv QjEZjq58rigLJyclAqfdZZMaMGbX5 fmDAQAIItb2jbnQWVK70KUK8Kp2IWAuYOcrSEpKAkJIwG0GQ5OtXekCBUDabss6qIABEAaEEKitrXVnZ2eLwaSy3w uPI2CLCtAgAMAgLFjx oqKyt59b7a3VZMbJYDzXJBp NAUZoFSWVlJa sKCgoK6NLgSXBSdOnGhseQAiImRnZ0u T21TFiAqmJgYj3PmzHF4ryiK7PuNDipAHDhwICIirly58kJ1daUz8L4XylarFX744YdW45CcnNzcmSvyAMrLy vqXOiKPBgEV4koXGXqmw0YOnQoDB06NKQK9u3bdz6YWdPpBqhGRWjoZsBQBkIxQBD12hA0y1vVBiOEgCIrYVmLXWxAs7z2teE4noPt27fbw7Gyg89PijA02RpETalWZ7N42rJlCzDlSl8kSYKpU6fqAAAEQYCHHnzIuWv3Lsvx48drb7311sGt6vO1zhARGWNotVrRarUiYwzbJwWLiz rSUyMR0QFRVFEH6mNR44caXK73aLH45EREQsKCjy JTMzEyPeiclJQVGjhwZYTQadZRSTpIkGDx4sCAIgtguB1TV0pZ6aY8DiIhlZWVNKjMREQVBUH7 ziBhdaEVB8KtINzva8qo29cH3dEAvKGHQGtA322AIivQG hs1QDGGAwdOhQoR0OSclarFbKysuq7zyZk4dmEiAoQgu16tXoNA1fHKPUrV5kDhBCQJAkYY73VABZQAEpKShyKokB fr49JPM80ESSJRmtVqufW7A9kywhYQhmZd3xk2qSqYYtImJCQkKHNdC2etbsEWABrljFb UkCBLwvB4I4bzM3L17d OpU6caEBFmzZrlfuaZZ wqOIOBlA JiCQnJLkddu0tS7Ytm2brCgKL8uy99Y777xD33vvvUhCCJyvOS lpqUq fv MREBE3btzoREQ8ePCgK3Ct0U4DWEgLE98GFBYWlvvenTRpknP8 PGNKp6C1dnFBiAmJibi7bff lPg9dTUVCmwjtWrVzcsW7bM3o3rAn9yu91gMplAkRU4 e1pXpZl0Ol03vsVFRVcQUGBpV05QCgJw RmV1bIwKCkpMSh1sHxnPfhJ0 etCMiBD682yXhkiVLdOqqWd0tYYzBiBEjotrqTLfoggiTBQAoHD582Hju3Dk3YzJyHIGH uvXrltuucXruAjJKmaMQXJyMlRVVYVsDwRzdQc2dO3atbWzZs1q5R g21KrgQBqiziO83 U16fK Bgc7OFtrgsCvdo9uTjVFiZaA7QGXPX9ght BDQGaAzQGKAx4GpSyEuSr7 Kysru7xDodK ffvOP LII GEEBgyZEj9oUOHYvsUAhDR6zP0vdZ1BjQvWhjKgKgA5Tg PyMi6ZR5r8mAnpIBPcZ7NegSA pSuSFfxTtzTffbLbZbKb09HRp0aJF5mPHjkWkp6db3n777foZM2Y4rxIDWBil60j45JNP6jdv3txYVVVVDwCg1 th vz5sRcvXoTDhw b6 rq3L0kAxjwPA83DU8FURSDOmWuqAraLq8REbZt2ybzvA4o5QGZKvlbj8mAAQN0c fONZ49e9Yv5Pf2228X586d22 hfqX3ieB47j DYcgu3tuN1uZenSpdx export const string
Definition constants.ts:258
export const randomLogo
Whether to use random logo selection instead of default logo.
Definition constants.ts:235
Structure representing a loaded ASCII art logo with metadata.
Structure representing a loaded ASCII art watermark with font metadata.
import type
export const logger
Singleton logger instance providing unified logging interface for the entire extension.
Definition logger.ts:910
export const getMessage
Exported function for direct message retrieval.
import *as vscode from vscode
Definition randomLogo.ts:85
import *as path from path
Definition randomLogo.ts:84