История: содержимое версии как кнопка Просмотр

- Вкладка Содержимое версии -> Просмотр версии: MarkdownView с markdown версии (vaultRoot/fileDir файла), как режим Просмотр в редакторе
- Ссылки в исторической версии только чтение: задачи/вики не трогаем, flora://open открывает в редакторе, внешние — в браузере, копирование кода с тостом Скопировано
- Легенда diff только на вкладке Изменения, emptyText для пустого состояния
This commit is contained in:
2026-09-06 18:57:45 +03:00
parent 9c8215b707
commit 3d04ac0095
2 changed files with 71 additions and 16 deletions
+69 -15
View File
@@ -29,8 +29,33 @@ Dialog {
property int selectedIndex: -1 property int selectedIndex: -1
property string selectedHash: "" property string selectedHash: ""
property string diffHtml: "" property string diffHtml: ""
property string versionContent: ""
property bool busy: false property bool busy: false
function fileDirOf(p) {
const i = p.lastIndexOf("/")
return i >= 0 ? p.substring(0, i) : ""
}
// Ссылки внутри просмотра исторической версии: только чтение, без правок
function handleHistoryLink(href) {
if (href.startsWith("flora://copycode/")) {
copyFeedback.text = qsTr("Скопировано!")
copyFeedback.visible = true
copyTimer.restart()
return
}
if (href.startsWith("flora://task/")) {
return // историческая версия — только чтение, галочки не переключаем
} else if (href.startsWith("flora://open/")) {
documentManager.openDocument(decodeURIComponent(href.substring(13)))
} else if (href.startsWith("flora://wiki/")) {
return // несуществующие заметки из истории не создаём
} else {
Qt.openUrlExternally(href)
}
}
function reload() { function reload() {
if (vaultPath.length===0 || filePath.length===0) { if (vaultPath.length===0 || filePath.length===0) {
historyModel = [] historyModel = []
@@ -49,6 +74,7 @@ Dialog {
} else { } else {
selectedIndex = -1 selectedIndex = -1
selectedHash = "" selectedHash = ""
versionContent = ""
const hasFile = filePath.length>0 const hasFile = filePath.length>0
if (hasFile) { if (hasFile) {
const st = gitManager.fileGitStatus(vaultPath, filePath) const st = gitManager.fileGitStatus(vaultPath, filePath)
@@ -67,14 +93,14 @@ Dialog {
function updateDiff() { function updateDiff() {
if (selectedHash.length===0) { if (selectedHash.length===0) {
diffHtml = "" diffHtml = ""
versionContent = ""
return return
} }
const html = gitManager.fileDiffHtml(vaultPath, filePath, selectedHash) const html = gitManager.fileDiffHtml(vaultPath, filePath, selectedHash)
if (html.length===0) diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Нет изменений") + "</p>" if (html.length===0) diffHtml = "<p style='color:" + Theme.textFaint + "'>" + qsTr("Нет изменений") + "</p>"
else diffHtml = html else diffHtml = html
// также обновляем превью содержимого версии // содержимое версии — сырой markdown, отрисуется через MarkdownView как в «Просмотре»
const content = gitManager.fileContentAt(vaultPath, filePath, selectedHash) versionContent = gitManager.fileContentAt(vaultPath, filePath, selectedHash)
previewArea.text = content
} }
onOpened: reload() onOpened: reload()
@@ -268,7 +294,7 @@ Dialog {
id: tabBar id: tabBar
Layout.fillWidth: true Layout.fillWidth: true
TabButton { text: qsTr("Изменения") } TabButton { text: qsTr("Изменения") }
TabButton { text: qsTr("Содержимое версии") } TabButton { text: qsTr("Просмотр версии") }
} }
StackLayout { StackLayout {
@@ -300,32 +326,37 @@ Dialog {
} }
} }
// Preview вкладка // Просмотр версии — как кнопка «Просмотр» в редакторе
Rectangle { Rectangle {
color: Theme.editorBg color: Theme.editorBg
border.color: Theme.divider border.color: Theme.divider
ScrollView { ScrollView {
id: versionScroll
anchors.fill: parent anchors.fill: parent
anchors.margins: 6 anchors.margins: 6
clip: true clip: true
ScrollBar.vertical: ScrollBar {} ScrollBar.vertical: ScrollBar {}
TextArea { Column {
id: previewArea width: versionScroll.availableWidth
readOnly: true MarkdownView {
wrapMode: Text.Wrap id: versionPreview
color: Theme.text width: parent.width
selectionColor: Theme.selectionBg markdown: root.versionContent
background: Rectangle { color: Theme.editorBg } vaultRoot: root.vaultPath
font.family: "Menlo, monospace" fileDir: root.fileDirOf(root.filePath)
font.pixelSize: 12 emptyText: qsTr("Нет версии для просмотра")
onLinkActivated: (href) => root.handleHistoryLink(href)
}
} }
} }
} }
} }
// Легенда // Легенда — только для вкладки «Изменения»
Row { Row {
visible: tabBar.currentIndex === 0
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: tabBar.currentIndex === 0 ? implicitHeight : 0
Layout.margins: 6 Layout.margins: 6
spacing: 12 spacing: 12
Row { spacing: 4; Rectangle { width:12; height:12; color:"#e6ffec"; 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:"#e6ffec"; border.color:"#1a7f37"; radius:2; anchors.verticalCenter: parent.verticalCenter } Label { text: qsTr("добавлено"); color: Theme.textMuted; font.pixelSize:10 } }
@@ -436,4 +467,27 @@ Dialog {
background: Rectangle { color: Theme.surface; border.color: Theme.borderStrong; radius: 10 } background: Rectangle { color: Theme.surface; border.color: Theme.borderStrong; radius: 10 }
Label { id: errorLabel; color: Theme.errorText; wrapMode: Text.Wrap; width: 360 } Label { id: errorLabel; color: Theme.errorText; wrapMode: Text.Wrap; width: 360 }
} }
// Тост "Скопировано" для кнопки копирования в блоках кода
Rectangle {
id: copyToast
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 8
visible: copyFeedback.visible
color: "#333"
radius: 6
width: copyFeedback.implicitWidth + 16
height: copyFeedback.implicitHeight + 10
z: 10
Label {
id: copyFeedback
anchors.centerIn: parent
visible: false
text: qsTr("Скопировано!")
color: "white"
font.pixelSize: 11
}
}
Timer { id: copyTimer; interval: 1500; onTriggered: copyFeedback.visible = false }
} }
+2 -1
View File
@@ -8,6 +8,7 @@ Item {
property string markdown: "" property string markdown: ""
property string vaultRoot: "" property string vaultRoot: ""
property string fileDir: "" property string fileDir: ""
property string emptyText: qsTr("Пустой файл — начните писать в режиме редактирования")
implicitHeight: column.implicitHeight + 24 implicitHeight: column.implicitHeight + 24
signal linkActivated(string href) signal linkActivated(string href)
@@ -86,7 +87,7 @@ Item {
Label { Label {
width: parent.width width: parent.width
text: markdown.trim().length === 0 ? qsTr("Пустой файл — начните писать в режиме редактирования") : "" text: markdown.trim().length === 0 ? emptyText : ""
color: Theme.textFaint color: Theme.textFaint
wrapMode: Text.Wrap wrapMode: Text.Wrap
font.italic: true font.italic: true