@@ -237,31 +237,32 @@ class UIManager {
237237 */
238238 generateCommandWithIcon ( process ) {
239239 let iconHtml = '' ;
240+ const command = process . command || '' ;
240241
241242 // Determine the type of icon based on the process service or command
242243 if ( process . service === 'nginx' ) {
243244 iconHtml = '<span class="command-icon nginx-icon">NGINX</span>' ;
244245 } else if ( process . service === 'node' ) {
245246 iconHtml = '<span class="command-icon node-icon">NODE</span>' ;
246- } else if ( process . service === 'python' || process . command . includes ( 'python' ) ) {
247+ } else if ( process . service === 'python' || command . includes ( 'python' ) ) {
247248 iconHtml = '<span class="command-icon python-icon">PY</span>' ;
248- } else if ( process . service === 'java' || process . command . includes ( 'java' ) ) {
249+ } else if ( process . service === 'java' || command . includes ( 'java' ) ) {
249250 iconHtml = '<span class="command-icon java-icon">JAVA</span>' ;
250- } else if ( process . service === 'mysql' || process . command . includes ( 'mysql' ) ) {
251+ } else if ( process . service === 'mysql' || command . includes ( 'mysql' ) ) {
251252 iconHtml = '<span class="command-icon mysql-icon">SQL</span>' ;
252- } else if ( process . command . includes ( 'firefox' ) ) {
253+ } else if ( command . includes ( 'firefox' ) ) {
253254 iconHtml = '<span class="command-icon firefox-icon">FF</span>' ;
254- } else if ( process . command . includes ( 'chrome' ) ) {
255+ } else if ( command . includes ( 'chrome' ) ) {
255256 iconHtml = '<span class="command-icon chrome-icon">CR</span>' ;
256- } else if ( process . command . includes ( 'pycharm' ) ) {
257+ } else if ( command . includes ( 'pycharm' ) ) {
257258 iconHtml = '<span class="command-icon pycharm-icon">PC</span>' ;
258- } else if ( process . command . includes ( 'vscode' ) || process . command . includes ( 'code' ) ) {
259+ } else if ( command . includes ( 'vscode' ) || command . includes ( 'code' ) ) {
259260 iconHtml = '<span class="command-icon vscode-icon">VS</span>' ;
260261 } else {
261262 iconHtml = '<span class="command-icon process-icon">PROC</span>' ;
262263 }
263264
264- return `<div class="command-with-icon">${ iconHtml } <span class="command-text">${ process . command } </span></div>` ;
265+ return `<div class="command-with-icon">${ iconHtml } <span class="command-text">${ command } </span></div>` ;
265266 }
266267
267268 /**
@@ -270,183 +271,108 @@ class UIManager {
270271 * @returns {string } HTML for the preview thumbnail
271272 */
272273 generatePreviewThumbnail ( process ) {
273- let thumbnailContent = '' ;
274- let thumbnailClass = 'preview-thumbnail' ;
275-
276- // Generate command icon for use in thumbnails
277- const commandIcon = this . generateCommandWithIcon ( process ) ;
278-
279- // Determine the type of preview based on the process
280- if ( process . file ) {
281- // Get file content from fileSystemManager if available, otherwise use local method
282- const fileContent = this . fileSystemManager ?
283- this . fileSystemManager . getFileContent ( process . file ) :
284- this . getFileContent ( process . file ) ;
285-
286- if ( fileContent ) {
287- if ( process . file . endsWith ( '.html' ) ) {
288- thumbnailContent = `
289- <div class="html-preview">
290- <div class="text-preview-header">
291- <span>${ commandIcon } </span>
292- <span class="file-icon" style="background: #e34c26; color: white;">HTML</span>
293- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
294- </div>
295- <iframe srcdoc="${ this . escapeHTML ( fileContent ) } "></iframe>
296- </div>
297- ` ;
298- } else if ( process . file . endsWith ( '.js' ) ) {
299- thumbnailContent = `
300- <div class="code-preview">
301- <div class="code-preview-header">
302- <span>${ commandIcon } </span>
303- <span class="file-icon" style="background: #f7df1e; color: #000;">JS</span>
304- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
305- </div>
306- <pre class="code-snippet">${ this . escapeHTML ( fileContent . substring ( 0 , 100 ) ) } ${ fileContent . length > 100 ? '...' : '' } </pre>
307- </div>
308- ` ;
309- } else if ( process . file . endsWith ( '.css' ) ) {
310- thumbnailContent = `
311- <div class="code-preview">
312- <div class="code-preview-header">
313- <span>${ commandIcon } </span>
314- <span class="file-icon" style="background: #264de4; color: white;">CSS</span>
315- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
316- </div>
317- <pre class="code-snippet">${ this . escapeHTML ( fileContent . substring ( 0 , 100 ) ) } ${ fileContent . length > 100 ? '...' : '' } </pre>
318- </div>
319- ` ;
320- } else if ( process . file . endsWith ( '.json' ) ) {
321- thumbnailContent = `
322- <div class="code-preview">
323- <div class="code-preview-header">
324- <span>${ commandIcon } </span>
325- <span class="file-icon" style="background: #000; color: white;">JSON</span>
326- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
327- </div>
328- <pre class="code-snippet">${ this . escapeHTML ( fileContent . substring ( 0 , 100 ) ) } ${ fileContent . length > 100 ? '...' : '' } </pre>
329- </div>
330- ` ;
331- } else if ( process . file . endsWith ( '.sh' ) || process . file . endsWith ( '.bash' ) ) {
332- thumbnailContent = `
333- <div class="code-preview">
334- <div class="code-preview-header">
335- <span>${ commandIcon } </span>
336- <span class="file-icon" style="background: #4EAA25; color: white;">BASH</span>
337- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
338- </div>
339- <pre class="code-snippet">${ this . escapeHTML ( fileContent . substring ( 0 , 100 ) ) } ${ fileContent . length > 100 ? '...' : '' } </pre>
340- </div>
341- ` ;
342- } else if ( / \. ( j p g | j p e g | p n g | g i f | s v g ) $ / i. test ( process . file ) ) {
343- thumbnailContent = `
344- <div class="text-preview">
345- <div class="text-preview-header">
346- <span>${ commandIcon } </span>
347- <span class="file-icon" style="background: #f06; color: white;">IMG</span>
348- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
349- </div>
350- <div class="text-content">Image file</div>
351- </div>
352- ` ;
353- } else if ( process . file . endsWith ( '.pdf' ) ) {
354- thumbnailContent = `
355- <div class="text-preview">
356- <div class="text-preview-header">
357- <span>${ commandIcon } </span>
358- <span class="file-icon" style="background: #f40f02; color: white;">PDF</span>
359- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
360- </div>
361- <div class="text-content">PDF Document</div>
362- </div>
363- ` ;
364- } else if ( process . file . endsWith ( '.txt' ) || process . file . endsWith ( '.md' ) || process . file . endsWith ( '.log' ) ) {
365- thumbnailContent = `
366- <div class="text-preview">
367- <div class="text-preview-header">
368- <span>${ commandIcon } </span>
369- <span class="file-icon" style="background: #eee; color: #333;">TXT</span>
370- <span>${ process . file . split ( '/' ) . pop ( ) } </span>
371- </div>
372- <div class="text-content">${ this . escapeHTML ( fileContent . substring ( 0 , 200 ) ) } ${ fileContent . length > 200 ? '...' : '' } </div>
373- </div>
374- ` ;
375- }
376- }
377- }
378- // Check if this is a web service
379- else if ( process . command && ( process . command . includes ( 'nginx' ) || process . command . includes ( 'apache' ) || process . command . includes ( 'http' ) ) ) {
380- thumbnailContent = `
381- <div class="web-service-preview">
382- <div class="web-service-header">
383- <span>${ commandIcon } </span>
384- ${ process . port ? `<span class="port-badge">:${ process . port } </span>` : '' }
385- </div>
386- <div class="browser-mockup">
387- <div class="browser-bar"></div>
388- <div class="browser-content"></div>
274+ // Create metrics visualization that will be used in all previews
275+ const metricsHTML = `
276+ <div class="process-metrics">
277+ <div class="metric-item">
278+ <div class="metric-label">CPU</div>
279+ <div class="metric-value">${ process . cpu . toFixed ( 1 ) } %</div>
280+ <div class="metric-bar">
281+ <div class="metric-fill cpu-fill" style="width: ${ Math . min ( process . cpu , 100 ) } %"></div>
389282 </div>
390283 </div>
391- ` ;
392- }
393- // Check if this is a database service
394- else if ( process . command && ( process . command . includes ( 'mysql' ) || process . command . includes ( 'postgres' ) || process . command . includes ( 'mongo' ) ) ) {
395- thumbnailContent = `
396- <div class="service-preview">
397- <div class="service-header">
398- <span>${ commandIcon } </span>
399- </div>
400- <div class="service-content">
401- <div class="service-status">Running</div>
402- <div class="service-metrics">
403- <div class="metric">CPU: ${ process . cpu . toFixed ( 1 ) } %</div>
404- <div class="metric">MEM: ${ process . memory . toFixed ( 1 ) } %</div>
405- </div>
284+ <div class="metric-item">
285+ <div class="metric-label">MEM</div>
286+ <div class="metric-value">${ process . memory . toFixed ( 1 ) } %</div>
287+ <div class="metric-bar">
288+ <div class="metric-fill mem-fill" style="width: ${ Math . min ( process . memory , 100 ) } %"></div>
406289 </div>
407290 </div>
408- ` ;
409- }
410- // Check if this is a port listener
411- else if ( process . port ) {
412- thumbnailContent = `
413- <div class="port-preview">
414- <div class="port-header ">
415- <span> ${ commandIcon } </span >
416- <span class="port-badge">: ${ process . port } </span>
291+ </div>
292+ ` ;
293+
294+ // Check if this is a web service (has a port)
295+ if ( process . port ) {
296+ return `
297+ <div class="web-service-preview ">
298+ <div class="preview-header" >
299+ <span class="preview-title">Web Service on Port ${ process . port } </span>
417300 </div>
418- <div class="port-details ">
419- <div class="port-status active"> </div>
420- <div class="port-info">TCP ${ process . port } </div>
301+ <div class="preview-content ">
302+ <div class="port-badge">: ${ process . port } </div>
303+ ${ metricsHTML }
421304 </div>
422305 </div>
423306 ` ;
424307 }
425- // Generic process
426- else if ( process . command ) {
427- thumbnailContent = `
428- <div class="generic-preview">
429- <div class="process-header">
430- <span>${ commandIcon } </span>
431- <span class="process-pid">${ process . pid } </span>
432- </div>
433- <div class="process-content">
434- <div class="process-command">${ this . escapeHTML ( process . command ) } </div>
435- <div class="process-metrics">
436- <div class="metric">CPU: ${ process . cpu . toFixed ( 1 ) } %</div>
437- <div class="metric">MEM: ${ process . memory . toFixed ( 1 ) } %</div>
308+
309+ // Check if this is a text file
310+ const command = process . command || '' ;
311+ if ( command . match ( / \. ( t x t | m d | l o g | j s o n | j s | p y | h t m l | c s s ) $ / i) ) {
312+ const fileType = command . split ( '.' ) . pop ( ) . toLowerCase ( ) ;
313+ let fileContent = '' ;
314+
315+ try {
316+ if ( this . fileSystemManager ) {
317+ fileContent = this . fileSystemManager . getFileContent ( command ) ;
318+
319+ // Handle HTML content differently
320+ if ( fileType === 'html' ) {
321+ return `
322+ <div class="html-preview">
323+ <div class="preview-header">
324+ <span class="preview-title">HTML Preview</span>
325+ </div>
326+ <iframe srcdoc="${ fileContent . replace ( / " / g, '"' ) } " style="width:100%; height:70%; transform: scale(0.2); transform-origin: 0 0; border: none;"></iframe>
327+ ${ metricsHTML }
328+ </div>
329+ ` ;
330+ }
331+
332+ // For code files, show syntax highlighted preview
333+ if ( [ 'js' , 'py' , 'css' , 'json' ] . includes ( fileType ) ) {
334+ return `
335+ <div class="code-preview">
336+ <div class="preview-header">
337+ <span class="preview-title">${ fileType . toUpperCase ( ) } File</span>
338+ </div>
339+ <pre class="code-content ${ fileType } -content">${ fileContent . substring ( 0 , 100 ) } ${ fileContent . length > 100 ? '...' : '' } </pre>
340+ ${ metricsHTML }
341+ </div>
342+ ` ;
343+ }
344+
345+ // For other text files
346+ return `
347+ <div class="text-preview">
348+ <div class="preview-header">
349+ <span class="preview-title">Text File</span>
350+ </div>
351+ <div class="text-content">${ fileContent . substring ( 0 , 100 ) } ${ fileContent . length > 100 ? '...' : '' } </div>
352+ ${ metricsHTML }
438353 </div>
439- </div>
440- </div>
441- ` ;
354+ ` ;
355+ }
356+ } catch ( error ) {
357+ console . error ( 'Error generating preview for file:' , error ) ;
358+ }
442359 }
443360
444- // Wrap the content in a div with the appropriate class
445- if ( thumbnailContent ) {
446- return `<div class="${ thumbnailClass } " data-pid="${ process . pid } ">${ thumbnailContent } </div>` ;
447- }
448-
449- return '' ;
361+ // Generate command icon for use in thumbnails
362+ const commandIcon = this . generateCommandWithIcon ( process ) ;
363+
364+ // Default generic preview
365+ return `
366+ <div class="generic-preview">
367+ <div class="preview-header">
368+ <span class="preview-title"></span>
369+ </div>
370+ <div class="preview-content">
371+ <div class="command-display">${ commandIcon } </div>
372+ ${ metricsHTML }
373+ </div>
374+ </div>
375+ ` ;
450376 }
451377
452378 /**
0 commit comments