mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
fix some dark mode issues, still battling the terminal to display wget progress displays
This commit is contained in:
parent
86d38819bb
commit
8ccd9595f5
5 changed files with 52 additions and 114 deletions
|
|
@ -88,7 +88,6 @@
|
|||
"dependencies": {
|
||||
"@mantine/core": "^8.2.7",
|
||||
"@mantine/hooks": "^8.2.7",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"execa": "^9.6.0",
|
||||
"got": "^14.4.7",
|
||||
"lucide-react": "^0.541.0",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
Loader,
|
||||
Progress,
|
||||
rem,
|
||||
useComputedColorScheme,
|
||||
} from '@mantine/core';
|
||||
import { Download } from 'lucide-react';
|
||||
import { MouseEvent } from 'react';
|
||||
|
|
@ -46,6 +47,10 @@ export const DownloadCard = ({
|
|||
onMakeCurrent,
|
||||
onUpdate,
|
||||
}: DownloadCardProps) => {
|
||||
const computedColorScheme = useComputedColorScheme('light', {
|
||||
getInitialValueInEffect: false,
|
||||
});
|
||||
const isDark = computedColorScheme === 'dark';
|
||||
const renderActionButton = () => {
|
||||
if (hasUpdate && onUpdate) {
|
||||
return (
|
||||
|
|
@ -107,9 +112,8 @@ export const DownloadCard = ({
|
|||
radius="sm"
|
||||
padding="sm"
|
||||
{...(isCurrent && {
|
||||
c: 'blue',
|
||||
bg: 'blue.0',
|
||||
bd: '2px solid blue',
|
||||
bg: isDark ? 'dark.6' : 'gray.0',
|
||||
bd: `2px solid var(--mantine-color-${isDark ? 'blue-4' : 'blue-6'})`,
|
||||
})}
|
||||
>
|
||||
<Group justify="space-between" align="center">
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import {
|
||||
Box,
|
||||
ScrollArea,
|
||||
Text,
|
||||
ActionIcon,
|
||||
useMantineColorScheme,
|
||||
useComputedColorScheme,
|
||||
} from '@mantine/core';
|
||||
import { ChevronDown } from 'lucide-react';
|
||||
import Convert from 'ansi-to-html';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
import { UI } from '@/constants';
|
||||
|
||||
|
|
@ -39,19 +38,20 @@ const handleCarriageReturns = (
|
|||
} else {
|
||||
const lines = result.split('\n');
|
||||
if (lines.length > 0) {
|
||||
const lastLineIndex = lines.length - 1;
|
||||
const restOfData = newData.slice(i + 1);
|
||||
const nextCrOrLfIndex = restOfData.search(/[\r\n]/);
|
||||
const nextNewlinePos = restOfData.indexOf('\n');
|
||||
const replacementText =
|
||||
nextNewlinePos === -1
|
||||
? restOfData
|
||||
: restOfData.slice(0, nextNewlinePos);
|
||||
|
||||
if (nextCrOrLfIndex === -1) {
|
||||
lines[lastLineIndex] = restOfData;
|
||||
lines[lines.length - 1] = replacementText;
|
||||
result = lines.join('\n');
|
||||
break;
|
||||
} else {
|
||||
const replacement = restOfData.slice(0, nextCrOrLfIndex);
|
||||
lines[lastLineIndex] = replacement;
|
||||
result = lines.join('\n');
|
||||
i += 1 + nextCrOrLfIndex;
|
||||
|
||||
i += 1 + replacementText.length;
|
||||
if (nextNewlinePos !== -1) {
|
||||
result += '\n';
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
|
|
@ -64,64 +64,24 @@ const handleCarriageReturns = (
|
|||
}
|
||||
|
||||
return result;
|
||||
} catch {
|
||||
} catch (error) {
|
||||
window.electronAPI.logs.logError('Terminal CR Error', error as Error);
|
||||
return prevContent + newData;
|
||||
}
|
||||
};
|
||||
|
||||
export const TerminalTab = ({ onServerReady }: TerminalTabProps) => {
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
const computedColorScheme = useComputedColorScheme('light', {
|
||||
getInitialValueInEffect: false,
|
||||
});
|
||||
const [terminalContent, setTerminalContent] = useState<string>('');
|
||||
const [formattedContent, setFormattedContent] = useState<string>('');
|
||||
const [isUserScrolling, setIsUserScrolling] = useState<boolean>(false);
|
||||
const [shouldAutoScroll, setShouldAutoScroll] = useState<boolean>(true);
|
||||
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
||||
const viewportRef = useRef<HTMLDivElement>(null);
|
||||
const lastScrollTop = useRef<number>(0);
|
||||
const updateTimeoutRef = useRef<number | null>(null);
|
||||
const pendingContentRef = useRef<string>('');
|
||||
|
||||
const debouncedUpdateContent = useCallback((newContent: string) => {
|
||||
pendingContentRef.current = newContent;
|
||||
|
||||
if (updateTimeoutRef.current) {
|
||||
clearTimeout(updateTimeoutRef.current);
|
||||
}
|
||||
|
||||
updateTimeoutRef.current = window.setTimeout(() => {
|
||||
setTerminalContent(pendingContentRef.current);
|
||||
updateTimeoutRef.current = null;
|
||||
}, 16);
|
||||
}, []);
|
||||
|
||||
const converter = useRef(
|
||||
new Convert({
|
||||
fg: colorScheme === 'dark' ? '#ffffff' : '#000000',
|
||||
bg: colorScheme === 'dark' ? '#1a1b1e' : '#ffffff',
|
||||
newline: false,
|
||||
escapeXML: true,
|
||||
stream: false,
|
||||
})
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
converter.current = new Convert({
|
||||
fg: colorScheme === 'dark' ? '#ffffff' : '#000000',
|
||||
bg: colorScheme === 'dark' ? '#1a1b1e' : '#ffffff',
|
||||
newline: false,
|
||||
escapeXML: true,
|
||||
stream: false,
|
||||
});
|
||||
if (terminalContent) {
|
||||
setFormattedContent(converter.current.toHtml(terminalContent));
|
||||
}
|
||||
}, [colorScheme, terminalContent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (terminalContent) {
|
||||
setFormattedContent(converter.current.toHtml(terminalContent));
|
||||
}
|
||||
}, [terminalContent]);
|
||||
const isDark = computedColorScheme === 'dark';
|
||||
|
||||
const handleScroll = ({ y }: { y: number }) => {
|
||||
if (!viewportRef.current) return;
|
||||
|
|
@ -145,7 +105,7 @@ export const TerminalTab = ({ onServerReady }: TerminalTabProps) => {
|
|||
const viewport = viewportRef.current;
|
||||
viewport.scrollTop = viewport.scrollHeight;
|
||||
}
|
||||
}, [formattedContent, shouldAutoScroll, isUserScrolling]);
|
||||
}, [terminalContent, shouldAutoScroll, isUserScrolling]);
|
||||
|
||||
useEffect(() => {
|
||||
const cleanup = window.electronAPI.kobold.onKoboldOutput((data: string) => {
|
||||
|
|
@ -165,19 +125,12 @@ export const TerminalTab = ({ onServerReady }: TerminalTabProps) => {
|
|||
}
|
||||
}
|
||||
|
||||
const newContent = handleCarriageReturns(prev, newData);
|
||||
|
||||
if (newData.includes('\r') && !newData.includes('\n')) {
|
||||
debouncedUpdateContent(newContent);
|
||||
return prev;
|
||||
}
|
||||
|
||||
return newContent;
|
||||
return handleCarriageReturns(prev, newData);
|
||||
});
|
||||
});
|
||||
|
||||
return cleanup;
|
||||
}, [onServerReady, debouncedUpdateContent]);
|
||||
}, [onServerReady]);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
if (viewportRef.current) {
|
||||
|
|
@ -194,8 +147,7 @@ export const TerminalTab = ({ onServerReady }: TerminalTabProps) => {
|
|||
height: `calc(100vh - ${UI.HEADER_HEIGHT}px)`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor:
|
||||
colorScheme === 'dark'
|
||||
backgroundColor: isDark
|
||||
? 'var(--mantine-color-dark-filled)'
|
||||
: 'var(--mantine-color-gray-0)',
|
||||
borderRadius: 'inherit',
|
||||
|
|
@ -219,18 +171,19 @@ export const TerminalTab = ({ onServerReady }: TerminalTabProps) => {
|
|||
<div
|
||||
style={{
|
||||
margin: 0,
|
||||
fontFamily: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
lineHeight: 'inherit',
|
||||
color:
|
||||
colorScheme === 'dark'
|
||||
fontFamily:
|
||||
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||
fontSize: '14px',
|
||||
lineHeight: 1.4,
|
||||
color: isDark
|
||||
? 'var(--mantine-color-gray-0)'
|
||||
: 'var(--mantine-color-dark-filled)',
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordBreak: 'break-word',
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: formattedContent }}
|
||||
/>
|
||||
>
|
||||
{terminalContent}
|
||||
</div>
|
||||
)}
|
||||
</Box>
|
||||
</ScrollArea>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import { Stack, Text, Group, SegmentedControl, rem } from '@mantine/core';
|
||||
import { useMantineColorScheme } from '@mantine/core';
|
||||
import { useMantineColorScheme, useComputedColorScheme } from '@mantine/core';
|
||||
import { Sun, Moon, Monitor } from 'lucide-react';
|
||||
|
||||
export const AppearanceTab = () => {
|
||||
const { colorScheme, setColorScheme } = useMantineColorScheme();
|
||||
const computedColorScheme = useComputedColorScheme('light', {
|
||||
getInitialValueInEffect: false,
|
||||
});
|
||||
const isDark = computedColorScheme === 'dark';
|
||||
|
||||
return (
|
||||
<Stack gap="lg" h="100%">
|
||||
|
|
@ -22,14 +26,11 @@ export const AppearanceTab = () => {
|
|||
}
|
||||
styles={(theme) => ({
|
||||
indicator: {
|
||||
backgroundColor:
|
||||
colorScheme === 'dark'
|
||||
backgroundColor: isDark
|
||||
? theme.colors.dark[5]
|
||||
: theme.colors.gray[2],
|
||||
border: `1px solid ${
|
||||
colorScheme === 'dark'
|
||||
? theme.colors.dark[4]
|
||||
: theme.colors.gray[4]
|
||||
isDark ? theme.colors.dark[4] : theme.colors.gray[4]
|
||||
}`,
|
||||
},
|
||||
})}
|
||||
|
|
|
|||
19
yarn.lock
19
yarn.lock
|
|
@ -2233,17 +2233,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ansi-to-html@npm:^0.7.2":
|
||||
version: 0.7.2
|
||||
resolution: "ansi-to-html@npm:0.7.2"
|
||||
dependencies:
|
||||
entities: "npm:^2.2.0"
|
||||
bin:
|
||||
ansi-to-html: bin/ansi-to-html
|
||||
checksum: 10c0/031da78f716e7c6b0e391c64f7bc5e95f2d37123dcc3237d8c592dc35830dd0da05e0c3f3e3f8179856cfe5fd85c689d2ad85024b71b50014da9ef6e8fa021cf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"app-builder-bin@npm:5.0.0-alpha.12":
|
||||
version: 5.0.0-alpha.12
|
||||
resolution: "app-builder-bin@npm:5.0.0-alpha.12"
|
||||
|
|
@ -3603,13 +3592,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"entities@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "entities@npm:2.2.0"
|
||||
checksum: 10c0/7fba6af1f116300d2ba1c5673fc218af1961b20908638391b4e1e6d5850314ee2ac3ec22d741b3a8060479911c99305164aed19b6254bde75e7e6b1b2c3f3aa3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"env-paths@npm:^2.2.0":
|
||||
version: 2.2.1
|
||||
resolution: "env-paths@npm:2.2.1"
|
||||
|
|
@ -4409,7 +4391,6 @@ __metadata:
|
|||
"@typescript-eslint/eslint-plugin": "npm:^8.40.0"
|
||||
"@typescript-eslint/parser": "npm:^8.40.0"
|
||||
"@vitejs/plugin-react": "npm:^5.0.1"
|
||||
ansi-to-html: "npm:^0.7.2"
|
||||
cross-env: "npm:^10.0.0"
|
||||
cspell: "npm:^9.2.0"
|
||||
electron: "npm:^37.3.1"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue