mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Move LogRow to its own file
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
da8570d974
commit
f09974fd1f
@ -17,11 +17,11 @@
|
||||
width: 100%;
|
||||
font-family: var(--font-monospace);
|
||||
font-size: smaller;
|
||||
padding: 0 16px;
|
||||
line-height: 120%;
|
||||
|
||||
> * {
|
||||
-webkit-font-smoothing: auto; // Better readability on non-retina screens
|
||||
padding: 2px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
import styles from "./log-list.module.scss";
|
||||
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import AnsiUp from 'ansi_up';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { SearchStore } from '../../../search-store/search-store';
|
||||
import { cssNames } from '../../../utils';
|
||||
import type { LogTabViewModel } from './logs-view-model';
|
||||
import { LogRow } from "./log-row";
|
||||
|
||||
export interface LogListProps {
|
||||
model: LogTabViewModel;
|
||||
@ -118,51 +115,3 @@ export const LogList = observer(({ model }: LogListProps) => {
|
||||
)
|
||||
});
|
||||
|
||||
const colorConverter = new AnsiUp();
|
||||
|
||||
function LogRow({ rowIndex, model }: { rowIndex: number; model: LogTabViewModel }) {
|
||||
const { searchQuery, isActiveOverlay } = model.searchStore;
|
||||
const log = model.visibleLogs.get()[rowIndex];
|
||||
const contents: React.ReactElement[] = [];
|
||||
const ansiToHtml = (ansi: string) => DOMPurify.sanitize(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");
|
||||
const matches = log.matchAll(regex);
|
||||
const modified = log.replace(regex, match => match.toLowerCase());
|
||||
// Splitting text line by keyword
|
||||
const pieces = modified.split(searchQuery.toLowerCase());
|
||||
|
||||
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("overlay", { active })}
|
||||
dangerouslySetInnerHTML={{ __html: ansiToHtml(overlayValue) }}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
|
||||
contents.push(
|
||||
<React.Fragment key={piece + index}>
|
||||
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(piece) }} />
|
||||
{overlay}
|
||||
</React.Fragment>,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cssNames("LogRow")}>
|
||||
{contents.length > 1 ? contents : (
|
||||
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(log) }} />
|
||||
)}
|
||||
{/* For preserving copy-paste experience and keeping line breaks */}
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
20
src/renderer/components/dock/logs/log-row.module.scss
Normal file
20
src/renderer/components/dock/logs/log-row.module.scss
Normal file
@ -0,0 +1,20 @@
|
||||
.overlay {
|
||||
--overlay-bg: #8cc474b8;
|
||||
--overlay-active-bg: orange;
|
||||
|
||||
border-radius: 2px;
|
||||
-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: var(--overlay-active-bg);
|
||||
|
||||
span {
|
||||
background-color: var(--overlay-active-bg)!important; // Rewriting inline styles from AnsiUp library
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/renderer/components/dock/logs/log-row.tsx
Normal file
57
src/renderer/components/dock/logs/log-row.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import styles from "./log-row.module.scss";
|
||||
|
||||
import AnsiUp from 'ansi_up';
|
||||
import DOMPurify from 'dompurify';
|
||||
import React from 'react';
|
||||
import { SearchStore } from '../../../search-store/search-store';
|
||||
import { cssNames } from '../../../utils';
|
||||
import type { LogTabViewModel } from './logs-view-model';
|
||||
|
||||
const colorConverter = new AnsiUp();
|
||||
|
||||
export function LogRow({ rowIndex, model }: { rowIndex: number; model: LogTabViewModel }) {
|
||||
const { searchQuery, isActiveOverlay } = model.searchStore;
|
||||
const log = model.visibleLogs.get()[rowIndex];
|
||||
const contents: React.ReactElement[] = [];
|
||||
const ansiToHtml = (ansi: string) => DOMPurify.sanitize(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");
|
||||
const matches = log.matchAll(regex);
|
||||
const modified = log.replace(regex, match => match.toLowerCase());
|
||||
// Splitting text line by keyword
|
||||
const pieces = modified.split(searchQuery.toLowerCase());
|
||||
|
||||
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(styles.overlay, { [styles.active]: active })}
|
||||
dangerouslySetInnerHTML={{ __html: ansiToHtml(overlayValue) }}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
|
||||
contents.push(
|
||||
<React.Fragment key={piece + index}>
|
||||
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(piece) }} />
|
||||
{overlay}
|
||||
</React.Fragment>,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{contents.length > 1 ? contents : (
|
||||
<span dangerouslySetInnerHTML={{ __html: ansiToHtml(log) }} />
|
||||
)}
|
||||
{/* For preserving copy-paste experience and keeping line breaks */}
|
||||
<br />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user