Move FilesTabBar out of DiffView

This commit is contained in:
Silvano Cerza 2025-02-22 17:02:38 +01:00
parent ca0049c383
commit 19f797c77a
2 changed files with 152 additions and 119 deletions

View file

@ -7,7 +7,6 @@ import { createDiffHighlightPlugin } from "./diff-highlight-plugin";
import EditorPane from "./editor-pane";
import ActionsGutter from "./actions-gutter";
import * as React from "react";
import FilesTabBar from "./files-tab-bar";
// Add styles for diff highlighting
const styles = document.createElement("style");
@ -54,117 +53,105 @@ const DiffView: React.FC<DiffViewProps> = ({
return (
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}
>
<FilesTabBar
files={["this", "that", "those"]}
onTabChange={(filename: string) => console.log(`Clicked ${filename}`)}
/>
<div
style={{
width: "100%",
height: "100%",
display: "flex",
overflow: "hidden",
}}
>
<div style={{ flex: 1, overflow: "hidden" }}>
<EditorPane
content={oldText}
highlightPluginSpec={{
diff: diffs,
isOriginal: true,
}}
onEditorUpdate={handleEditorReady}
onContentChange={onOldTextChange}
onScrollTopUpdate={setLeftEditorTopOffset}
/>
</div>
<div style={{ minWidth: "160px", width: "auto" }}>
<ActionsGutter
diffChunks={diffs}
lineHeight={lineHeight}
leftEditorTopOffset={leftEditorTopOffset}
rightEditorTopLineOffset={rightEditorTopOffset}
onAcceptLeft={(chunk: DiffChunk) => {
if (chunk.type === "add") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
0,
...newText
.split("\n")
.slice(chunk.startRightLine - 1, chunk.endRightLine - 1),
);
onOldTextChange(oldLines.join("\n"));
} else if (chunk.type === "modify") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
chunk.endLeftLine - chunk.startLeftLine,
...newText
.split("\n")
.slice(chunk.startRightLine - 1, chunk.endRightLine - 1),
);
onOldTextChange(oldLines.join("\n"));
}
}}
onAcceptRight={(chunk: DiffChunk) => {
if (chunk.type === "remove") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
0,
...oldText
.split("\n")
.slice(chunk.startLeftLine - 1, chunk.endLeftLine - 1),
);
onNewTextChange(newLines.join("\n"));
} else if (chunk.type === "modify") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
chunk.endRightLine - chunk.startRightLine,
...oldText
.split("\n")
.slice(chunk.startLeftLine - 1, chunk.endLeftLine - 1),
);
onNewTextChange(newLines.join("\n"));
}
}}
onReject={(chunk: DiffChunk) => {
if (chunk.type === "add") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
chunk.endRightLine - chunk.startRightLine,
);
onNewTextChange(newLines.join("\n"));
} else if (chunk.type === "remove") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
chunk.endLeftLine - chunk.startLeftLine,
);
onOldTextChange(oldLines.join("\n"));
}
}}
/>
</div>
<div style={{ flex: 1, overflow: "hidden" }}>
<EditorPane
content={newText}
highlightPluginSpec={{
diff: diffs,
isOriginal: false,
}}
onContentChange={onNewTextChange}
onScrollTopUpdate={setRightEditorTopOffset}
/>
</div>
<div style={{ flex: 1, overflow: "hidden" }}>
<EditorPane
content={oldText}
highlightPluginSpec={{
diff: diffs,
isOriginal: true,
}}
onEditorUpdate={handleEditorReady}
onContentChange={onOldTextChange}
onScrollTopUpdate={setLeftEditorTopOffset}
/>
</div>
<div style={{ minWidth: "160px", width: "auto" }}>
<ActionsGutter
diffChunks={diffs}
lineHeight={lineHeight}
leftEditorTopOffset={leftEditorTopOffset}
rightEditorTopLineOffset={rightEditorTopOffset}
onAcceptLeft={(chunk: DiffChunk) => {
if (chunk.type === "add") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
0,
...newText
.split("\n")
.slice(chunk.startRightLine - 1, chunk.endRightLine - 1),
);
onOldTextChange(oldLines.join("\n"));
} else if (chunk.type === "modify") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
chunk.endLeftLine - chunk.startLeftLine,
...newText
.split("\n")
.slice(chunk.startRightLine - 1, chunk.endRightLine - 1),
);
onOldTextChange(oldLines.join("\n"));
}
}}
onAcceptRight={(chunk: DiffChunk) => {
if (chunk.type === "remove") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
0,
...oldText
.split("\n")
.slice(chunk.startLeftLine - 1, chunk.endLeftLine - 1),
);
onNewTextChange(newLines.join("\n"));
} else if (chunk.type === "modify") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
chunk.endRightLine - chunk.startRightLine,
...oldText
.split("\n")
.slice(chunk.startLeftLine - 1, chunk.endLeftLine - 1),
);
onNewTextChange(newLines.join("\n"));
}
}}
onReject={(chunk: DiffChunk) => {
if (chunk.type === "add") {
const newLines = newText.split("\n");
newLines.splice(
chunk.startRightLine - 1,
chunk.endRightLine - chunk.startRightLine,
);
onNewTextChange(newLines.join("\n"));
} else if (chunk.type === "remove") {
const oldLines = oldText.split("\n");
oldLines.splice(
chunk.startLeftLine - 1,
chunk.endLeftLine - chunk.startLeftLine,
);
onOldTextChange(oldLines.join("\n"));
}
}}
/>
</div>
<div style={{ flex: 1, overflow: "hidden" }}>
<EditorPane
content={newText}
highlightPluginSpec={{
diff: diffs,
isOriginal: false,
}}
onContentChange={onNewTextChange}
onScrollTopUpdate={setRightEditorTopOffset}
/>
</div>
</div>
);

