diff --git a/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml b/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml index 9152ddd..a4759ca 100644 --- a/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml +++ b/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml @@ -77,11 +77,9 @@ NPanel { } // Unified list - Rectangle { + NBox { Layout.fillWidth: true Layout.fillHeight: true - color: Color.mSurfaceVariant - radius: Style.radiusM * scaling // Combine repo and AUR lists in order: repos first, then AUR property var items: (ArchUpdaterService.repoPackages || []).concat(ArchUpdaterService.aurPackages || []) @@ -89,21 +87,21 @@ NPanel { ListView { id: unifiedList anchors.fill: parent - anchors.margins: Style.marginS * scaling + anchors.margins: Style.marginM * scaling + cacheBuffer: Math.round(300 * scaling) clip: true + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AsNeeded + } model: parent.items - spacing: Style.marginXS * scaling - cacheBuffer: 300 * scaling - delegate: Rectangle { width: unifiedList.width - height: 56 * scaling + height: 44 * scaling color: Color.transparent radius: Style.radiusS * scaling RowLayout { anchors.fill: parent - anchors.margins: Style.marginS * scaling spacing: Style.marginS * scaling // Checkbox for selection @@ -112,16 +110,12 @@ NPanel { label: "" description: "" checked: ArchUpdaterService.isPackageSelected(modelData.name) + baseSize: Math.max(Style.baseWidgetSize * 0.7, 14) onToggled: function (checked) { ArchUpdaterService.togglePackageSelection(modelData.name) // Force refresh of the checked property checkbox.checked = ArchUpdaterService.isPackageSelected(modelData.name) } - activeColor: (modelData.source === "aur") ? Color.mSecondary : Color.mPrimary - activeOnColor: (modelData.source === "aur") ? Color.mOnSecondary : Color.mOnPrimary - Layout.fillWidth: false - Layout.preferredWidth: 30 * scaling - Layout.preferredHeight: 30 * scaling } // Package info @@ -129,51 +123,43 @@ NPanel { Layout.fillWidth: true spacing: Style.marginXXS * scaling - RowLayout { + NText { + text: modelData.name + font.pointSize: Style.fontSizeS * scaling + font.weight: Style.fontWeightBold + color: Color.mOnSurface Layout.fillWidth: true - spacing: Style.marginXS * scaling - - NText { - text: modelData.name - font.pointSize: Style.fontSizeM * scaling - font.weight: Style.fontWeightMedium - color: Color.mOnSurface - Layout.fillWidth: true - } - - // Source badge (custom rectangle) - Rectangle { - visible: !!modelData.source - radius: 9999 - color: modelData.source === "aur" ? Color.mSecondary : Color.mPrimary - Layout.alignment: Qt.AlignVCenter - implicitHeight: Math.max(Style.fontSizeXS * 1.7 * scaling, 16 * scaling) - // Width based on label content + horizontal padding - implicitWidth: badgeText.implicitWidth + Math.max(12 * scaling, Style.marginS * scaling) - - NText { - id: badgeText - anchors.centerIn: parent - text: modelData.source === "aur" ? "AUR" : "Repo" - font.pointSize: Style.fontSizeXS * scaling - font.weight: Style.fontWeightBold - color: modelData.source === "aur" ? Color.mOnSecondary : Color.mOnPrimary - } - } + Layout.alignment: Qt.AlignVCenter } NText { text: modelData.oldVersion + " → " + modelData.newVersion - font.pointSize: Style.fontSizeS * scaling + font.pointSize: Style.fontSizeXXS * scaling color: Color.mOnSurfaceVariant Layout.fillWidth: true } } - } - } - ScrollBar.vertical: ScrollBar { - policy: ScrollBar.AsNeeded + // Source tag (AUR vs PAC) + Rectangle { + visible: !!modelData.source + radius: width * 0.5 + color: modelData.source === "aur" ? Color.mTertiary : Color.mSecondary + Layout.alignment: Qt.AlignVCenter + implicitHeight: Style.fontSizeS * 1.8 * scaling + // Width based on label content + horizontal padding + implicitWidth: badgeText.implicitWidth + Math.max(12 * scaling, Style.marginS * scaling) + + NText { + id: badgeText + anchors.centerIn: parent + text: modelData.source === "aur" ? "AUR" : "PAC" + font.pointSize: Style.fontSizeXXS * scaling + font.weight: Style.fontWeightBold + color: modelData.source === "aur" ? Color.mOnTertiary : Color.mOnSecondary + } + } + } } } } @@ -219,9 +205,9 @@ NPanel { } } colorBg: ArchUpdaterService.updateInProgress ? Color.mSurfaceVariant : (ArchUpdaterService.selectedPackagesCount - > 0 ? Color.mSecondary : Color.mSurfaceVariant) + > 0 ? Color.mPrimary : Color.mSurfaceVariant) colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : (ArchUpdaterService.selectedPackagesCount - > 0 ? Color.mOnSecondary : Color.mOnSurfaceVariant) + > 0 ? Color.mOnPrimary : Color.mOnSurfaceVariant) Layout.fillWidth: true } } diff --git a/Modules/Bar/Widgets/ArchUpdater.qml b/Modules/Bar/Widgets/ArchUpdater.qml index 90cedb7..106b167 100644 --- a/Modules/Bar/Widgets/ArchUpdater.qml +++ b/Modules/Bar/Widgets/ArchUpdater.qml @@ -14,18 +14,9 @@ NIconButton { sizeRatio: 0.8 colorBg: Color.mSurfaceVariant - // Highlight color based on update source - colorFg: { - if (ArchUpdaterService.totalUpdates === 0) - return Color.mOnSurface - if (ArchUpdaterService.updates > 0 && ArchUpdaterService.aurUpdates > 0) - return Color.mPrimary - if (ArchUpdaterService.updates > 0) - return Color.mPrimary - return Color.mSecondary - } colorBorder: Color.transparent colorBorderHover: Color.transparent + colorFg: (ArchUpdaterService.totalUpdates === 0) ? Color.mOnSurface : Color.mPrimary // Icon states icon: { @@ -40,42 +31,34 @@ NIconButton { // Tooltip with repo vs AUR breakdown and sample lists tooltipText: { - if (ArchUpdaterService.busy || ArchUpdaterService.aurBusy) + if (ArchUpdaterService.busy || ArchUpdaterService.aurBusy) { return "Checking for updates…" - - const repoCount = ArchUpdaterService.updates - const aurCount = ArchUpdaterService.aurUpdates - const total = ArchUpdaterService.totalUpdates - - if (total === 0) - return "System is up to date ✓" - - let header = total === 1 ? "One package can be upgraded:" : (total + " packages can be upgraded:") - - function sampleList(arr, n, colorLabel) { - const limit = Math.min(arr.length, n) - let s = "" - for (var i = 0; i < limit; ++i) { - const p = arr[i] - s += (i ? "\n" : "") + (p.name + ": " + p.oldVersion + " → " + p.newVersion) - } - if (arr.length > limit) - s += "\n… and " + (arr.length - limit) + " more" - return (colorLabel ? (colorLabel + "\n") : "") + (s || "None") } - const repoHeader = repoCount > 0 ? ("Repo (" + repoCount + "):") : "Repo: 0" - const aurHeader = aurCount > 0 ? ("AUR (" + aurCount + "):") : "AUR: 0" + const total = ArchUpdaterService.totalUpdates + if (total === 0) { + return "System is up to date ✓" + } + let header = (total === 1) ? "1 package can be updated" : (total + " packages can be updated") - const repoBlock = repoCount > 0 ? (repoHeader + "\n\n" + sampleList(ArchUpdaterService.repoPackages, - 5)) : repoHeader - const aurBlock = aurCount > 0 ? (aurHeader + "\n\n" + sampleList(ArchUpdaterService.aurPackages, 5)) : aurHeader + const pacCount = ArchUpdaterService.updates + const aurCount = ArchUpdaterService.aurUpdates + const pacmanTooltip = (pacCount > 0) ? ((pacCount === 1) ? "1 system package" : pacCount + " system packages") : "" + const aurTooltip = (aurCount > 0) ? ((aurCount === 1) ? "1 AUR package" : aurCount + " AUR packages") : "" - return header + "\n\n" + repoBlock + "\n\n" + aurBlock + "\n\nClick to update system" + let tooltip = header + if (pacmanTooltip !== "") { + tooltip += "\n" + pacmanTooltip + } + if (aurTooltip !== "") { + tooltip += "\n" + aurTooltip + } + return tooltip } onClicked: { if (ArchUpdaterService.busy || ArchUpdaterService.aurBusy) { + ToastService.showNotice("ArchUpdater", "Still fetching updates...") return } diff --git a/Widgets/NCheckbox.qml b/Widgets/NCheckbox.qml index 24944e2..962b303 100644 --- a/Widgets/NCheckbox.qml +++ b/Widgets/NCheckbox.qml @@ -24,6 +24,7 @@ RowLayout { NLabel { label: root.label description: root.description + visible: root.label !== "" || root.description !== "" } Rectangle { @@ -31,7 +32,7 @@ RowLayout { implicitWidth: root.baseSize * scaling implicitHeight: root.baseSize * scaling - radius: Math.max(2 * scaling, Style.radiusXS * scaling) + radius: Style.radiusXS * scaling color: root.checked ? root.activeColor : Color.mSurface border.color: root.checked ? root.activeColor : Color.mOutline border.width: Math.max(1, Style.borderM * scaling)