verison deletion feature

This commit is contained in:
2026-08-27 21:05:37 +03:00
parent dddc0261d4
commit af41017446
5 changed files with 365 additions and 8 deletions
+211 -8
View File
@@ -108,6 +108,183 @@ Dialog {
picker.close()
}
function catalogHas(versionId) {
const source = picker.backend.versionCatalog
for (var i = 0; i < source.length; ++i) {
if (source[i].id === versionId)
return true
}
return false
}
// Спрашиваем до удаления: версию придётся качать заново, а профили
// модлоадеров поверх неё — переустанавливать. Id запоминаем здесь:
// к моменту ответа строка под курсором может быть уже другой.
function askRemove(versionId) {
const info = picker.backend.versionRemovalInfo(versionId)
if (!info || info.installed !== true)
return
removeConfirm.versionId = versionId
removeConfirm.sizeMb = info.sizeMb || 0
removeConfirm.dependents = info.dependents || []
removeConfirm.builds = info.builds || []
removeConfirm.open()
}
function performRemove(versionId) {
picker.backend.removeVersion(versionId)
// Профиль модлоадера был в каталоге только потому, что установлен:
// после удаления строка исчезает совсем, и выбор надо снять.
if (picker.selectedId === versionId && !picker.catalogHas(versionId))
picker.selectedId = ""
picker.revealSelected()
}
Dialog {
id: removeConfirm
property string versionId: ""
property int sizeMb: 0
property var dependents: []
property var builds: []
modal: true
padding: 0
width: 420
parent: picker.parent
x: (picker.parent.width - width) / 2
y: (picker.parent.height - height) / 2
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
color: "#1e1e1e"
radius: 10
border.color: "#cc6666"
border.width: 1
}
header: Item {
implicitHeight: 52
Text {
anchors.centerIn: parent
text: qsTr("Удалить версию?")
color: "#ffffff"
font.pixelSize: 17
font.bold: true
}
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: 1
color: "#333333"
}
}
contentItem: Column {
spacing: 10
topPadding: 18
bottomPadding: 18
Text {
x: 20
width: parent.width - 40
wrapMode: Text.Wrap
color: "#ffffff"
font.pixelSize: 13
text: removeConfirm.sizeMb > 0
? qsTr("Файлы версии «%1» будут удалены из versions/ — освободится около %2 МБ. Скачать её заново можно в любой момент.")
.arg(removeConfirm.versionId).arg(removeConfirm.sizeMb)
: qsTr("Файлы версии «%1» будут удалены из versions/. Скачать её заново можно в любой момент.")
.arg(removeConfirm.versionId)
}
Text {
x: 20
width: parent.width - 40
visible: removeConfirm.dependents.length > 0
wrapMode: Text.Wrap
color: "#cc6666"
font.pixelSize: 12
text: qsTr("На эту версию опираются установленные профили модлоадеров: %1. Без неё они не запустятся — их придётся переустановить.")
.arg(removeConfirm.dependents.join(", "))
}
Text {
x: 20
width: parent.width - 40
visible: removeConfirm.builds.length > 0
wrapMode: Text.Wrap
color: "#cc6666"
font.pixelSize: 12
text: qsTr("Версию используют сборки: %1. Файлы понадобится скачать заново кнопкой «Установить».")
.arg(removeConfirm.builds.join(", "))
}
Text {
x: 20
width: parent.width - 40
wrapMode: Text.Wrap
color: "#888888"
font.pixelSize: 12
text: qsTr("Библиотеки и ресурсы в libraries/ и assets/ общие для всех версий и остаются на месте.")
}
}
footer: Item {
implicitHeight: 60
Rectangle {
anchors.top: parent.top
width: parent.width
height: 1
color: "#333333"
}
Row {
anchors.centerIn: parent
spacing: 12
Button {
text: qsTr("Отмена")
width: 130; height: 36
contentItem: Text {
text: parent.text
color: "#ffffff"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
color: parent.pressed ? "#6a8510" : "#91B315"
radius: 6
}
onClicked: removeConfirm.close()
}
Button {
text: qsTr("Удалить")
width: 130; height: 36
contentItem: Text {
text: parent.text
color: "#ffffff"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
color: parent.pressed ? "#8a3a3a" : "#663333"
radius: 6
border.color: "#cc6666"
border.width: 1
}
onClicked: {
const id = removeConfirm.versionId
removeConfirm.close()
picker.performRemove(id)
}
}
}
}
onClosed: removeConfirm.versionId = ""
}
header: Item {
implicitHeight: 52
Text {
@@ -291,7 +468,7 @@ Dialog {
Text {
anchors.left: parent.left
anchors.leftMargin: 10
anchors.right: installedMark.left
anchors.right: rightMarks.left
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
text: versionRow.modelData.label
@@ -300,21 +477,47 @@ Dialog {
font.pixelSize: 13
}
Text {
id: installedMark
Row {
id: rightMarks
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
visible: versionRow.modelData.installed
text: "✓"
color: picker.selectedId === versionRow.modelData.id ? "#1e1e1e" : "#91B315"
font.pixelSize: 13
font.bold: true
spacing: 8
Text {
visible: versionRow.modelData.installed
text: "✓"
color: picker.selectedId === versionRow.modelData.id ? "#1e1e1e" : "#91B315"
font.pixelSize: 13
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
// Версия весит от десятков мегабайт, а галочка рядом —
// единственное место, где видно, что именно скачано.
Image {
visible: versionRow.modelData.installed
source: "images/Trash.svg"
width: 14
height: 14
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
opacity: trashArea.containsMouse ? 1.0 : 0.55
MouseArea {
id: trashArea
anchors.fill: parent
anchors.margins: -5
hoverEnabled: true
onClicked: picker.askRemove(versionRow.modelData.id)
}
}
}
MouseArea {
id: versionArea
anchors.fill: parent
anchors.rightMargin: 40
hoverEnabled: true
onClicked: {
picker.selectedId = versionRow.modelData.id