Perfect! I've successfully added a text wrap toggle to the frontend diff viewer. Here's a summary of the changes: (#1219)
## Changes Made ### 1. **State Management** (`frontend/src/stores/useDiffViewStore.ts:11-13,22-23,29`) - Added `wrapText` boolean state (defaults to `false`) - Added `setWrapText` action to update the state - Exported `useWrapTextDiff` hook for components to access the state ### 2. **UI Toggle Component** (`frontend/src/components/diff-view-switch.tsx:1,8,28-29,32,100-121`) - Imported `WrapText` icon from `lucide-react` - Added a new toggle group for the text wrap feature - The toggle appears alongside the existing view mode and whitespace toggles - Uses the same UI pattern as the "Ignore Whitespace" toggle - Includes tooltip with internationalization support ### 3. **Diff Viewer Integration** (`frontend/src/components/DiffCard.tsx:31,84,300`) - Imported and used the `useWrapTextDiff` hook - Connected the `wrapText` state to the `DiffView` component's `diffViewWrap` prop - The `DiffView` component now responds to the toggle state ## How It Works - The toggle button appears in the diff view controls with a `WrapText` icon - Clicking the toggle switches between wrapped and unwrapped text in the diff viewer - The state is managed globally via Zustand, so all diff viewers share the same wrap preference - The default is set to `false` (no wrapping), preserving the original behavior - The feature follows the existing architectural patterns for the ignore whitespace and view mode toggles The implementation is complete and ready to use!
This commit is contained in:
committed by
GitHub
parent
44b7f749c5
commit
f651c64f7d
@@ -32,6 +32,7 @@ import { ReviewCommentRenderer } from '@/components/diff/ReviewCommentRenderer';
|
|||||||
import {
|
import {
|
||||||
useDiffViewMode,
|
useDiffViewMode,
|
||||||
useIgnoreWhitespaceDiff,
|
useIgnoreWhitespaceDiff,
|
||||||
|
useWrapTextDiff,
|
||||||
} from '@/stores/useDiffViewStore';
|
} from '@/stores/useDiffViewStore';
|
||||||
import { useProject } from '@/contexts/ProjectContext';
|
import { useProject } from '@/contexts/ProjectContext';
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ export default function DiffCard({
|
|||||||
const { comments, drafts, setDraft } = useReview();
|
const { comments, drafts, setDraft } = useReview();
|
||||||
const globalMode = useDiffViewMode();
|
const globalMode = useDiffViewMode();
|
||||||
const ignoreWhitespace = useIgnoreWhitespaceDiff();
|
const ignoreWhitespace = useIgnoreWhitespaceDiff();
|
||||||
|
const wrapText = useWrapTextDiff();
|
||||||
const { projectId } = useProject();
|
const { projectId } = useProject();
|
||||||
|
|
||||||
const oldName = diff.oldPath || undefined;
|
const oldName = diff.oldPath || undefined;
|
||||||
@@ -301,7 +303,7 @@ export default function DiffCard({
|
|||||||
<div>
|
<div>
|
||||||
<DiffView
|
<DiffView
|
||||||
diffFile={diffFile}
|
diffFile={diffFile}
|
||||||
diffViewWrap={false}
|
diffViewWrap={wrapText}
|
||||||
diffViewTheme={theme}
|
diffViewTheme={theme}
|
||||||
diffViewHighlight
|
diffViewHighlight
|
||||||
diffViewMode={
|
diffViewMode={
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Columns, FileText, Pilcrow } from 'lucide-react';
|
import { Columns, FileText, Pilcrow, WrapText } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import {
|
import {
|
||||||
useDiffViewMode,
|
useDiffViewMode,
|
||||||
useDiffViewStore,
|
useDiffViewStore,
|
||||||
useIgnoreWhitespaceDiff,
|
useIgnoreWhitespaceDiff,
|
||||||
|
useWrapTextDiff,
|
||||||
} from '@/stores/useDiffViewStore';
|
} from '@/stores/useDiffViewStore';
|
||||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
|
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
|
||||||
import {
|
import {
|
||||||
@@ -24,8 +25,11 @@ export default function DiffViewSwitch({ className }: Props) {
|
|||||||
const setMode = useDiffViewStore((s) => s.setMode);
|
const setMode = useDiffViewStore((s) => s.setMode);
|
||||||
const ignoreWhitespace = useIgnoreWhitespaceDiff();
|
const ignoreWhitespace = useIgnoreWhitespaceDiff();
|
||||||
const setIgnoreWhitespace = useDiffViewStore((s) => s.setIgnoreWhitespace);
|
const setIgnoreWhitespace = useDiffViewStore((s) => s.setIgnoreWhitespace);
|
||||||
|
const wrapText = useWrapTextDiff();
|
||||||
|
const setWrapText = useDiffViewStore((s) => s.setWrapText);
|
||||||
|
|
||||||
const whitespaceValue = ignoreWhitespace ? ['ignoreWhitespace'] : [];
|
const whitespaceValue = ignoreWhitespace ? ['ignoreWhitespace'] : [];
|
||||||
|
const wrapTextValue = wrapText ? ['wrapText'] : [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
@@ -92,6 +96,29 @@ export default function DiffViewSwitch({ className }: Props) {
|
|||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</ToggleGroup>
|
</ToggleGroup>
|
||||||
|
|
||||||
|
<ToggleGroup
|
||||||
|
type="multiple"
|
||||||
|
value={wrapTextValue}
|
||||||
|
onValueChange={(values) => setWrapText(values.includes('wrapText'))}
|
||||||
|
className="inline-flex gap-4"
|
||||||
|
aria-label={t('diff.wrapText', 'Wrap text')}
|
||||||
|
>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<ToggleGroupItem
|
||||||
|
value="wrapText"
|
||||||
|
aria-label={t('diff.wrapText', 'Wrap text')}
|
||||||
|
active={wrapText}
|
||||||
|
>
|
||||||
|
<WrapText className="h-4 w-4" />
|
||||||
|
</ToggleGroupItem>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="bottom">
|
||||||
|
{t('diff.wrapText', 'Wrap text')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</ToggleGroup>
|
||||||
</div>
|
</div>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ type State = {
|
|||||||
toggle: () => void;
|
toggle: () => void;
|
||||||
ignoreWhitespace: boolean;
|
ignoreWhitespace: boolean;
|
||||||
setIgnoreWhitespace: (value: boolean) => void;
|
setIgnoreWhitespace: (value: boolean) => void;
|
||||||
|
wrapText: boolean;
|
||||||
|
setWrapText: (value: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDiffViewStore = create<State>((set) => ({
|
export const useDiffViewStore = create<State>((set) => ({
|
||||||
@@ -17,8 +19,11 @@ export const useDiffViewStore = create<State>((set) => ({
|
|||||||
set((s) => ({ mode: s.mode === 'unified' ? 'split' : 'unified' })),
|
set((s) => ({ mode: s.mode === 'unified' ? 'split' : 'unified' })),
|
||||||
ignoreWhitespace: true,
|
ignoreWhitespace: true,
|
||||||
setIgnoreWhitespace: (value) => set({ ignoreWhitespace: value }),
|
setIgnoreWhitespace: (value) => set({ ignoreWhitespace: value }),
|
||||||
|
wrapText: false,
|
||||||
|
setWrapText: (value) => set({ wrapText: value }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useDiffViewMode = () => useDiffViewStore((s) => s.mode);
|
export const useDiffViewMode = () => useDiffViewStore((s) => s.mode);
|
||||||
export const useIgnoreWhitespaceDiff = () =>
|
export const useIgnoreWhitespaceDiff = () =>
|
||||||
useDiffViewStore((s) => s.ignoreWhitespace);
|
useDiffViewStore((s) => s.ignoreWhitespace);
|
||||||
|
export const useWrapTextDiff = () => useDiffViewStore((s) => s.wrapText);
|
||||||
|
|||||||
Reference in New Issue
Block a user