mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'main' into pr/networking-refactor-pt2
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user