83import * as
fs from
'fs/promises';
84import * as
path from
'path';
98export
interface logo {
100 logoContent:
string[],
132export
class RandomLogo {
134 private cwd:
string | undefined = undefined;
136 private rootDir:
string | undefined = undefined;
150 constructor(rootDir:
string | undefined = undefined, cwd:
string | undefined = undefined) {
153 this.rootDir = rootDir;
154 this.gatherAllLogoFiles(this.rootDir);
180 async updateRootDir(basePath:
string, alternateBasePath:
string | undefined = undefined): Promise<boolean> {
182 this.rootDir = basePath;
184 await this.gatherAllLogoFiles(this.rootDir);
189 if (alternateBasePath === undefined) {
193 this.rootDir = alternateBasePath;
195 await this.gatherAllLogoFiles(this.rootDir);
199 logger.error(
getMessage(
"alternateLogoDirectoryNotFound", alternateBasePath, String(e)));
214 updateCurrentWorkingDirectory(cwd:
string): boolean {
215 logger.debug(
getMessage(
"inFunction",
"updateCurrentWorkingDirectory",
"RandomLogo"));
229 private getRandomNumber(maxValue: number): number {
231 return Math.floor(Math.random() * maxValue);
260 private async gatherAllLogoFiles(rootDir:
string | undefined = undefined): Promise<void> {
262 if (!rootDir && !this.rootDir) {
265 if (!rootDir && this.rootDir) {
266 rootDir = this.rootDir;
269 const dirents = await
fs.readdir(rootDir, { withFileTypes:
true });
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));
302 private copyButtonScript():
string {
306 const vscode = acquireVsCodeApi();
308 document.getElementById(
'copyBtn').addEventListener(
'click', () => {
309 const content = document.getElementById(
'ascii').innerText;
310 navigator.clipboard.writeText(content).then(() => {
338 private zoomScript():
string {
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}\`);
352 console.log(\`currentSize (no update) = \${currentSize}\`);
354 asciiPre.style.fontSize = currentSize +
"px";
355 asciiPre.style.lineHeight = currentSize +
"px";
356 console.log(\`newSize = \${asciiPre.style.fontSize}\`);
359 document.getElementById(
'zoomInBtn').addEventListener(
'click', () => {
363 document.getElementById(
'zoomOutBtn').addEventListener(
'click', () => {
364 updateFontSize((-2));
388 private pageStyle():
string {
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; }
428 async getRandomLogoFromFolder(): Promise<
logo> {
429 logger.debug(
getMessage(
"inFunction",
"getRandomLogoFromFolder",
"RandomLogo"));
430 if (this.liveLogoFiles.length === 0) {
431 await this.gatherAllLogoFiles();
434 if (this.liveLogoFiles.length === 0) {
435 const errMsg =
getMessage(
"watermarkJsonFileInvalid");
437 throw new Error(errMsg);
440 const chosenIndex = this.getRandomNumber(this.liveLogoFiles.length);
441 const chosenFile = this.liveLogoFiles[chosenIndex];
442 const content = await chosenFile.get();
445 const lines = content.split(/\r?\n/);
448 fileName:
path.basename(chosenFile.getFilePath() ||
""),
486 async displayRandomLogoInWindow() {
487 logger.debug(
getMessage(
"inFunction",
"displayRandomLogoInWindow",
"RandomLogo"));
490 const panel =
vscode.window.createWebviewPanel(
494 { enableScripts: true }
508 const copyButton:
string = this.copyButtonScript();
509 const pageStyle:
string = this.pageStyle();
510 const zoomScript:
string = this.zoomScript();
512 panel.webview.html = `
516 <meta charset=
"UTF-8">
521 <button
id=
"copyBtn">${
getMessage(
'logoCopyAscii')}</button>
522 <button
id=
"zoomInBtn">${
getMessage(
'logoZoomIn')}</button>
523 <button
id=
"zoomOutBtn">${
getMessage(
'logoZoomOut')}</button>
526 <pre
id=
"ascii">${asciiArt}</pre>
533 panel.webview.onDidReceiveMessage(message => {
534 if (message.type ===
"copied") {
Generic lazy file loader with caching and type safety @template T The expected type of the loaded fil...
export const randomLogo
Whether to use random logo selection instead of default logo.
Structure representing a loaded ASCII art logo with metadata.
Structure representing a loaded ASCII art watermark with font metadata.
export const logger
Singleton logger instance providing unified logging interface for the entire extension.
export const getMessage
Exported function for direct message retrieval.
export const Record< string,(...args:any[])=> string
import *as vscode from vscode
import *as path from path