Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Commit

Permalink
use arrows to navigate between selected ranges (#1075)
Browse files Browse the repository at this point in the history
  • Loading branch information
anastasiya1155 authored Oct 26, 2023
1 parent f455999 commit 8cd066b
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Token as TokenType } from '../../../types/prism';
import { hashCode, mergeRanges } from '../../../utils';
import { findElementInCurrentTab } from '../../../utils/domUtils';
import { CODE_LINE_HEIGHT } from '../../../consts/code';
import useKeyboardNavigation from '../../../hooks/useKeyboardNavigation';
import SelectionHandler from './SelectionHandler';
import SelectionRect from './SelectionRect';
import LinesContainer from './LazyLinesContainer';
Expand Down Expand Up @@ -51,6 +52,7 @@ const CodeContainerSelectable = ({
const [shouldScroll, setShouldScroll] = useState<'top' | 'bottom' | false>(
false,
);
const [currentFocusedRange, setCurrentFocusedRange] = useState(-1);

useEffect(() => {
if (scrollToIndex && ref.current) {
Expand Down Expand Up @@ -176,6 +178,48 @@ const CodeContainerSelectable = ({
});
}, [tokens.length]);

const handleKeyEvent = useCallback(
(e: KeyboardEvent) => {
if (
!['TEXTAREA', 'INPUT'].includes(
document.activeElement?.tagName || '',
) &&
!e.shiftKey &&
!e.ctrlKey &&
!e.metaKey &&
!e.altKey &&
currentSelection.length > 1
) {
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
e.preventDefault();
setCurrentFocusedRange((prev) => {
const newIndex =
e.key === 'ArrowDown'
? prev >= currentSelection.length - 1
? 0
: prev + 1
: prev <= 0
? currentSelection.length - 1
: prev - 1;
const lineNum = currentSelection[newIndex][0];
if (lineNum > -1) {
const line = findElementInCurrentTab(
`[data-line-number="${lineNum}"]`,
);
line?.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
}
return newIndex;
});
}
}
},
[currentSelection],
);
useKeyboardNavigation(handleKeyEvent);

return (
<div ref={ref} className="relative pb-16">
{currentSelection.map((r, i) => (
Expand Down
5 changes: 3 additions & 2 deletions client/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,5 +393,6 @@
"You've upgraded your account!": "You've upgraded your account!",
"Unlimited usage and premium features are activated.": "Unlimited usage and premium features are activated.",
"Let's go": "Let's go",
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate."
}
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.",
"<0></0><1></1> to navigate.": "<0></0><1></1> to navigate."
}
5 changes: 3 additions & 2 deletions client/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,6 @@
"Unlimited usage and premium features are activated.": "Se activan el uso ilimitado y las características premium.",
"You've upgraded your account!": "¡Has actualizado tu cuenta!",
"Let's go": "Vamos",
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "Límite de token alcanzado, esta respuesta puede estar incompleta. Para generar una respuesta completa, reduzca el número de tokens utilizados y regenerados."
}
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "Límite de token alcanzado, esta respuesta puede estar incompleta. Para generar una respuesta completa, reduzca el número de tokens utilizados y regenerados.",
"<0></0><1></1> to navigate.": "<0> </0> <1> </1> para navegar."
}
5 changes: 3 additions & 2 deletions client/src/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -391,5 +391,6 @@
"You've upgraded your account!": "アカウントをアップグレードしました!",
"Unlimited usage and premium features are activated.": "無制限の使用機能とプレミアム機能がアクティブになります。",
"Let's go": "さあ行こう",
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "到達したトークン制限は、この答えが不完全になる可能性があります。 完全な回答を生成するには、使用して再生するトークンの数を減らしてください。"
}
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "到達したトークン制限は、この答えが不完全になる可能性があります。 完全な回答を生成するには、使用して再生するトークンの数を減らしてください。",
"<0></0><1></1> to navigate.": "<0> </0> <1> </1>ナビゲートします。"
}
5 changes: 3 additions & 2 deletions client/src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,5 +399,6 @@
"Let's go": "我们走吧",
"You've upgraded your account!": "您已经升级了您的帐户!",
"Unlimited usage and premium features are activated.": "无限用法和高级功能被激活。",
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "达到令牌限制,此答案可能不完整。 要产生完整的答案,请减少使用和再生的代币数量。"
}
"Token limit reached, this answer may be incomplete. To generate a full answer, please reduce the number of tokens used and regenerate.": "达到令牌限制,此答案可能不完整。 要产生完整的答案,请减少使用和再生的代币数量。",
"<0></0><1></1> to navigate.": "<0> </0> <1> </1>导航。"
}
15 changes: 15 additions & 0 deletions client/src/pages/StudioTab/BlueChip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { memo, ReactElement } from 'react';

type Props = {
text: string | ReactElement;
};

const BlueChip = ({ text }: Props) => {
return (
<div className="h-5 px-1 flex items-center rounded-sm bg-bg-main/15 caption text-bg-main flex-shrink-0 w-fit select-none">
{text}
</div>
);
};

export default memo(BlueChip);
13 changes: 12 additions & 1 deletion client/src/pages/StudioTab/FilePanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import BreadcrumbsPath from '../../../components/BreadcrumbsPath';
import KeyboardChip from '../KeyboardChip';
import useKeyboardNavigation from '../../../hooks/useKeyboardNavigation';
import OverflowTracker from '../../../components/OverflowTracker';
import BlueChip from '../BlueChip';

type Props = {
setLeftPanel: Dispatch<SetStateAction<StudioLeftPanelDataType>>;
Expand Down Expand Up @@ -264,9 +265,19 @@ const FilePanel = ({
Only the selected lines (# - #) will be used as context.
</Trans>
) : (
<Trans>Only the selected ranges will be used as context.</Trans>
<>
<Trans>Only the selected ranges will be used as context.</Trans>
</>
)}
</p>
{selectedLines?.length > 1 && (
<div className="pointer-events-none select-none cursor-default flex gap-1 items-center">
<Trans>
<BlueChip text="↑" />
<BlueChip text="↓" /> to navigate.
</Trans>
</div>
)}
{!!selectedLines.length && (
<Button
variant="tertiary"
Expand Down
27 changes: 15 additions & 12 deletions client/src/pages/StudioTab/LinesBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import BlueChip from './BlueChip';

type Props = {
ranges: ([number, number] | [number])[];
Expand All @@ -9,18 +10,20 @@ type Props = {
const LinesBadge = ({ ranges, isShort }: Props) => {
const { t } = useTranslation();
return (
<div className="h-5 px-1 flex items-center rounded-sm bg-bg-main/15 caption text-bg-main flex-shrink-0 w-fit select-none">
{!ranges.length
? t('Whole file')
: ranges.length === 1
? isShort
? `${ranges[0][0] + 1} - ${ranges[0][1] ? ranges[0][1] + 1 : ''}`
: t('Lines # - #', {
start: ranges[0][0] + 1,
end: ranges[0][1] ? ranges[0][1] + 1 : '',
})
: t('# ranges', { count: ranges.length })}
</div>
<BlueChip
text={
!ranges.length
? t('Whole file')
: ranges.length === 1
? isShort
? `${ranges[0][0] + 1} - ${ranges[0][1] ? ranges[0][1] + 1 : ''}`
: t('Lines # - #', {
start: ranges[0][0] + 1,
end: ranges[0][1] ? ranges[0][1] + 1 : '',
})
: t('# ranges', { count: ranges.length })
}
/>
);
};

Expand Down

0 comments on commit 8cd066b

Please sign in to comment.