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

View file

@ -2,8 +2,8 @@ import { IconName, ItemView, WorkspaceLeaf } from "obsidian";
import { Root, createRoot } from "react-dom/client"; import { Root, createRoot } from "react-dom/client";
import DiffView from "./component"; import DiffView from "./component";
import GitHubSyncPlugin from "src/main"; import GitHubSyncPlugin from "src/main";
import { PluginContext } from "../hooks";
import * as React from "react"; import * as React from "react";
import FilesTabBar from "./files-tab-bar";
export const CONFLICTS_RESOLUTION_VIEW_TYPE = "conflicts-resolution-view"; export const CONFLICTS_RESOLUTION_VIEW_TYPE = "conflicts-resolution-view";
@ -40,6 +40,36 @@ let newText2 = `# Modified Title
Modified paragraph Modified paragraph
New 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 { export class ConflictsResolutionView extends ItemView {
icon: IconName = "merge"; icon: IconName = "merge";
@ -61,20 +91,36 @@ export class ConflictsResolutionView extends ItemView {
async onOpen() { async onOpen() {
const container = this.containerEl.children[1]; const container = this.containerEl.children[1];
container.empty(); 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 root: Root = createRoot(container);
const App = () => { const App = () => {
const [oldText, setOldText] = React.useState(oldText1); const [oldText, setOldText] = React.useState(oldText3);
const [newText, setNewText] = React.useState(newText1); const [newText, setNewText] = React.useState(newText3);
return ( return (
<PluginContext.Provider value={this.plugin}> <React.StrictMode>
<DiffView <div
oldText={oldText} style={{
newText={newText} height: "100%",
onOldTextChange={setOldText} display: "flex",
onNewTextChange={setNewText} flexDirection: "column",
/> }}
</PluginContext.Provider> >
<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 />); root.render(<App />);