Упрощение git: только просмотр с diff, без словного уровня, render без побочек

- История: убран таб текстового diff — только Просмотр версии с подсветкой; пустые состояния через emptyMessage
- GitManager: удалены fileDiffText/fileDiffHtml (+escHtml), остался fileContentAt/workdirContent/history/restore
- MdParser: удалён словный merge (плейсхолдеры/tokenize/risiko), текст — отдельными del/add как diff; renderInner без сброса codeBlocks, render() — clear+renderInner; убраны save/restore хаки
- Тесты обновлены
This commit is contained in:
2026-09-06 20:49:14 +03:00
parent 781e1dfc12
commit f6074df0fc
7 changed files with 67 additions and 360 deletions
+29 -77
View File
@@ -28,9 +28,9 @@ Dialog {
property var historyModel: []
property int selectedIndex: -1
property string selectedHash: ""
property string diffHtml: ""
property string versionContent: ""
property string currentContent: ""
property string emptyMessage: qsTr("Нет версии для просмотра")
property bool busy: false
function fileDirOf(p) {
@@ -62,7 +62,7 @@ Dialog {
historyModel = []
versionContent = ""
currentContent = ""
diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Файл не выбран") + "</p>"
emptyMessage = qsTr("Файл не выбран")
return
}
busy = true
@@ -79,16 +79,11 @@ Dialog {
selectedHash = ""
versionContent = ""
currentContent = ""
const hasFile = filePath.length>0
if (hasFile) {
const st = gitManager.fileGitStatus(vaultPath, filePath)
if (st === "неотслеживается" || st === "новый") {
diffHtml = "<p style='color:" + Theme.warningText + "'>" + qsTr("История пуста — файл ещё не сохранён в git. Сохраните файл, и здесь появится первая версия.") + "</p>"
} else {
diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Нет версий для этого файла") + "</p>"
}
const st = gitManager.fileGitStatus(vaultPath, filePath)
if (st === "неотслеживается" || st === "новый") {
emptyMessage = qsTr("История пуста — файл ещё не сохранён в git. Сохраните файл, и здесь появится первая версия.")
} else {
diffHtml = ""
emptyMessage = qsTr("Нет версий для этого файла")
}
}
busy = false
@@ -96,16 +91,12 @@ Dialog {
function updateDiff() {
if (selectedHash.length===0) {
diffHtml = ""
versionContent = ""
currentContent = ""
return
}
// свежее содержимое с диска — diff всегда актуален, даже если файл правили при открытом диалоге
currentContent = gitManager.workdirContent(filePath)
const html = gitManager.fileDiffHtml(vaultPath, filePath, selectedHash)
if (html.length===0) diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Нет изменений") + "</p>"
else diffHtml = html
// содержимое версии — сырой markdown, отрисуется через MarkdownView как в «Просмотре»,
// с подсветкой отличий от текущего файла прямо там
versionContent = gitManager.fileContentAt(vaultPath, filePath, selectedHash)
@@ -292,87 +283,48 @@ Dialog {
}
}
// Правая панель — diff и превью
// Правая панель — версия как кнопка «Просмотр», с подсветкой отличий прямо там
ColumnLayout {
SplitView.fillWidth: true
SplitView.minimumWidth: 300
spacing: 0
TabBar {
id: tabBar
Layout.fillWidth: true
TabButton { text: qsTr("Изменения") }
TabButton { text: qsTr("Просмотр версии") }
}
StackLayout {
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: tabBar.currentIndex
// Diff вкладка
Rectangle {
color: Theme.editorBg
border.color: Theme.divider
ScrollView {
anchors.fill: parent
anchors.margins: 6
clip: true
ScrollBar.vertical: ScrollBar {}
TextArea {
id: diffArea
readOnly: true
textFormat: Text.RichText
wrapMode: Text.Wrap
color: Theme.text
selectionColor: Theme.selectionBg
text: root.diffHtml
background: Rectangle { color: Theme.editorBg }
font.family: "Menlo, monospace"
font.pixelSize: 12
}
}
}
// Просмотр версии — как кнопка «Просмотр» в редакторе
Rectangle {
color: Theme.editorBg
border.color: Theme.divider
ScrollView {
id: versionScroll
anchors.fill: parent
anchors.margins: 6
clip: true
ScrollBar.vertical: ScrollBar {}
Column {
width: versionScroll.availableWidth
MarkdownView {
id: versionPreview
width: parent.width
markdown: root.versionContent
compareMarkdown: root.currentContent
vaultRoot: root.vaultPath
fileDir: root.fileDirOf(root.filePath)
emptyText: qsTr("Нет версии для просмотра")
onLinkActivated: (href) => root.handleHistoryLink(href)
}
color: Theme.editorBg
border.color: Theme.divider
ScrollView {
id: versionScroll
anchors.fill: parent
anchors.margins: 6
clip: true
ScrollBar.vertical: ScrollBar {}
Column {
width: versionScroll.availableWidth
MarkdownView {
id: versionPreview
width: parent.width
markdown: root.versionContent
compareMarkdown: root.currentContent
vaultRoot: root.vaultPath
fileDir: root.fileDirOf(root.filePath)
emptyText: root.emptyMessage
onLinkActivated: (href) => root.handleHistoryLink(href)
}
}
}
}
// Легенда — цвета отличий от текущего файла (обе вкладки)
// Легенда — цвета отличий от текущего файла
Row {
Layout.fillWidth: true
Layout.margins: 6
spacing: 12
Row { spacing: 4; Rectangle { width:12; height:12; color:"#7322C55E"; border.color:"#1a7f37"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("добавлено"); color: Theme.textMuted; font.pixelSize:10 } }
Row { spacing: 4; Rectangle { width:12; height:12; color:"#73F43F5E"; border.color:"#e5484d"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("удалено"); color: Theme.textMuted; font.pixelSize:10 } }
Row { visible: tabBar.currentIndex === 0; spacing: 4; Rectangle { width:12; height:12; color:"#ddf4ff"; border.color:"#0969da"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("заголовок"); color: Theme.textMuted; font.pixelSize:10 } }
Label {
text: tabBar.currentIndex === 0
? qsTr("Сравнение выбранной версии с текущим файлом")
: qsTr("Версия с подсветкой отличий от текущего файла")
text: qsTr("Версия с подсветкой отличий от текущего файла")
color: Theme.textFaint
font.pixelSize: 10
Layout.fillWidth: true