View file

@ -2,8 +2,8 @@ import { IconName, ItemView, WorkspaceLeaf } from "obsidian";
import { Root, createRoot } from "react-dom/client";
import DiffView from "./component";
import GitHubSyncPlugin from "src/main";
import { PluginContext } from "../hooks";
import * as React from "react";
import FilesTabBar from "./files-tab-bar";
export const CONFLICTS_RESOLUTION_VIEW_TYPE = "conflicts-resolution-view";
@ -40,6 +40,36 @@ let newText2 = `# Modified Title
Modified paragraph
New paragraph`;
let oldText3 = `# My Document
This is a modified test
Some new content here
This is a test
Some content here
Some line
Another line
Final line
asdfasdf`;
let newText3 = `# My Document
This is a modified test
Some new content here
This is a test
Some content here
Some line
Another line
Final line
asdfasdf`;
export class ConflictsResolutionView extends ItemView {
icon: IconName = "merge";
@ -61,20 +91,36 @@ export class ConflictsResolutionView extends ItemView {
async onOpen() {
const container = this.containerEl.children[1];
container.empty();
// We don't want any padding, the DiffView component will handle that
(container as HTMLElement).style.padding = "0";
const root: Root = createRoot(container);
const App = () => {
const [oldText, setOldText] = React.useState(oldText1);
const [newText, setNewText] = React.useState(newText1);
const [oldText, setOldText] = React.useState(oldText3);
const [newText, setNewText] = React.useState(newText3);
return (
<PluginContext.Provider value={this.plugin}>
<DiffView
oldText={oldText}
newText={newText}
onOldTextChange={setOldText}
onNewTextChange={setNewText}
/>
</PluginContext.Provider>
<React.StrictMode>
<div
style={{
height: "100%",
display: "flex",
flexDirection: "column",
}}
>
<FilesTabBar
files={["this", "that", "those"]}
onTabChange={(filename: string) =>
console.log(`Clicked ${filename}`)
}
/>
<DiffView
oldText={oldText}
newText={newText}
onOldTextChange={setOldText}
onNewTextChange={setNewText}
/>
</div>
</React.StrictMode>
);
};
root.render(<App />);