1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 04:42:05 -04:00

core: add DL helper, apply to TrackArt OSD, DankLocationSearch

- unrelated change to add gsettingsOrDconf helpers
This commit is contained in:
bbedward
2026-02-10 15:42:40 -05:00
parent 2c360dc3e8
commit c783ff3dcf
12 changed files with 319 additions and 139 deletions

View File

@@ -853,7 +853,8 @@ Item {
icon: "folder",
priority: 4,
items: fileItems,
collapsed: collapsedSections["files"] || false
collapsed: collapsedSections["files"] || false,
flatStartIndex: 0
};
var newSections;
@@ -1284,7 +1285,11 @@ Item {
},
actions: [],
primaryAction: null,
_diskCached: true
_diskCached: true,
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
});
}
sectionsData.push({
@@ -1293,7 +1298,8 @@ Item {
icon: s.icon || "",
priority: s.priority || 0,
items: items,
collapsed: false
collapsed: false,
flatStartIndex: 0
});
}
return sectionsData;

View File

@@ -1,6 +1,6 @@
.pragma library
.import "ControllerUtils.js" as Utils
.import "ControllerUtils.js" as Utils
function transformApp(app, override, defaultActions, primaryActionLabel) {
var appId = app.id || app.execString || app.exec || "";
@@ -31,7 +31,11 @@ function transformApp(app, override, defaultActions, primaryActionLabel) {
name: primaryActionLabel,
icon: "open_in_new",
action: "launch"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -66,7 +70,11 @@ function transformCoreApp(app, openLabel) {
name: openLabel,
icon: "open_in_new",
action: "launch"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -100,7 +108,11 @@ function transformBuiltInLauncherItem(item, pluginId, openLabel) {
name: openLabel,
icon: "open_in_new",
action: "execute"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -133,7 +145,11 @@ function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel) {
name: openLabel,
icon: "open_in_new",
action: "open"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -166,7 +182,11 @@ function transformPluginItem(item, pluginId, selectLabel) {
name: selectLabel,
icon: "check",
action: "execute"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -188,7 +208,11 @@ function createCalculatorItem(calc, query, copyLabel) {
name: copyLabel,
icon: "content_copy",
action: "copy"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}
@@ -218,6 +242,10 @@ function createPluginBrowseItem(pluginId, plugin, trigger, isBuiltIn, isAllowed,
name: browseLabel,
icon: "arrow_forward",
action: "browse_plugin"
}
},
_hName: "",
_hSub: "",
_hRich: false,
_preScored: undefined
};
}

View File

@@ -187,7 +187,8 @@ function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSec
icon: sectionOrder[i].icon,
priority: sectionOrder[i].priority,
items: [],
collapsed: false
collapsed: false,
flatStartIndex: 0
}
}
@@ -220,6 +221,7 @@ function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSec
function flattenSections(sections) {
var flat = []
flat._sectionBounds = null
var bounds = {}
for (var i = 0; i < sections.length; i++) {

View File

@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Effects
import qs.Common
import qs.Services
@@ -37,9 +36,23 @@ DankOSD {
}
}
property bool _pendingShow: false
onPlayerChanged: {
if (!player)
if (!player) {
_pendingShow = false;
hide();
}
}
Connections {
target: TrackArtService
function onLoadingChanged() {
if (!TrackArtService.loading && root._pendingShow) {
root._pendingShow = false;
root.show();
}
}
}
Connections {
@@ -48,10 +61,20 @@ DankOSD {
function handleUpdate() {
if (!root.player?.trackTitle)
return;
if (SettingsData.osdMediaPlaybackEnabled) {
TrackArtService.loadArtwork(player.trackArtUrl);
if (!SettingsData.osdMediaPlaybackEnabled)
return;
TrackArtService.loadArtwork(player.trackArtUrl);
if (!player.trackArtUrl || player.trackArtUrl === "") {
root.show();
return;
}
if (!TrackArtService.loading) {
root.show();
return;
}
root._pendingShow = true;
}
function onTrackArtUrlChanged() {

View File

@@ -3,62 +3,62 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import Quickshell.Io
import Quickshell.Services.Mpris
import qs.Common
Singleton {
id: root
property string _lastArtUrl: ""
property string _bgArtSource: ""
property string activeTrackArtFile: ""
property bool loading: false
function loadArtwork(url) {
if (!url || url == "") {
if (!url || url === "") {
_bgArtSource = "";
_lastArtUrl = "";
loading = false;
return;
}
if (url == _lastArtUrl)
if (url === _lastArtUrl)
return;
_lastArtUrl = url;
if (url.startsWith("http://") || url.startsWith("https://")) {
const filename = "/tmp/.dankshell/trackart_" + Date.now() + ".jpg";
activeTrackArtFile = filename;
cleanupProcess.command = ["sh", "-c", "mkdir -p /tmp/.dankshell && find /tmp/.dankshell -name 'trackart_*' ! -name '" + filename.split('/').pop() + "' -delete"];
cleanupProcess.running = true;
_bgArtSource = "";
loading = true;
imageDownloader.command = ["curl", "-L", "-s", "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", "-o", filename, url];
imageDownloader.targetFile = filename;
imageDownloader.running = true;
if (!url.startsWith("http://") && !url.startsWith("https://")) {
const localUrl = url;
const filePath = url.startsWith("file://") ? url.substring(7) : url;
Proc.runCommand("trackart", ["test", "-f", filePath], (output, exitCode) => {
if (_lastArtUrl !== localUrl)
return;
if (exitCode === 0)
_bgArtSource = localUrl;
loading = false;
}, 200);
return;
}
// otherwise
_bgArtSource = url;
const filename = "/tmp/.dankshell/trackart_" + Date.now() + ".jpg";
activeTrackArtFile = filename;
Proc.runCommand("trackart_cleanup", ["sh", "-c", "mkdir -p /tmp/.dankshell && find /tmp/.dankshell -name 'trackart_*' ! -name '" + filename.split('/').pop() + "' -delete"], null, 0);
Proc.runCommand("trackart", ["dms", "dl", "-o", filename, "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", url], (output, exitCode) => {
const resultPath = output.trim();
if (resultPath !== filename)
return;
if (exitCode === 0)
_bgArtSource = "file://" + resultPath;
loading = false;
}, 200);
}
property MprisPlayer activePlayer: MprisController.activePlayer
onActivePlayerChanged: {
loadArtwork(activePlayer.trackArtUrl);
}
Process {
id: imageDownloader
running: false
property string targetFile: ""
onExited: exitCode => {
if (exitCode === 0 && targetFile)
_bgArtSource = "file://" + targetFile;
}
}
Process {
id: cleanupProcess
running: false
loadArtwork(activePlayer?.trackArtUrl ?? "");
}
}

View File

@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
@@ -13,7 +12,7 @@ Item {
onActiveFocusChanged: {
if (activeFocus) {
locationInput.forceActiveFocus()
locationInput.forceActiveFocus();
}
}
@@ -28,10 +27,10 @@ Item {
signal locationSelected(string displayName, string coordinates)
function resetSearchState() {
locationSearchTimer.stop()
dropdownHideTimer.stop()
isLoading = false
searchResultsModel.clear()
locationSearchTimer.stop();
dropdownHideTimer.stop();
isLoading = false;
searchResultsModel.clear();
}
width: parent.width
@@ -49,52 +48,49 @@ Item {
repeat: false
onTriggered: {
if (locationInput.text.length > 2) {
searchResultsModel.clear()
root.isLoading = true
const searchLocation = locationInput.text
root.currentSearchText = searchLocation
const encodedLocation = encodeURIComponent(searchLocation)
const curlCommand = `curl -4 -s --connect-timeout 5 --max-time 10 'https://nominatim.openstreetmap.org/search?q=${encodedLocation}&format=json&limit=5&addressdetails=1'`
Proc.runCommand("locationSearch", ["bash", "-c", curlCommand], (output, exitCode) => {
root.isLoading = false
searchResultsModel.clear();
root.isLoading = true;
const searchLocation = locationInput.text;
root.currentSearchText = searchLocation;
const encodedLocation = encodeURIComponent(searchLocation);
const searchUrl = "https://nominatim.openstreetmap.org/search?q=" + encodedLocation + "&format=json&limit=5&addressdetails=1";
Proc.runCommand("locationSearch", ["dms", "dl", "-4", "--timeout", "10", searchUrl], (output, exitCode) => {
root.isLoading = false;
if (exitCode !== 0) {
searchResultsModel.clear()
return
searchResultsModel.clear();
return;
}
if (root.currentSearchText !== locationInput.text)
return
const raw = output.trim()
searchResultsModel.clear()
return;
const raw = output.trim();
searchResultsModel.clear();
if (!raw || raw[0] !== "[") {
return
return;
}
try {
const data = JSON.parse(raw)
const data = JSON.parse(raw);
if (data.length === 0) {
return
return;
}
for (var i = 0; i < Math.min(data.length, 5); i++) {
const location = data[i]
const location = data[i];
if (location.display_name && location.lat && location.lon) {
const parts = location.display_name.split(', ')
let cleanName = parts[0]
const parts = location.display_name.split(', ');
let cleanName = parts[0];
if (parts.length > 1) {
const state = parts[parts.length - 2]
const state = parts[parts.length - 2];
if (state && state !== cleanName)
cleanName += `, ${state}`
cleanName += `, ${state}`;
}
const query = `${location.lat},${location.lon}`
const query = `${location.lat},${location.lon}`;
searchResultsModel.append({
"name": cleanName,
"query": query
})
"name": cleanName,
"query": query
});
}
}
} catch (e) {
}
})
} catch (e) {}
});
}
}
}
@@ -107,7 +103,7 @@ Item {
repeat: false
onTriggered: {
if (!locationInput.getActiveFocus() && !searchDropdown.hovered)
root.resetSearchState()
root.resetSearchState();
}
}
@@ -132,23 +128,23 @@ Item {
keyNavigationBacktab: root.keyNavigationBacktab
onTextEdited: {
if (root._internalChange)
return
return;
if (getActiveFocus()) {
if (text.length > 2) {
root.isLoading = true
locationSearchTimer.restart()
root.isLoading = true;
locationSearchTimer.restart();
} else {
root.resetSearchState()
root.resetSearchState();
}
}
}
onFocusStateChanged: hasFocus => {
if (hasFocus) {
dropdownHideTimer.stop()
} else {
dropdownHideTimer.start()
}
}
if (hasFocus) {
dropdownHideTimer.stop();
} else {
dropdownHideTimer.start();
}
}
}
DankIcon {
@@ -187,13 +183,13 @@ Item {
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.hovered = true
dropdownHideTimer.stop()
parent.hovered = true;
dropdownHideTimer.stop();
}
onExited: {
parent.hovered = false
parent.hovered = false;
if (!locationInput.getActiveFocus())
dropdownHideTimer.start()
dropdownHideTimer.start();
}
acceptedButtons: Qt.NoButton
}
@@ -245,14 +241,14 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root._internalChange = true
const selectedName = model.name
const selectedQuery = model.query
locationInput.text = selectedName
root.locationSelected(selectedName, selectedQuery)
root.resetSearchState()
locationInput.setFocus(false)
root._internalChange = false
root._internalChange = true;
const selectedName = model.name;
const selectedQuery = model.query;
locationInput.text = selectedName;
root.locationSelected(selectedName, selectedQuery);
root.resetSearchState();
locationInput.setFocus(false);
root._internalChange = false;
}
}
}