1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Showing colors in logs (#1419)

* Converting ansi values to colored html

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Rewriting AnsiUp colors for search overlay

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2020-11-18 08:31:36 +03:00 committed by GitHub
parent 6fd0bebdd6
commit 960bbe6813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 33 deletions

View File

@ -1,4 +1,7 @@
.PodLogs {
--overlay-bg: #8cc474b8;
--overlay-active-bg: orange;
.logs {
@include custom-scrollbar;
@ -11,14 +14,6 @@
background: $logsBackground;
flex-grow: 1;
.find-overlay {
position: absolute;
border-radius: 2px;
background-color: #8cc474;
margin-top: 4px;
opacity: 0.5;
}
.VirtualList {
height: 100%;
@ -29,19 +24,30 @@
font-family: $font-monospace;
font-size: smaller;
white-space: pre;
-webkit-font-smoothing: auto; // Better readability on non-retina screens
&:hover {
background: $logRowHoverBackground;
}
span {
-webkit-font-smoothing: auto; // Better readability on non-retina screens
}
span.overlay {
border-radius: 2px;
background-color: #8cc474b8;
-webkit-font-smoothing: auto;
background-color: var(--overlay-bg);
span {
background-color: var(--overlay-bg)!important; // Rewriting inline styles from AnsiUp library
}
&.active {
background-color: orange;
background-color: var(--overlay-active-bg);
span {
background-color: var(--overlay-active-bg)!important; // Rewriting inline styles from AnsiUp library
}
}
}
}
@ -49,25 +55,6 @@
}
}
.new-logs-sep {
position: relative;
display: block;
height: 0;
border-top: 1px solid $primary;
margin: $margin * 2 0;
&:after {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
content: 'new';
background: $primary;
color: white;
padding: $padding / 3;
border-radius: $radius;
}
}
.jump-to-bottom {
position: absolute;
right: 30px;

View File

@ -1,5 +1,7 @@
import "./pod-logs.scss";
import React from "react";
import AnsiUp from 'ansi_up';
import DOMPurify from "dompurify"
import { Trans } from "@lingui/macro";
import { action, computed, observable, reaction } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react";
@ -33,6 +35,7 @@ export class PodLogs extends React.Component<Props> {
private logsElement = React.createRef<HTMLDivElement>(); // A reference for outer container in VirtualList
private virtualListRef = React.createRef<VirtualList>(); // A reference for VirtualList component
private lastLineIsShown = true; // used for proper auto-scroll content after refresh
private colorConverter = new AnsiUp();
componentDidMount() {
disposeOnUnmount(this, [
@ -185,6 +188,7 @@ export class PodLogs extends React.Component<Props> {
const { searchQuery, isActiveOverlay } = searchStore;
const item = this.logs[rowIndex];
const contents: React.ReactElement[] = [];
const ansiToHtml = (ansi: string) => DOMPurify.sanitize(this.colorConverter.ansi_to_html(ansi));
if (searchQuery) { // If search is enabled, replace keyword with backgrounded <span>
// Case-insensitive search (lowercasing query and keywords in line)
const regex = new RegExp(searchStore.escapeRegex(searchQuery), "gi");
@ -195,19 +199,26 @@ export class PodLogs extends React.Component<Props> {
pieces.forEach((piece, index) => {
const active = isActiveOverlay(rowIndex, index);
const lastItem = index === pieces.length - 1;
const overlayValue = matches.next().value;
const overlay = !lastItem ?
<span className={cssNames({ active })}>{matches.next().value}</span> :
<span
className={cssNames("overlay", { active })}
dangerouslySetInnerHTML={{ __html: ansiToHtml(overlayValue) }}
/> :
null
contents.push(
<React.Fragment key={piece + index}>
{piece}{overlay}
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(piece) }} />
{overlay}
</React.Fragment>
);
})
}
return (
<div className={cssNames("LogRow")}>
{contents.length > 1 ? contents : item}
{contents.length > 1 ? contents : (
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(item) }} />
)}
</div>
);
}