This commit is contained in:
duanfuxiang
2025-01-05 11:51:39 +08:00
commit 0c7ee142cb
215 changed files with 20611 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
import { Change, diffLines } from 'diff'
import { CheckIcon, X } from 'lucide-react'
import { getIcon } from 'obsidian'
import { useState } from 'react'
import { ApplyViewState } from '../../ApplyView'
import { useApp } from '../../contexts/AppContext'
export default function ApplyViewRoot({
state,
close,
}: {
state: ApplyViewState
close: () => void
}) {
const acceptIcon = getIcon('check')
const rejectIcon = getIcon('x')
const excludeIcon = getIcon('x')
const app = useApp()
const [diff, setDiff] = useState<Change[]>(
diffLines(state.originalContent, state.newContent),
)
const handleAccept = async () => {
const newContent = diff
.filter((change) => !change.removed)
.map((change) => change.value)
.join('')
await app.vault.modify(state.file, newContent)
close()
}
const handleReject = async () => {
close()
}
const excludeDiffLine = (index: number) => {
setDiff((prevDiff) => {
const newDiff = [...prevDiff]
const change = newDiff[index]
if (change.added) {
// Remove the entry if it's an added line
return newDiff.filter((_, i) => i !== index)
} else if (change.removed) {
change.removed = false
}
return newDiff
})
}
const acceptDiffLine = (index: number) => {
setDiff((prevDiff) => {
const newDiff = [...prevDiff]
const change = newDiff[index]
if (change.added) {
change.added = false
} else if (change.removed) {
// Remove the entry if it's a removed line
return newDiff.filter((_, i) => i !== index)
}
return newDiff
})
}
return (
<div id="infio-apply-view">
<div className="view-header">
<div className="view-header-left">
<div className="view-header-nav-buttons"></div>
</div>
<div className="view-header-title-container mod-at-start">
<div className="view-header-title">
Applying: {state?.file?.name ?? ''}
</div>
<div className="view-actions">
<button
className="clickable-icon view-action infio-approve-button"
aria-label="Accept changes"
onClick={handleAccept}
>
{acceptIcon && <CheckIcon size={14} />}
Accept
</button>
<button
className="clickable-icon view-action infio-reject-button"
aria-label="Reject changes"
onClick={handleReject}
>
{rejectIcon && <X size={14} />}
Reject
</button>
</div>
</div>
</div>
<div className="view-content">
<div className="markdown-source-view cm-s-obsidian mod-cm6 node-insert-event is-readable-line-width is-live-preview is-folding show-properties">
<div className="cm-editor">
<div className="cm-scroller">
<div className="cm-sizer">
<div className="infio-inline-title">
{state?.file?.name
? state.file.name.replace(/\.[^/.]+$/, '')
: ''}
</div>
{diff.map((part, index) => (
<div
key={index}
className={`infio-diff-line ${part.added ? 'added' : part.removed ? 'removed' : ''}`}
>
<div style={{ width: '100%' }}>{part.value}</div>
{(part.added || part.removed) && (
<div className="infio-diff-line-actions">
<button
aria-label="Accept line"
onClick={() => acceptDiffLine(index)}
className="infio-accept"
>
{acceptIcon && 'Y'}
</button>
<button
aria-label="Exclude line"
onClick={() => excludeDiffLine(index)}
className="infio-exclude"
>
{excludeIcon && 'N'}
</button>
</div>
)}
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
)
}