Merge branch 'main' into pr/networking-refactor-pt2

This commit is contained in:
Turann_
2026-03-14 05:46:20 +03:00
committed by GitHub
28 changed files with 291 additions and 53 deletions
+4 -3
View File
@@ -113,9 +113,9 @@ Item {
if (useFixedWidth)
return maxWidth;
// Calculate icon/art width
// Calculate icon/art width (must match RowLayout visibility)
var iconWidth = 0;
if (!hasPlayer || (!showAlbumArt && !showProgressRing)) {
if (!hasPlayer) {
iconWidth = iconSize;
} else if (showAlbumArt || showProgressRing) {
iconWidth = artSize;
@@ -126,7 +126,8 @@ Item {
// Add spacing and text width
var textWidth = 0;
if (titleContainer.measuredWidth > 0) {
margins += Style.marginS;
if (iconWidth > 0)
margins += Style.marginS;
textWidth = titleContainer.measuredWidth + Style.margin2XXS;
}
+4
View File
@@ -172,6 +172,7 @@ Rectangle {
// Custom Clock (Stacked)
ColumnLayout {
anchors.centerIn: parent
width: parent.width
visible: Settings.data.general.clockStyle === "custom"
spacing: -3
@@ -182,8 +183,11 @@ Rectangle {
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: parent.width
Layout.fillWidth: true
}
}
}
+1 -1
View File
@@ -65,7 +65,7 @@ Rectangle {
readonly property int badgeSize: Math.round(effectiveIconSize * Style.uiScaleRatio)
readonly property int entryHeight: Math.round(badgeSize + (launcherDensity === "compact" ? (Style.marginL + Style.marginXXS) : (Style.marginXL + Style.marginS)))
readonly property bool providerShowsCategories: currentProvider.showsCategories === true
readonly property bool providerShowsCategories: (currentProvider.showsCategories !== undefined ? currentProvider.showsCategories : true) && providerCategories.length > 0
readonly property var providerCategories: {
if (currentProvider.availableCategories && currentProvider.availableCategories.length > 0) {
@@ -2,6 +2,7 @@ import QtQuick
import Quickshell
import qs.Commons
import qs.Services.Keyboard
import qs.Services.Noctalia
Item {
id: root
@@ -23,6 +24,28 @@ Item {
// Image handling - expose revision for reactive updates in delegates
readonly property int imageRevision: ClipboardService.revision
// Categories
property var availableCategories: Settings.data.appLauncher.enableClipboardChips ? ["All", "Images", "Links", "Files", "Code", "Colors"] : []
property string selectedCategory: "All"
function selectCategory(cat) {
if (selectedCategory !== cat) {
selectedCategory = cat;
if (launcher) {
launcher.updateResults();
}
}
}
property var categoryIcons: {
"All": iconMode === "tabler" ? "border-all" : "view-grid",
"Images": iconMode === "tabler" ? "photo" : "image",
"Links": iconMode === "tabler" ? "link" : "insert-link",
"Files": iconMode === "tabler" ? "file" : "text-x-generic",
"Code": iconMode === "tabler" ? "code" : "text-x-script",
"Colors": iconMode === "tabler" ? "palette" : "color-picker"
}
// Internal state
property bool isWaitingForData: false
property bool gotResults: false
@@ -199,8 +222,25 @@ Item {
// Search clipboard items
const searchTerm = query.toLowerCase();
const now = Date.now() / 1000;
const catMap = {
"Images": "image",
"Links": "link",
"Files": "file",
"Code": "code",
"Colors": "color"
};
// Filter and format results
items.forEach(function (item) {
// Category filter
if (Settings.data.appLauncher.enableClipboardChips && root.selectedCategory !== "All") {
if (item.contentType !== catMap[root.selectedCategory]) {
return;
}
}
const preview = (item.preview || "").toLowerCase();
// Skip if search term doesn't match
@@ -208,12 +248,14 @@ Item {
return;
}
const firstSeen = ClipboardService.firstSeenById[item.id] || now;
// Format the result based on type
let entry;
if (item.isImage) {
entry = formatImageEntry(item);
entry = formatImageEntry(item, firstSeen);
} else {
entry = formatTextEntry(item);
entry = formatTextEntry(item, firstSeen);
}
// Add activation handler
@@ -249,12 +291,16 @@ Item {
return results;
}
function formatImageEntry(item) {
function formatImageEntry(item, firstSeen) {
const meta = ClipboardService.parseImageMeta(item.preview);
const timeStr = Time.formatRelativeTime(new Date(firstSeen * 1000));
let desc = meta ? `${meta.fmt} ${meta.size}` : item.mime || "Image data";
if (timeStr)
desc += ` ${timeStr}`;
return {
"name": meta ? `Image ${meta.w}×${meta.h}` : "Image",
"description": meta ? `${meta.fmt} ${meta.size}` : item.mime || "Image data",
"description": desc,
"icon": iconMode === "tabler" ? "photo" : "image",
"isTablerIcon": true,
"isImage": true,
@@ -267,7 +313,7 @@ Item {
};
}
function formatTextEntry(item) {
function formatTextEntry(item, firstSeen) {
const preview = (item.preview || "").trim();
const lines = preview.split('\n').filter(l => l.trim());
@@ -293,14 +339,35 @@ Item {
}
}
const timeStr = Time.formatRelativeTime(new Date(firstSeen * 1000));
if (timeStr)
description += ` ${timeStr}`;
let defaultIcon = iconMode === "tabler" ? "clipboard" : "text-x-generic";
let colorHex = "";
if (Settings.data.appLauncher.enableClipboardSmartIcons) {
if (item.contentType === "link")
defaultIcon = iconMode === "tabler" ? "link" : "insert-link";
else if (item.contentType === "file")
defaultIcon = iconMode === "tabler" ? "file" : "text-x-generic";
else if (item.contentType === "code")
defaultIcon = iconMode === "tabler" ? "code" : "text-x-script";
else if (item.contentType === "color") {
defaultIcon = iconMode === "tabler" ? "palette" : "color-picker";
colorHex = preview;
}
}
return {
"name": title,
"description": description,
"icon": iconMode === "tabler" ? "clipboard" : "text-x-generic",
"icon": defaultIcon,
"isTablerIcon": true,
"isImage": false,
"clipboardId": item.id,
"preview": preview,
"contentType": item.contentType,
"colorHex": colorHex,
"provider": root
};
}
@@ -284,7 +284,7 @@ Item {
// Auto-scan timer when panel is visible
Timer {
id: autoScanTimer
interval: 15000 // Scan every 15s
interval: 5000
running: root.effectivelyVisible && Settings.data.network.wifiEnabled
repeat: true
onTriggered: NetworkService.scan()
@@ -45,6 +45,24 @@ ColumnLayout {
enabled: Settings.data.appLauncher.enableClipboardHistory && ProgramCheckerService.wtypeAvailable
}
NToggle {
label: I18n.tr("panels.launcher.settings-clip-smart-icons-label")
description: I18n.tr("panels.launcher.settings-clip-smart-icons-description")
checked: Settings.data.appLauncher.enableClipboardSmartIcons
onToggled: checked => Settings.data.appLauncher.enableClipboardSmartIcons = checked
defaultValue: Settings.getDefaultValue("appLauncher.enableClipboardSmartIcons")
enabled: Settings.data.appLauncher.enableClipboardHistory
}
NToggle {
label: I18n.tr("panels.launcher.settings-clip-chips-label")
description: I18n.tr("panels.launcher.settings-clip-chips-description")
checked: Settings.data.appLauncher.enableClipboardChips
onToggled: checked => Settings.data.appLauncher.enableClipboardChips = checked
defaultValue: Settings.getDefaultValue("appLauncher.enableClipboardChips")
enabled: Settings.data.appLauncher.enableClipboardHistory
}
NDivider {
Layout.fillWidth: true
visible: Settings.data.appLauncher.enableClipboardHistory